1706f2543Smrg/* 2706f2543Smrg * Copyright � 1999 Keith Packard 3706f2543Smrg * Copyright � 2006 Nokia Corporation 4706f2543Smrg * 5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 7706f2543Smrg * the above copyright notice appear in all copies and that both that 8706f2543Smrg * copyright notice and this permission notice appear in supporting 9706f2543Smrg * documentation, and that the name of the authors not be used in 10706f2543Smrg * advertising or publicity pertaining to distribution of the software without 11706f2543Smrg * specific, written prior permission. The authors make no 12706f2543Smrg * representations about the suitability of this software for any purpose. It 13706f2543Smrg * is provided "as is" without express or implied warranty. 14706f2543Smrg * 15706f2543Smrg * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17706f2543Smrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 22706f2543Smrg */ 23706f2543Smrg 24706f2543Smrg#ifdef HAVE_CONFIG_H 25706f2543Smrg#include <kdrive-config.h> 26706f2543Smrg#endif 27706f2543Smrg#include "kdrive.h" 28706f2543Smrg#include "inputstr.h" 29706f2543Smrg 30706f2543Smrg#define XK_PUBLISHING 31706f2543Smrg#include <X11/keysym.h> 32706f2543Smrg#if HAVE_X11_XF86KEYSYM_H 33706f2543Smrg#include <X11/XF86keysym.h> 34706f2543Smrg#endif 35706f2543Smrg#include <signal.h> 36706f2543Smrg#include <stdio.h> 37706f2543Smrg#ifdef sun 38706f2543Smrg#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ 39706f2543Smrg#endif 40706f2543Smrg 41706f2543Smrg#include "xkbsrv.h" 42706f2543Smrg 43706f2543Smrg#include <X11/extensions/XI.h> 44706f2543Smrg#include <X11/extensions/XIproto.h> 45706f2543Smrg#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ 46706f2543Smrg#include "exevents.h" 47706f2543Smrg#include "extinit.h" 48706f2543Smrg#include "exglobals.h" 49706f2543Smrg#include "eventstr.h" 50706f2543Smrg#include "xserver-properties.h" 51706f2543Smrg#include "inpututils.h" 52706f2543Smrg 53706f2543Smrg#define AtomFromName(x) MakeAtom(x, strlen(x), 1) 54706f2543Smrg 55706f2543Smrgstruct KdConfigDevice { 56706f2543Smrg char *line; 57706f2543Smrg struct KdConfigDevice *next; 58706f2543Smrg}; 59706f2543Smrg 60706f2543Smrg/* kdKeyboards and kdPointers hold all the real devices. */ 61706f2543Smrgstatic KdKeyboardInfo *kdKeyboards = NULL; 62706f2543Smrgstatic KdPointerInfo *kdPointers = NULL; 63706f2543Smrgstatic struct KdConfigDevice *kdConfigKeyboards = NULL; 64706f2543Smrgstatic struct KdConfigDevice *kdConfigPointers = NULL; 65706f2543Smrg 66706f2543Smrgstatic KdKeyboardDriver *kdKeyboardDrivers = NULL; 67706f2543Smrgstatic KdPointerDriver *kdPointerDrivers = NULL; 68706f2543Smrg 69706f2543Smrgstatic EventListPtr kdEvents = NULL; 70706f2543Smrg 71706f2543Smrgstatic Bool kdInputEnabled; 72706f2543Smrgstatic Bool kdOffScreen; 73706f2543Smrgstatic unsigned long kdOffScreenTime; 74706f2543Smrgstatic KdPointerMatrix kdPointerMatrix = { 75706f2543Smrg { { 1, 0, 0 }, 76706f2543Smrg { 0, 1, 0 } } 77706f2543Smrg}; 78706f2543Smrg 79706f2543Smrgvoid KdResetInputMachine (void); 80706f2543Smrg 81706f2543Smrg#define KD_MAX_INPUT_FDS 8 82706f2543Smrg 83706f2543Smrgtypedef struct _kdInputFd { 84706f2543Smrg int fd; 85706f2543Smrg void (*read) (int fd, void *closure); 86706f2543Smrg int (*enable) (int fd, void *closure); 87706f2543Smrg void (*disable) (int fd, void *closure); 88706f2543Smrg void *closure; 89706f2543Smrg} KdInputFd; 90706f2543Smrg 91706f2543Smrgstatic KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; 92706f2543Smrgstatic int kdNumInputFds; 93706f2543Smrg 94706f2543Smrgextern Bool kdRawPointerCoordinates; 95706f2543Smrg 96706f2543Smrgstatic void 97706f2543SmrgKdSigio (int sig) 98706f2543Smrg{ 99706f2543Smrg int i; 100706f2543Smrg 101706f2543Smrg for (i = 0; i < kdNumInputFds; i++) 102706f2543Smrg (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); 103706f2543Smrg} 104706f2543Smrg 105706f2543Smrgstatic void 106706f2543SmrgKdBlockSigio (void) 107706f2543Smrg{ 108706f2543Smrg sigset_t set; 109706f2543Smrg 110706f2543Smrg sigemptyset (&set); 111706f2543Smrg sigaddset (&set, SIGIO); 112706f2543Smrg sigprocmask (SIG_BLOCK, &set, 0); 113706f2543Smrg} 114706f2543Smrg 115706f2543Smrgstatic void 116706f2543SmrgKdUnblockSigio (void) 117706f2543Smrg{ 118706f2543Smrg sigset_t set; 119706f2543Smrg 120706f2543Smrg sigemptyset (&set); 121706f2543Smrg sigaddset (&set, SIGIO); 122706f2543Smrg sigprocmask (SIG_UNBLOCK, &set, 0); 123706f2543Smrg} 124706f2543Smrg 125706f2543Smrg#ifdef DEBUG_SIGIO 126706f2543Smrg 127706f2543Smrgvoid 128706f2543SmrgKdAssertSigioBlocked (char *where) 129706f2543Smrg{ 130706f2543Smrg sigset_t set, old; 131706f2543Smrg 132706f2543Smrg sigemptyset (&set); 133706f2543Smrg sigprocmask (SIG_BLOCK, &set, &old); 134706f2543Smrg if (!sigismember (&old, SIGIO)) { 135706f2543Smrg ErrorF ("SIGIO not blocked at %s\n", where); 136706f2543Smrg KdBacktrace(0); 137706f2543Smrg } 138706f2543Smrg} 139706f2543Smrg 140706f2543Smrg#else 141706f2543Smrg 142706f2543Smrg#define KdAssertSigioBlocked(s) 143706f2543Smrg 144706f2543Smrg#endif 145706f2543Smrg 146706f2543Smrgstatic int kdnFds; 147706f2543Smrg 148706f2543Smrg#ifdef FNONBLOCK 149706f2543Smrg#define NOBLOCK FNONBLOCK 150706f2543Smrg#else 151706f2543Smrg#define NOBLOCK FNDELAY 152706f2543Smrg#endif 153706f2543Smrg 154706f2543Smrgvoid 155706f2543SmrgKdResetInputMachine (void) 156706f2543Smrg{ 157706f2543Smrg KdPointerInfo *pi; 158706f2543Smrg 159706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) { 160706f2543Smrg pi->mouseState = start; 161706f2543Smrg pi->eventHeld = FALSE; 162706f2543Smrg } 163706f2543Smrg} 164706f2543Smrg 165706f2543Smrgstatic void 166706f2543SmrgKdNonBlockFd (int fd) 167706f2543Smrg{ 168706f2543Smrg int flags; 169706f2543Smrg flags = fcntl (fd, F_GETFL); 170706f2543Smrg flags |= FASYNC|NOBLOCK; 171706f2543Smrg fcntl (fd, F_SETFL, flags); 172706f2543Smrg} 173706f2543Smrg 174706f2543Smrgstatic void 175706f2543SmrgKdAddFd (int fd) 176706f2543Smrg{ 177706f2543Smrg struct sigaction act; 178706f2543Smrg sigset_t set; 179706f2543Smrg 180706f2543Smrg kdnFds++; 181706f2543Smrg fcntl (fd, F_SETOWN, getpid()); 182706f2543Smrg KdNonBlockFd (fd); 183706f2543Smrg AddEnabledDevice (fd); 184706f2543Smrg memset (&act, '\0', sizeof act); 185706f2543Smrg act.sa_handler = KdSigio; 186706f2543Smrg sigemptyset (&act.sa_mask); 187706f2543Smrg sigaddset (&act.sa_mask, SIGIO); 188706f2543Smrg sigaddset (&act.sa_mask, SIGALRM); 189706f2543Smrg sigaddset (&act.sa_mask, SIGVTALRM); 190706f2543Smrg sigaction (SIGIO, &act, 0); 191706f2543Smrg sigemptyset (&set); 192706f2543Smrg sigprocmask (SIG_SETMASK, &set, 0); 193706f2543Smrg} 194706f2543Smrg 195706f2543Smrgstatic void 196706f2543SmrgKdRemoveFd (int fd) 197706f2543Smrg{ 198706f2543Smrg struct sigaction act; 199706f2543Smrg int flags; 200706f2543Smrg 201706f2543Smrg kdnFds--; 202706f2543Smrg RemoveEnabledDevice (fd); 203706f2543Smrg flags = fcntl (fd, F_GETFL); 204706f2543Smrg flags &= ~(FASYNC|NOBLOCK); 205706f2543Smrg fcntl (fd, F_SETFL, flags); 206706f2543Smrg if (kdnFds == 0) 207706f2543Smrg { 208706f2543Smrg memset (&act, '\0', sizeof act); 209706f2543Smrg act.sa_handler = SIG_IGN; 210706f2543Smrg sigemptyset (&act.sa_mask); 211706f2543Smrg sigaction (SIGIO, &act, 0); 212706f2543Smrg } 213706f2543Smrg} 214706f2543Smrg 215706f2543SmrgBool 216706f2543SmrgKdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure) 217706f2543Smrg{ 218706f2543Smrg if (kdNumInputFds == KD_MAX_INPUT_FDS) 219706f2543Smrg return FALSE; 220706f2543Smrg kdInputFds[kdNumInputFds].fd = fd; 221706f2543Smrg kdInputFds[kdNumInputFds].read = read; 222706f2543Smrg kdInputFds[kdNumInputFds].enable = 0; 223706f2543Smrg kdInputFds[kdNumInputFds].disable = 0; 224706f2543Smrg kdInputFds[kdNumInputFds].closure = closure; 225706f2543Smrg kdNumInputFds++; 226706f2543Smrg if (kdInputEnabled) 227706f2543Smrg KdAddFd (fd); 228706f2543Smrg return TRUE; 229706f2543Smrg} 230706f2543Smrg 231706f2543Smrgvoid 232706f2543SmrgKdUnregisterFd (void *closure, int fd, Bool do_close) 233706f2543Smrg{ 234706f2543Smrg int i, j; 235706f2543Smrg 236706f2543Smrg for (i = 0; i < kdNumInputFds; i++) { 237706f2543Smrg if (kdInputFds[i].closure == closure && 238706f2543Smrg (fd == -1 || kdInputFds[i].fd == fd)) { 239706f2543Smrg if (kdInputEnabled) 240706f2543Smrg KdRemoveFd (kdInputFds[i].fd); 241706f2543Smrg if (do_close) 242706f2543Smrg close (kdInputFds[i].fd); 243706f2543Smrg kdNumInputFds--; 244706f2543Smrg for (j = i; j < kdNumInputFds; j++) 245706f2543Smrg kdInputFds[j] = kdInputFds[j+1]; 246706f2543Smrg break; 247706f2543Smrg } 248706f2543Smrg } 249706f2543Smrg} 250706f2543Smrg 251706f2543Smrgvoid 252706f2543SmrgKdUnregisterFds (void *closure, Bool do_close) 253706f2543Smrg{ 254706f2543Smrg KdUnregisterFd(closure, -1, do_close); 255706f2543Smrg} 256706f2543Smrg 257706f2543Smrgvoid 258706f2543SmrgKdDisableInput (void) 259706f2543Smrg{ 260706f2543Smrg KdKeyboardInfo *ki; 261706f2543Smrg KdPointerInfo *pi; 262706f2543Smrg int found = 0, i = 0; 263706f2543Smrg 264706f2543Smrg KdBlockSigio(); 265706f2543Smrg 266706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 267706f2543Smrg if (ki->driver && ki->driver->Disable) 268706f2543Smrg (*ki->driver->Disable) (ki); 269706f2543Smrg } 270706f2543Smrg 271706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) { 272706f2543Smrg if (pi->driver && pi->driver->Disable) 273706f2543Smrg (*pi->driver->Disable) (pi); 274706f2543Smrg } 275706f2543Smrg 276706f2543Smrg if (kdNumInputFds) { 277706f2543Smrg ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!", 278706f2543Smrg kdNumInputFds); 279706f2543Smrg i = 0; 280706f2543Smrg while (i < kdNumInputFds) { 281706f2543Smrg found = 0; 282706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 283706f2543Smrg if (ki == kdInputFds[i].closure) { 284706f2543Smrg ErrorF(" fd %d belongs to keybd driver %s\n", 285706f2543Smrg kdInputFds[i].fd, 286706f2543Smrg ki->driver && ki->driver->name ? 287706f2543Smrg ki->driver->name : "(unnamed!)"); 288706f2543Smrg found = 1; 289706f2543Smrg break; 290706f2543Smrg } 291706f2543Smrg } 292706f2543Smrg 293706f2543Smrg if (found) { 294706f2543Smrg i++; 295706f2543Smrg continue; 296706f2543Smrg } 297706f2543Smrg 298706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) { 299706f2543Smrg if (pi == kdInputFds[i].closure) { 300706f2543Smrg ErrorF(" fd %d belongs to pointer driver %s\n", 301706f2543Smrg kdInputFds[i].fd, 302706f2543Smrg pi->driver && pi->driver->name ? 303706f2543Smrg pi->driver->name : "(unnamed!)"); 304706f2543Smrg break; 305706f2543Smrg } 306706f2543Smrg } 307706f2543Smrg 308706f2543Smrg if (found) { 309706f2543Smrg i++; 310706f2543Smrg continue; 311706f2543Smrg } 312706f2543Smrg 313706f2543Smrg ErrorF(" fd %d not claimed by any active device!\n", 314706f2543Smrg kdInputFds[i].fd); 315706f2543Smrg KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE); 316706f2543Smrg } 317706f2543Smrg } 318706f2543Smrg 319706f2543Smrg kdInputEnabled = FALSE; 320706f2543Smrg} 321706f2543Smrg 322706f2543Smrgvoid 323706f2543SmrgKdEnableInput (void) 324706f2543Smrg{ 325706f2543Smrg InternalEvent ev; 326706f2543Smrg KdKeyboardInfo *ki; 327706f2543Smrg KdPointerInfo *pi; 328706f2543Smrg 329706f2543Smrg kdInputEnabled = TRUE; 330706f2543Smrg 331706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 332706f2543Smrg if (ki->driver && ki->driver->Enable) 333706f2543Smrg (*ki->driver->Enable) (ki); 334706f2543Smrg } 335706f2543Smrg 336706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) { 337706f2543Smrg if (pi->driver && pi->driver->Enable) 338706f2543Smrg (*pi->driver->Enable) (pi); 339706f2543Smrg } 340706f2543Smrg 341706f2543Smrg /* reset screen saver */ 342706f2543Smrg ev.any.time = GetTimeInMillis (); 343706f2543Smrg NoticeEventTime (&ev); 344706f2543Smrg 345706f2543Smrg KdUnblockSigio (); 346706f2543Smrg} 347706f2543Smrg 348706f2543Smrgstatic KdKeyboardDriver * 349706f2543SmrgKdFindKeyboardDriver (char *name) 350706f2543Smrg{ 351706f2543Smrg KdKeyboardDriver *ret; 352706f2543Smrg 353706f2543Smrg /* ask a stupid question ... */ 354706f2543Smrg if (!name) 355706f2543Smrg return NULL; 356706f2543Smrg 357706f2543Smrg for (ret = kdKeyboardDrivers; ret; ret = ret->next) { 358706f2543Smrg if (strcmp(ret->name, name) == 0) 359706f2543Smrg return ret; 360706f2543Smrg } 361706f2543Smrg 362706f2543Smrg return NULL; 363706f2543Smrg} 364706f2543Smrg 365706f2543Smrgstatic KdPointerDriver * 366706f2543SmrgKdFindPointerDriver (char *name) 367706f2543Smrg{ 368706f2543Smrg KdPointerDriver *ret; 369706f2543Smrg 370706f2543Smrg /* ask a stupid question ... */ 371706f2543Smrg if (!name) 372706f2543Smrg return NULL; 373706f2543Smrg 374706f2543Smrg for (ret = kdPointerDrivers; ret; ret = ret->next) { 375706f2543Smrg if (strcmp(ret->name, name) == 0) 376706f2543Smrg return ret; 377706f2543Smrg } 378706f2543Smrg 379706f2543Smrg return NULL; 380706f2543Smrg} 381706f2543Smrg 382706f2543Smrgstatic int 383706f2543SmrgKdPointerProc(DeviceIntPtr pDevice, int onoff) 384706f2543Smrg{ 385706f2543Smrg DevicePtr pDev = (DevicePtr)pDevice; 386706f2543Smrg KdPointerInfo *pi; 387706f2543Smrg Atom xiclass; 388706f2543Smrg Atom *btn_labels; 389706f2543Smrg Atom *axes_labels; 390706f2543Smrg 391706f2543Smrg if (!pDev) 392706f2543Smrg return BadImplementation; 393706f2543Smrg 394706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) { 395706f2543Smrg if (pi->dixdev && pi->dixdev->id == pDevice->id) 396706f2543Smrg break; 397706f2543Smrg } 398706f2543Smrg 399706f2543Smrg if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { 400706f2543Smrg ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", 401706f2543Smrg pDevice->id); 402706f2543Smrg return BadImplementation; 403706f2543Smrg } 404706f2543Smrg 405706f2543Smrg switch (onoff) 406706f2543Smrg { 407706f2543Smrg case DEVICE_INIT: 408706f2543Smrg#ifdef DEBUG 409706f2543Smrg ErrorF("initialising pointer %s ...\n", pi->name); 410706f2543Smrg#endif 411706f2543Smrg if (!pi->driver) { 412706f2543Smrg if (!pi->driverPrivate) { 413706f2543Smrg ErrorF("no driver specified for %s\n", pi->name); 414706f2543Smrg return BadImplementation; 415706f2543Smrg } 416706f2543Smrg 417706f2543Smrg pi->driver = KdFindPointerDriver(pi->driverPrivate); 418706f2543Smrg if (!pi->driver) { 419706f2543Smrg ErrorF("Couldn't find pointer driver %s\n", 420706f2543Smrg pi->driverPrivate ? (char *) pi->driverPrivate : 421706f2543Smrg "(unnamed)"); 422706f2543Smrg return !Success; 423706f2543Smrg } 424706f2543Smrg free(pi->driverPrivate); 425706f2543Smrg pi->driverPrivate = NULL; 426706f2543Smrg } 427706f2543Smrg 428706f2543Smrg if (!pi->driver->Init) { 429706f2543Smrg ErrorF("no init function\n"); 430706f2543Smrg return BadImplementation; 431706f2543Smrg } 432706f2543Smrg 433706f2543Smrg if ((*pi->driver->Init) (pi) != Success) { 434706f2543Smrg return !Success; 435706f2543Smrg } 436706f2543Smrg 437706f2543Smrg btn_labels = calloc(pi->nButtons, sizeof(Atom)); 438706f2543Smrg if (!btn_labels) 439706f2543Smrg return BadAlloc; 440706f2543Smrg axes_labels = calloc(pi->nAxes, sizeof(Atom)); 441706f2543Smrg if (!axes_labels) { 442706f2543Smrg free(btn_labels); 443706f2543Smrg return BadAlloc; 444706f2543Smrg } 445706f2543Smrg 446706f2543Smrg switch(pi->nAxes) 447706f2543Smrg { 448706f2543Smrg default: 449706f2543Smrg case 7: 450706f2543Smrg btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 451706f2543Smrg case 6: 452706f2543Smrg btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 453706f2543Smrg case 5: 454706f2543Smrg btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); 455706f2543Smrg case 4: 456706f2543Smrg btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 457706f2543Smrg case 3: 458706f2543Smrg btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 459706f2543Smrg case 2: 460706f2543Smrg btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 461706f2543Smrg case 1: 462706f2543Smrg btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 463706f2543Smrg case 0: 464706f2543Smrg break; 465706f2543Smrg } 466706f2543Smrg 467706f2543Smrg if (pi->nAxes >= 2) { 468706f2543Smrg axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 469706f2543Smrg axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 470706f2543Smrg } 471706f2543Smrg 472706f2543Smrg InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels, 473706f2543Smrg (PtrCtrlProcPtr)NoopDDA, 474706f2543Smrg GetMotionHistorySize(), pi->nAxes, axes_labels); 475706f2543Smrg 476706f2543Smrg free(btn_labels); 477706f2543Smrg free(axes_labels); 478706f2543Smrg 479706f2543Smrg if (pi->inputClass == KD_TOUCHSCREEN) { 480706f2543Smrg InitAbsoluteClassDeviceStruct(pDevice); 481706f2543Smrg xiclass = AtomFromName(XI_TOUCHSCREEN); 482706f2543Smrg } 483706f2543Smrg else { 484706f2543Smrg xiclass = AtomFromName(XI_MOUSE); 485706f2543Smrg } 486706f2543Smrg 487706f2543Smrg AssignTypeAndName(pi->dixdev, xiclass, 488706f2543Smrg pi->name ? pi->name : "Generic KDrive Pointer"); 489706f2543Smrg 490706f2543Smrg return Success; 491706f2543Smrg 492706f2543Smrg case DEVICE_ON: 493706f2543Smrg if (pDev->on == TRUE) 494706f2543Smrg return Success; 495706f2543Smrg 496706f2543Smrg if (!pi->driver->Enable) { 497706f2543Smrg ErrorF("no enable function\n"); 498706f2543Smrg return BadImplementation; 499706f2543Smrg } 500706f2543Smrg 501706f2543Smrg if ((*pi->driver->Enable) (pi) == Success) { 502706f2543Smrg pDev->on = TRUE; 503706f2543Smrg return Success; 504706f2543Smrg } 505706f2543Smrg else { 506706f2543Smrg return BadImplementation; 507706f2543Smrg } 508706f2543Smrg 509706f2543Smrg return Success; 510706f2543Smrg 511706f2543Smrg case DEVICE_OFF: 512706f2543Smrg if (pDev->on == FALSE) { 513706f2543Smrg return Success; 514706f2543Smrg } 515706f2543Smrg 516706f2543Smrg if (!pi->driver->Disable) { 517706f2543Smrg return BadImplementation; 518706f2543Smrg } 519706f2543Smrg else { 520706f2543Smrg (*pi->driver->Disable) (pi); 521706f2543Smrg pDev->on = FALSE; 522706f2543Smrg return Success; 523706f2543Smrg } 524706f2543Smrg 525706f2543Smrg return Success; 526706f2543Smrg 527706f2543Smrg case DEVICE_CLOSE: 528706f2543Smrg if (pDev->on) { 529706f2543Smrg if (!pi->driver->Disable) { 530706f2543Smrg return BadImplementation; 531706f2543Smrg } 532706f2543Smrg (*pi->driver->Disable) (pi); 533706f2543Smrg pDev->on = FALSE; 534706f2543Smrg } 535706f2543Smrg 536706f2543Smrg if (!pi->driver->Fini) 537706f2543Smrg return BadImplementation; 538706f2543Smrg 539706f2543Smrg (*pi->driver->Fini) (pi); 540706f2543Smrg 541706f2543Smrg KdRemovePointer(pi); 542706f2543Smrg 543706f2543Smrg return Success; 544706f2543Smrg } 545706f2543Smrg 546706f2543Smrg /* NOTREACHED */ 547706f2543Smrg return BadImplementation; 548706f2543Smrg} 549706f2543Smrg 550706f2543SmrgBool 551706f2543SmrgLegalModifier(unsigned int key, DeviceIntPtr pDev) 552706f2543Smrg{ 553706f2543Smrg return TRUE; 554706f2543Smrg} 555706f2543Smrg 556706f2543Smrgstatic void 557706f2543SmrgKdBell (int volume, DeviceIntPtr pDev, pointer arg, int something) 558706f2543Smrg{ 559706f2543Smrg KeybdCtrl *ctrl = arg; 560706f2543Smrg KdKeyboardInfo *ki = NULL; 561706f2543Smrg 562706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 563706f2543Smrg if (ki->dixdev && ki->dixdev->id == pDev->id) 564706f2543Smrg break; 565706f2543Smrg } 566706f2543Smrg 567706f2543Smrg if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) 568706f2543Smrg return; 569706f2543Smrg 570706f2543Smrg KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); 571706f2543Smrg} 572706f2543Smrg 573706f2543Smrgvoid 574706f2543SmrgDDXRingBell(int volume, int pitch, int duration) 575706f2543Smrg{ 576706f2543Smrg KdKeyboardInfo *ki = NULL; 577706f2543Smrg 578706f2543Smrg if (kdOsFuncs->Bell) { 579706f2543Smrg (*kdOsFuncs->Bell)(volume, pitch, duration); 580706f2543Smrg } 581706f2543Smrg else { 582706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 583706f2543Smrg if (ki->dixdev->coreEvents) 584706f2543Smrg KdRingBell(ki, volume, pitch, duration); 585706f2543Smrg } 586706f2543Smrg } 587706f2543Smrg} 588706f2543Smrg 589706f2543Smrgvoid 590706f2543SmrgKdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration) 591706f2543Smrg{ 592706f2543Smrg if (!ki || !ki->driver || !ki->driver->Bell) 593706f2543Smrg return; 594706f2543Smrg 595706f2543Smrg if (kdInputEnabled) 596706f2543Smrg (*ki->driver->Bell) (ki, volume, pitch, duration); 597706f2543Smrg} 598706f2543Smrg 599706f2543Smrg 600706f2543Smrgstatic void 601706f2543SmrgKdSetLeds (KdKeyboardInfo *ki, int leds) 602706f2543Smrg{ 603706f2543Smrg if (!ki || !ki->driver) 604706f2543Smrg return; 605706f2543Smrg 606706f2543Smrg if (kdInputEnabled) { 607706f2543Smrg if (ki->driver->Leds) 608706f2543Smrg (*ki->driver->Leds) (ki, leds); 609706f2543Smrg } 610706f2543Smrg} 611706f2543Smrg 612706f2543Smrgvoid 613706f2543SmrgKdSetLed (KdKeyboardInfo *ki, int led, Bool on) 614706f2543Smrg{ 615706f2543Smrg if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) 616706f2543Smrg return; 617706f2543Smrg 618706f2543Smrg NoteLedState (ki->dixdev, led, on); 619706f2543Smrg KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds); 620706f2543Smrg} 621706f2543Smrg 622706f2543Smrgvoid 623706f2543SmrgKdSetPointerMatrix (KdPointerMatrix *matrix) 624706f2543Smrg{ 625706f2543Smrg kdPointerMatrix = *matrix; 626706f2543Smrg} 627706f2543Smrg 628706f2543Smrgvoid 629706f2543SmrgKdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width, 630706f2543Smrg int height) 631706f2543Smrg{ 632706f2543Smrg int x_dir = 1, y_dir = 1; 633706f2543Smrg int i, j; 634706f2543Smrg int size[2]; 635706f2543Smrg 636706f2543Smrg size[0] = width; size[1] = height; 637706f2543Smrg if (randr & RR_Reflect_X) 638706f2543Smrg x_dir = -1; 639706f2543Smrg if (randr & RR_Reflect_Y) 640706f2543Smrg y_dir = -1; 641706f2543Smrg switch (randr & (RR_Rotate_All)) { 642706f2543Smrg case RR_Rotate_0: 643706f2543Smrg m->matrix[0][0] = x_dir; m->matrix[0][1] = 0; 644706f2543Smrg m->matrix[1][0] = 0; m->matrix[1][1] = y_dir; 645706f2543Smrg break; 646706f2543Smrg case RR_Rotate_90: 647706f2543Smrg m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir; 648706f2543Smrg m->matrix[1][0] = y_dir; m->matrix[1][1] = 0; 649706f2543Smrg break; 650706f2543Smrg case RR_Rotate_180: 651706f2543Smrg m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0; 652706f2543Smrg m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir; 653706f2543Smrg break; 654706f2543Smrg case RR_Rotate_270: 655706f2543Smrg m->matrix[0][0] = 0; m->matrix[0][1] = x_dir; 656706f2543Smrg m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0; 657706f2543Smrg break; 658706f2543Smrg } 659706f2543Smrg for (i = 0; i < 2; i++) 660706f2543Smrg { 661706f2543Smrg m->matrix[i][2] = 0; 662706f2543Smrg for (j = 0 ; j < 2; j++) 663706f2543Smrg if (m->matrix[i][j] < 0) 664706f2543Smrg m->matrix[i][2] = size[j] - 1; 665706f2543Smrg } 666706f2543Smrg} 667706f2543Smrg 668706f2543Smrgvoid 669706f2543SmrgKdScreenToPointerCoords (int *x, int *y) 670706f2543Smrg{ 671706f2543Smrg int (*m)[3] = kdPointerMatrix.matrix; 672706f2543Smrg int div = m[0][1] * m[1][0] - m[1][1] * m[0][0]; 673706f2543Smrg int sx = *x; 674706f2543Smrg int sy = *y; 675706f2543Smrg 676706f2543Smrg *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div; 677706f2543Smrg *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div; 678706f2543Smrg} 679706f2543Smrg 680706f2543Smrgstatic void 681706f2543SmrgKdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl) 682706f2543Smrg{ 683706f2543Smrg KdKeyboardInfo *ki; 684706f2543Smrg 685706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 686706f2543Smrg if (ki->dixdev && ki->dixdev->id == pDevice->id) 687706f2543Smrg break; 688706f2543Smrg } 689706f2543Smrg 690706f2543Smrg if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) 691706f2543Smrg return; 692706f2543Smrg 693706f2543Smrg KdSetLeds(ki, ctrl->leds); 694706f2543Smrg ki->bellPitch = ctrl->bell_pitch; 695706f2543Smrg ki->bellDuration = ctrl->bell_duration; 696706f2543Smrg} 697706f2543Smrg 698706f2543Smrgextern KeybdCtrl defaultKeyboardControl; 699706f2543Smrg 700706f2543Smrgstatic int 701706f2543SmrgKdKeyboardProc(DeviceIntPtr pDevice, int onoff) 702706f2543Smrg{ 703706f2543Smrg Bool ret; 704706f2543Smrg DevicePtr pDev = (DevicePtr)pDevice; 705706f2543Smrg KdKeyboardInfo *ki; 706706f2543Smrg Atom xiclass; 707706f2543Smrg XkbRMLVOSet rmlvo; 708706f2543Smrg 709706f2543Smrg if (!pDev) 710706f2543Smrg return BadImplementation; 711706f2543Smrg 712706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 713706f2543Smrg if (ki->dixdev && ki->dixdev->id == pDevice->id) 714706f2543Smrg break; 715706f2543Smrg } 716706f2543Smrg 717706f2543Smrg if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { 718706f2543Smrg return BadImplementation; 719706f2543Smrg } 720706f2543Smrg 721706f2543Smrg switch (onoff) 722706f2543Smrg { 723706f2543Smrg case DEVICE_INIT: 724706f2543Smrg#ifdef DEBUG 725706f2543Smrg ErrorF("initialising keyboard %s\n", ki->name); 726706f2543Smrg#endif 727706f2543Smrg if (!ki->driver) { 728706f2543Smrg if (!ki->driverPrivate) { 729706f2543Smrg ErrorF("no driver specified!\n"); 730706f2543Smrg return BadImplementation; 731706f2543Smrg } 732706f2543Smrg 733706f2543Smrg ki->driver = KdFindKeyboardDriver(ki->driverPrivate); 734706f2543Smrg if (!ki->driver) { 735706f2543Smrg ErrorF("Couldn't find keyboard driver %s\n", 736706f2543Smrg ki->driverPrivate ? (char *) ki->driverPrivate : 737706f2543Smrg "(unnamed)"); 738706f2543Smrg return !Success; 739706f2543Smrg } 740706f2543Smrg free(ki->driverPrivate); 741706f2543Smrg ki->driverPrivate = NULL; 742706f2543Smrg } 743706f2543Smrg 744706f2543Smrg if (!ki->driver->Init) { 745706f2543Smrg ErrorF("Keyboard %s: no init function\n", ki->name); 746706f2543Smrg return BadImplementation; 747706f2543Smrg } 748706f2543Smrg 749706f2543Smrg if ((*ki->driver->Init) (ki) != Success) { 750706f2543Smrg return !Success; 751706f2543Smrg } 752706f2543Smrg 753706f2543Smrg memset(&rmlvo, 0, sizeof(rmlvo)); 754706f2543Smrg rmlvo.rules = ki->xkbRules; 755706f2543Smrg rmlvo.model = ki->xkbModel; 756706f2543Smrg rmlvo.layout = ki->xkbLayout; 757706f2543Smrg rmlvo.variant = ki->xkbVariant; 758706f2543Smrg rmlvo.options = ki->xkbOptions; 759706f2543Smrg ret = InitKeyboardDeviceStruct (pDevice, &rmlvo, KdBell, KdKbdCtrl); 760706f2543Smrg if (!ret) { 761706f2543Smrg ErrorF("Couldn't initialise keyboard %s\n", ki->name); 762706f2543Smrg return BadImplementation; 763706f2543Smrg } 764706f2543Smrg 765706f2543Smrg xiclass = AtomFromName(XI_KEYBOARD); 766706f2543Smrg AssignTypeAndName(pDevice, xiclass, 767706f2543Smrg ki->name ? ki->name : "Generic KDrive Keyboard"); 768706f2543Smrg 769706f2543Smrg KdResetInputMachine(); 770706f2543Smrg 771706f2543Smrg return Success; 772706f2543Smrg 773706f2543Smrg case DEVICE_ON: 774706f2543Smrg if (pDev->on == TRUE) 775706f2543Smrg return Success; 776706f2543Smrg 777706f2543Smrg if (!ki->driver->Enable) 778706f2543Smrg return BadImplementation; 779706f2543Smrg 780706f2543Smrg if ((*ki->driver->Enable) (ki) != Success) { 781706f2543Smrg return BadMatch; 782706f2543Smrg } 783706f2543Smrg 784706f2543Smrg pDev->on = TRUE; 785706f2543Smrg return Success; 786706f2543Smrg 787706f2543Smrg case DEVICE_OFF: 788706f2543Smrg if (pDev->on == FALSE) 789706f2543Smrg return Success; 790706f2543Smrg 791706f2543Smrg if (!ki->driver->Disable) 792706f2543Smrg return BadImplementation; 793706f2543Smrg 794706f2543Smrg (*ki->driver->Disable) (ki); 795706f2543Smrg pDev->on = FALSE; 796706f2543Smrg 797706f2543Smrg return Success; 798706f2543Smrg 799706f2543Smrg break; 800706f2543Smrg 801706f2543Smrg case DEVICE_CLOSE: 802706f2543Smrg if (pDev->on) { 803706f2543Smrg if (!ki->driver->Disable) 804706f2543Smrg return BadImplementation; 805706f2543Smrg 806706f2543Smrg (*ki->driver->Disable) (ki); 807706f2543Smrg pDev->on = FALSE; 808706f2543Smrg } 809706f2543Smrg 810706f2543Smrg if (!ki->driver->Fini) 811706f2543Smrg return BadImplementation; 812706f2543Smrg 813706f2543Smrg (*ki->driver->Fini) (ki); 814706f2543Smrg 815706f2543Smrg KdRemoveKeyboard(ki); 816706f2543Smrg 817706f2543Smrg return Success; 818706f2543Smrg } 819706f2543Smrg 820706f2543Smrg /* NOTREACHED */ 821706f2543Smrg return BadImplementation; 822706f2543Smrg} 823706f2543Smrg 824706f2543Smrgvoid 825706f2543SmrgKdAddPointerDriver (KdPointerDriver *driver) 826706f2543Smrg{ 827706f2543Smrg KdPointerDriver **prev; 828706f2543Smrg 829706f2543Smrg if (!driver) 830706f2543Smrg return; 831706f2543Smrg 832706f2543Smrg for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { 833706f2543Smrg if (*prev == driver) 834706f2543Smrg return; 835706f2543Smrg } 836706f2543Smrg *prev = driver; 837706f2543Smrg} 838706f2543Smrg 839706f2543Smrgvoid 840706f2543SmrgKdRemovePointerDriver (KdPointerDriver *driver) 841706f2543Smrg{ 842706f2543Smrg KdPointerDriver *tmp; 843706f2543Smrg 844706f2543Smrg if (!driver) 845706f2543Smrg return; 846706f2543Smrg 847706f2543Smrg /* FIXME remove all pointers using this driver */ 848706f2543Smrg for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { 849706f2543Smrg if (tmp->next == driver) 850706f2543Smrg tmp->next = driver->next; 851706f2543Smrg } 852706f2543Smrg if (tmp == driver) 853706f2543Smrg tmp = NULL; 854706f2543Smrg} 855706f2543Smrg 856706f2543Smrgvoid 857706f2543SmrgKdAddKeyboardDriver (KdKeyboardDriver *driver) 858706f2543Smrg{ 859706f2543Smrg KdKeyboardDriver **prev; 860706f2543Smrg 861706f2543Smrg if (!driver) 862706f2543Smrg return; 863706f2543Smrg 864706f2543Smrg for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { 865706f2543Smrg if (*prev == driver) 866706f2543Smrg return; 867706f2543Smrg } 868706f2543Smrg *prev = driver; 869706f2543Smrg} 870706f2543Smrg 871706f2543Smrgvoid 872706f2543SmrgKdRemoveKeyboardDriver (KdKeyboardDriver *driver) 873706f2543Smrg{ 874706f2543Smrg KdKeyboardDriver *tmp; 875706f2543Smrg 876706f2543Smrg if (!driver) 877706f2543Smrg return; 878706f2543Smrg 879706f2543Smrg /* FIXME remove all keyboards using this driver */ 880706f2543Smrg for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { 881706f2543Smrg if (tmp->next == driver) 882706f2543Smrg tmp->next = driver->next; 883706f2543Smrg } 884706f2543Smrg if (tmp == driver) 885706f2543Smrg tmp = NULL; 886706f2543Smrg} 887706f2543Smrg 888706f2543SmrgKdKeyboardInfo * 889706f2543SmrgKdNewKeyboard (void) 890706f2543Smrg{ 891706f2543Smrg KdKeyboardInfo *ki = calloc(sizeof(KdKeyboardInfo), 1); 892706f2543Smrg if (!ki) 893706f2543Smrg return NULL; 894706f2543Smrg 895706f2543Smrg ki->minScanCode = 0; 896706f2543Smrg ki->maxScanCode = 0; 897706f2543Smrg ki->leds = 0; 898706f2543Smrg ki->bellPitch = 1000; 899706f2543Smrg ki->bellDuration = 200; 900706f2543Smrg ki->next = NULL; 901706f2543Smrg ki->options = NULL; 902706f2543Smrg ki->xkbRules = strdup(XKB_DFLT_RULES); 903706f2543Smrg ki->xkbModel = strdup(XKB_DFLT_MODEL); 904706f2543Smrg ki->xkbLayout = strdup(XKB_DFLT_LAYOUT); 905706f2543Smrg ki->xkbVariant = strdup(XKB_DFLT_VARIANT); 906706f2543Smrg ki->xkbOptions = strdup(XKB_DFLT_OPTIONS); 907706f2543Smrg 908706f2543Smrg return ki; 909706f2543Smrg} 910706f2543Smrg 911706f2543Smrgint 912706f2543SmrgKdAddConfigKeyboard (char *keyboard) 913706f2543Smrg{ 914706f2543Smrg struct KdConfigDevice **prev, *new; 915706f2543Smrg 916706f2543Smrg if (!keyboard) 917706f2543Smrg return Success; 918706f2543Smrg 919706f2543Smrg new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1); 920706f2543Smrg if (!new) 921706f2543Smrg return BadAlloc; 922706f2543Smrg 923706f2543Smrg new->line = strdup(keyboard); 924706f2543Smrg new->next = NULL; 925706f2543Smrg 926706f2543Smrg for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); 927706f2543Smrg *prev = new; 928706f2543Smrg 929706f2543Smrg return Success; 930706f2543Smrg} 931706f2543Smrg 932706f2543Smrgint 933706f2543SmrgKdAddKeyboard (KdKeyboardInfo *ki) 934706f2543Smrg{ 935706f2543Smrg KdKeyboardInfo **prev; 936706f2543Smrg 937706f2543Smrg if (!ki) 938706f2543Smrg return !Success; 939706f2543Smrg 940706f2543Smrg ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE); 941706f2543Smrg if (!ki->dixdev) { 942706f2543Smrg ErrorF("Couldn't register keyboard device %s\n", 943706f2543Smrg ki->name ? ki->name : "(unnamed)"); 944706f2543Smrg return !Success; 945706f2543Smrg } 946706f2543Smrg 947706f2543Smrg#ifdef DEBUG 948706f2543Smrg ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); 949706f2543Smrg#endif 950706f2543Smrg 951706f2543Smrg for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); 952706f2543Smrg *prev = ki; 953706f2543Smrg 954706f2543Smrg return Success; 955706f2543Smrg} 956706f2543Smrg 957706f2543Smrgvoid 958706f2543SmrgKdRemoveKeyboard (KdKeyboardInfo *ki) 959706f2543Smrg{ 960706f2543Smrg KdKeyboardInfo **prev; 961706f2543Smrg 962706f2543Smrg if (!ki) 963706f2543Smrg return; 964706f2543Smrg 965706f2543Smrg for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { 966706f2543Smrg if (*prev == ki) { 967706f2543Smrg *prev = ki->next; 968706f2543Smrg break; 969706f2543Smrg } 970706f2543Smrg } 971706f2543Smrg 972706f2543Smrg KdFreeKeyboard(ki); 973706f2543Smrg} 974706f2543Smrg 975706f2543Smrgint 976706f2543SmrgKdAddConfigPointer (char *pointer) 977706f2543Smrg{ 978706f2543Smrg struct KdConfigDevice **prev, *new; 979706f2543Smrg 980706f2543Smrg if (!pointer) 981706f2543Smrg return Success; 982706f2543Smrg 983706f2543Smrg new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1); 984706f2543Smrg if (!new) 985706f2543Smrg return BadAlloc; 986706f2543Smrg 987706f2543Smrg new->line = strdup(pointer); 988706f2543Smrg new->next = NULL; 989706f2543Smrg 990706f2543Smrg for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); 991706f2543Smrg *prev = new; 992706f2543Smrg 993706f2543Smrg return Success; 994706f2543Smrg} 995706f2543Smrg 996706f2543Smrgint 997706f2543SmrgKdAddPointer (KdPointerInfo *pi) 998706f2543Smrg{ 999706f2543Smrg KdPointerInfo **prev; 1000706f2543Smrg 1001706f2543Smrg if (!pi) 1002706f2543Smrg return Success; 1003706f2543Smrg 1004706f2543Smrg pi->mouseState = start; 1005706f2543Smrg pi->eventHeld = FALSE; 1006706f2543Smrg 1007706f2543Smrg pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE); 1008706f2543Smrg if (!pi->dixdev) { 1009706f2543Smrg ErrorF("Couldn't add pointer device %s\n", 1010706f2543Smrg pi->name ? pi->name : "(unnamed)"); 1011706f2543Smrg return BadDevice; 1012706f2543Smrg } 1013706f2543Smrg 1014706f2543Smrg for (prev = &kdPointers; *prev; prev = &(*prev)->next); 1015706f2543Smrg *prev = pi; 1016706f2543Smrg 1017706f2543Smrg return Success; 1018706f2543Smrg} 1019706f2543Smrg 1020706f2543Smrgvoid 1021706f2543SmrgKdRemovePointer (KdPointerInfo *pi) 1022706f2543Smrg{ 1023706f2543Smrg KdPointerInfo **prev; 1024706f2543Smrg 1025706f2543Smrg if (!pi) 1026706f2543Smrg return; 1027706f2543Smrg 1028706f2543Smrg for (prev = &kdPointers; *prev; prev = &(*prev)->next) { 1029706f2543Smrg if (*prev == pi) { 1030706f2543Smrg *prev = pi->next; 1031706f2543Smrg break; 1032706f2543Smrg } 1033706f2543Smrg } 1034706f2543Smrg 1035706f2543Smrg KdFreePointer(pi); 1036706f2543Smrg} 1037706f2543Smrg 1038706f2543Smrg/* 1039706f2543Smrg * You can call your kdriver server with something like: 1040706f2543Smrg * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd 1041706f2543Smrg * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br 1042706f2543Smrg */ 1043706f2543Smrgstatic Bool 1044706f2543SmrgKdGetOptions (InputOption **options, char *string) 1045706f2543Smrg{ 1046706f2543Smrg InputOption *newopt = NULL, **tmpo = NULL; 1047706f2543Smrg int tam_key = 0; 1048706f2543Smrg 1049706f2543Smrg newopt = calloc(1, sizeof (InputOption)); 1050706f2543Smrg if (!newopt) 1051706f2543Smrg return FALSE; 1052706f2543Smrg 1053706f2543Smrg for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) 1054706f2543Smrg ; /* Hello, I'm here */ 1055706f2543Smrg *tmpo = newopt; 1056706f2543Smrg 1057706f2543Smrg if (strchr(string, '=')) 1058706f2543Smrg { 1059706f2543Smrg tam_key = (strchr(string, '=') - string); 1060706f2543Smrg newopt->key = (char *)malloc(tam_key); 1061706f2543Smrg strncpy(newopt->key, string, tam_key); 1062706f2543Smrg newopt->key[tam_key] = '\0'; 1063706f2543Smrg newopt->value = strdup(strchr(string, '=') + 1); 1064706f2543Smrg } 1065706f2543Smrg else 1066706f2543Smrg { 1067706f2543Smrg newopt->key = strdup(string); 1068706f2543Smrg newopt->value = NULL; 1069706f2543Smrg } 1070706f2543Smrg newopt->next = NULL; 1071706f2543Smrg 1072706f2543Smrg return TRUE; 1073706f2543Smrg} 1074706f2543Smrg 1075706f2543Smrgstatic void 1076706f2543SmrgKdParseKbdOptions (KdKeyboardInfo *ki) 1077706f2543Smrg{ 1078706f2543Smrg InputOption *option = NULL; 1079706f2543Smrg 1080706f2543Smrg for (option = ki->options; option; option = option->next) 1081706f2543Smrg { 1082706f2543Smrg if (strcasecmp(option->key, "XkbRules") == 0) 1083706f2543Smrg ki->xkbRules = option->value; 1084706f2543Smrg else if (strcasecmp(option->key, "XkbModel") == 0) 1085706f2543Smrg ki->xkbModel = option->value; 1086706f2543Smrg else if (strcasecmp(option->key, "XkbLayout") == 0) 1087706f2543Smrg ki->xkbLayout = option->value; 1088706f2543Smrg else if (strcasecmp(option->key, "XkbVariant") == 0) 1089706f2543Smrg ki->xkbVariant = option->value; 1090706f2543Smrg else if (strcasecmp(option->key, "XkbOptions") == 0) 1091706f2543Smrg ki->xkbOptions = option->value; 1092706f2543Smrg else if (!strcasecmp (option->key, "device")) 1093706f2543Smrg ki->path = strdup(option->value); 1094706f2543Smrg else 1095706f2543Smrg ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", 1096706f2543Smrg option->key, option->value); 1097706f2543Smrg } 1098706f2543Smrg} 1099706f2543Smrg 1100706f2543SmrgKdKeyboardInfo * 1101706f2543SmrgKdParseKeyboard (char *arg) 1102706f2543Smrg{ 1103706f2543Smrg char save[1024]; 1104706f2543Smrg char delim; 1105706f2543Smrg InputOption *options = NULL; 1106706f2543Smrg KdKeyboardInfo *ki = NULL; 1107706f2543Smrg 1108706f2543Smrg ki = KdNewKeyboard(); 1109706f2543Smrg if (!ki) 1110706f2543Smrg return NULL; 1111706f2543Smrg 1112706f2543Smrg ki->name = strdup("Unknown KDrive Keyboard"); 1113706f2543Smrg ki->path = NULL; 1114706f2543Smrg ki->driver = NULL; 1115706f2543Smrg ki->driverPrivate = NULL; 1116706f2543Smrg ki->next = NULL; 1117706f2543Smrg 1118706f2543Smrg if (!arg) 1119706f2543Smrg { 1120706f2543Smrg ErrorF("keybd: no arg\n"); 1121706f2543Smrg KdFreeKeyboard (ki); 1122706f2543Smrg return NULL; 1123706f2543Smrg } 1124706f2543Smrg 1125706f2543Smrg if (strlen (arg) >= sizeof (save)) 1126706f2543Smrg { 1127706f2543Smrg ErrorF("keybd: arg too long\n"); 1128706f2543Smrg KdFreeKeyboard (ki); 1129706f2543Smrg return NULL; 1130706f2543Smrg } 1131706f2543Smrg 1132706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1133706f2543Smrg if (!save[0]) 1134706f2543Smrg { 1135706f2543Smrg ErrorF("keybd: failed on save[0]\n"); 1136706f2543Smrg KdFreeKeyboard (ki); 1137706f2543Smrg return NULL; 1138706f2543Smrg } 1139706f2543Smrg 1140706f2543Smrg if (strcmp (save, "auto") == 0) 1141706f2543Smrg ki->driverPrivate = NULL; 1142706f2543Smrg else 1143706f2543Smrg ki->driverPrivate = strdup(save); 1144706f2543Smrg 1145706f2543Smrg if (delim != ',') 1146706f2543Smrg { 1147706f2543Smrg return ki; 1148706f2543Smrg } 1149706f2543Smrg 1150706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1151706f2543Smrg 1152706f2543Smrg while (delim == ',') 1153706f2543Smrg { 1154706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1155706f2543Smrg 1156706f2543Smrg if (!KdGetOptions(&options, save)) 1157706f2543Smrg { 1158706f2543Smrg KdFreeKeyboard(ki); 1159706f2543Smrg return NULL; 1160706f2543Smrg } 1161706f2543Smrg } 1162706f2543Smrg 1163706f2543Smrg if (options) 1164706f2543Smrg { 1165706f2543Smrg ki->options = options; 1166706f2543Smrg KdParseKbdOptions(ki); 1167706f2543Smrg } 1168706f2543Smrg 1169706f2543Smrg return ki; 1170706f2543Smrg} 1171706f2543Smrg 1172706f2543Smrgstatic void 1173706f2543SmrgKdParsePointerOptions (KdPointerInfo *pi) 1174706f2543Smrg{ 1175706f2543Smrg InputOption *option = NULL; 1176706f2543Smrg 1177706f2543Smrg for (option = pi->options; option; option = option->next) 1178706f2543Smrg { 1179706f2543Smrg if (!strcmp (option->key, "emulatemiddle")) 1180706f2543Smrg pi->emulateMiddleButton = TRUE; 1181706f2543Smrg else if (!strcmp (option->key, "noemulatemiddle")) 1182706f2543Smrg pi->emulateMiddleButton = FALSE; 1183706f2543Smrg else if (!strcmp (option->key, "transformcoord")) 1184706f2543Smrg pi->transformCoordinates = TRUE; 1185706f2543Smrg else if (!strcmp (option->key, "rawcoord")) 1186706f2543Smrg pi->transformCoordinates = FALSE; 1187706f2543Smrg else if (!strcasecmp (option->key, "device")) 1188706f2543Smrg pi->path = strdup(option->value); 1189706f2543Smrg else if (!strcasecmp (option->key, "protocol")) 1190706f2543Smrg pi->protocol = strdup(option->value); 1191706f2543Smrg else 1192706f2543Smrg ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", 1193706f2543Smrg option->key, option->value); 1194706f2543Smrg } 1195706f2543Smrg} 1196706f2543Smrg 1197706f2543SmrgKdPointerInfo * 1198706f2543SmrgKdParsePointer (char *arg) 1199706f2543Smrg{ 1200706f2543Smrg char save[1024]; 1201706f2543Smrg char delim; 1202706f2543Smrg KdPointerInfo *pi = NULL; 1203706f2543Smrg InputOption *options = NULL; 1204706f2543Smrg int i = 0; 1205706f2543Smrg 1206706f2543Smrg pi = KdNewPointer(); 1207706f2543Smrg if (!pi) 1208706f2543Smrg return NULL; 1209706f2543Smrg pi->emulateMiddleButton = kdEmulateMiddleButton; 1210706f2543Smrg pi->transformCoordinates = !kdRawPointerCoordinates; 1211706f2543Smrg pi->protocol = NULL; 1212706f2543Smrg pi->nButtons = 5; /* XXX should not be hardcoded */ 1213706f2543Smrg pi->inputClass = KD_MOUSE; 1214706f2543Smrg 1215706f2543Smrg if (!arg) 1216706f2543Smrg { 1217706f2543Smrg ErrorF("mouse: no arg\n"); 1218706f2543Smrg KdFreePointer (pi); 1219706f2543Smrg return NULL; 1220706f2543Smrg } 1221706f2543Smrg 1222706f2543Smrg if (strlen (arg) >= sizeof (save)) 1223706f2543Smrg { 1224706f2543Smrg ErrorF("mouse: arg too long\n"); 1225706f2543Smrg KdFreePointer (pi); 1226706f2543Smrg return NULL; 1227706f2543Smrg } 1228706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1229706f2543Smrg if (!save[0]) 1230706f2543Smrg { 1231706f2543Smrg ErrorF("failed on save[0]\n"); 1232706f2543Smrg KdFreePointer (pi); 1233706f2543Smrg return NULL; 1234706f2543Smrg } 1235706f2543Smrg 1236706f2543Smrg if (strcmp(save, "auto") == 0) 1237706f2543Smrg pi->driverPrivate = NULL; 1238706f2543Smrg else 1239706f2543Smrg pi->driverPrivate = strdup(save); 1240706f2543Smrg 1241706f2543Smrg if (delim != ',') 1242706f2543Smrg { 1243706f2543Smrg return pi; 1244706f2543Smrg } 1245706f2543Smrg 1246706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1247706f2543Smrg 1248706f2543Smrg while (delim == ',') 1249706f2543Smrg { 1250706f2543Smrg arg = KdParseFindNext (arg, ",", save, &delim); 1251706f2543Smrg if (save[0] == '{') 1252706f2543Smrg { 1253706f2543Smrg char *s = save + 1; 1254706f2543Smrg i = 0; 1255706f2543Smrg while (*s && *s != '}') 1256706f2543Smrg { 1257706f2543Smrg if ('1' <= *s && *s <= '0' + pi->nButtons) 1258706f2543Smrg pi->map[i] = *s - '0'; 1259706f2543Smrg else 1260706f2543Smrg UseMsg (); 1261706f2543Smrg s++; 1262706f2543Smrg } 1263706f2543Smrg } 1264706f2543Smrg else 1265706f2543Smrg { 1266706f2543Smrg if (!KdGetOptions(&options, save)) 1267706f2543Smrg { 1268706f2543Smrg KdFreePointer(pi); 1269706f2543Smrg return NULL; 1270706f2543Smrg } 1271706f2543Smrg } 1272706f2543Smrg } 1273706f2543Smrg 1274706f2543Smrg if (options) 1275706f2543Smrg { 1276706f2543Smrg pi->options = options; 1277706f2543Smrg KdParsePointerOptions(pi); 1278706f2543Smrg } 1279706f2543Smrg 1280706f2543Smrg return pi; 1281706f2543Smrg} 1282706f2543Smrg 1283706f2543Smrg 1284706f2543Smrgvoid 1285706f2543SmrgKdInitInput (void) 1286706f2543Smrg{ 1287706f2543Smrg KdPointerInfo *pi; 1288706f2543Smrg KdKeyboardInfo *ki; 1289706f2543Smrg struct KdConfigDevice *dev; 1290706f2543Smrg 1291706f2543Smrg kdInputEnabled = TRUE; 1292706f2543Smrg 1293706f2543Smrg for (dev = kdConfigPointers; dev; dev = dev->next) { 1294706f2543Smrg pi = KdParsePointer(dev->line); 1295706f2543Smrg if (!pi) 1296706f2543Smrg ErrorF("Failed to parse pointer\n"); 1297706f2543Smrg if (KdAddPointer(pi) != Success) 1298706f2543Smrg ErrorF("Failed to add pointer!\n"); 1299706f2543Smrg } 1300706f2543Smrg for (dev = kdConfigKeyboards; dev; dev = dev->next) { 1301706f2543Smrg ki = KdParseKeyboard(dev->line); 1302706f2543Smrg if (!ki) 1303706f2543Smrg ErrorF("Failed to parse keyboard\n"); 1304706f2543Smrg if (KdAddKeyboard(ki) != Success) 1305706f2543Smrg ErrorF("Failed to add keyboard!\n"); 1306706f2543Smrg } 1307706f2543Smrg 1308706f2543Smrg mieqInit(); 1309706f2543Smrg} 1310706f2543Smrg 1311706f2543Smrg/* 1312706f2543Smrg * Middle button emulation state machine 1313706f2543Smrg * 1314706f2543Smrg * Possible transitions: 1315706f2543Smrg * Button 1 press v1 1316706f2543Smrg * Button 1 release ^1 1317706f2543Smrg * Button 2 press v2 1318706f2543Smrg * Button 2 release ^2 1319706f2543Smrg * Button 3 press v3 1320706f2543Smrg * Button 3 release ^3 1321706f2543Smrg * Button other press vo 1322706f2543Smrg * Button other release ^o 1323706f2543Smrg * Mouse motion <> 1324706f2543Smrg * Keyboard event k 1325706f2543Smrg * timeout ... 1326706f2543Smrg * outside box <-> 1327706f2543Smrg * 1328706f2543Smrg * States: 1329706f2543Smrg * start 1330706f2543Smrg * button_1_pend 1331706f2543Smrg * button_1_down 1332706f2543Smrg * button_2_down 1333706f2543Smrg * button_3_pend 1334706f2543Smrg * button_3_down 1335706f2543Smrg * synthetic_2_down_13 1336706f2543Smrg * synthetic_2_down_3 1337706f2543Smrg * synthetic_2_down_1 1338706f2543Smrg * 1339706f2543Smrg * Transition diagram 1340706f2543Smrg * 1341706f2543Smrg * start 1342706f2543Smrg * v1 -> (hold) (settimeout) button_1_pend 1343706f2543Smrg * ^1 -> (deliver) start 1344706f2543Smrg * v2 -> (deliver) button_2_down 1345706f2543Smrg * ^2 -> (deliever) start 1346706f2543Smrg * v3 -> (hold) (settimeout) button_3_pend 1347706f2543Smrg * ^3 -> (deliver) start 1348706f2543Smrg * vo -> (deliver) start 1349706f2543Smrg * ^o -> (deliver) start 1350706f2543Smrg * <> -> (deliver) start 1351706f2543Smrg * k -> (deliver) start 1352706f2543Smrg * 1353706f2543Smrg * button_1_pend (button 1 is down, timeout pending) 1354706f2543Smrg * ^1 -> (release) (deliver) start 1355706f2543Smrg * v2 -> (release) (deliver) button_1_down 1356706f2543Smrg * ^2 -> (release) (deliver) button_1_down 1357706f2543Smrg * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 1358706f2543Smrg * ^3 -> (release) (deliver) button_1_down 1359706f2543Smrg * vo -> (release) (deliver) button_1_down 1360706f2543Smrg * ^o -> (release) (deliver) button_1_down 1361706f2543Smrg * <-> -> (release) (deliver) button_1_down 1362706f2543Smrg * <> -> (deliver) button_1_pend 1363706f2543Smrg * k -> (release) (deliver) button_1_down 1364706f2543Smrg * ... -> (release) button_1_down 1365706f2543Smrg * 1366706f2543Smrg * button_1_down (button 1 is down) 1367706f2543Smrg * ^1 -> (deliver) start 1368706f2543Smrg * v2 -> (deliver) button_1_down 1369706f2543Smrg * ^2 -> (deliver) button_1_down 1370706f2543Smrg * v3 -> (deliver) button_1_down 1371706f2543Smrg * ^3 -> (deliver) button_1_down 1372706f2543Smrg * vo -> (deliver) button_1_down 1373706f2543Smrg * ^o -> (deliver) button_1_down 1374706f2543Smrg * <> -> (deliver) button_1_down 1375706f2543Smrg * k -> (deliver) button_1_down 1376706f2543Smrg * 1377706f2543Smrg * button_2_down (button 2 is down) 1378706f2543Smrg * v1 -> (deliver) button_2_down 1379706f2543Smrg * ^1 -> (deliver) button_2_down 1380706f2543Smrg * ^2 -> (deliver) start 1381706f2543Smrg * v3 -> (deliver) button_2_down 1382706f2543Smrg * ^3 -> (deliver) button_2_down 1383706f2543Smrg * vo -> (deliver) button_2_down 1384706f2543Smrg * ^o -> (deliver) button_2_down 1385706f2543Smrg * <> -> (deliver) button_2_down 1386706f2543Smrg * k -> (deliver) button_2_down 1387706f2543Smrg * 1388706f2543Smrg * button_3_pend (button 3 is down, timeout pending) 1389706f2543Smrg * v1 -> (generate v2) synthetic_2_down 1390706f2543Smrg * ^1 -> (release) (deliver) button_3_down 1391706f2543Smrg * v2 -> (release) (deliver) button_3_down 1392706f2543Smrg * ^2 -> (release) (deliver) button_3_down 1393706f2543Smrg * ^3 -> (release) (deliver) start 1394706f2543Smrg * vo -> (release) (deliver) button_3_down 1395706f2543Smrg * ^o -> (release) (deliver) button_3_down 1396706f2543Smrg * <-> -> (release) (deliver) button_3_down 1397706f2543Smrg * <> -> (deliver) button_3_pend 1398706f2543Smrg * k -> (release) (deliver) button_3_down 1399706f2543Smrg * ... -> (release) button_3_down 1400706f2543Smrg * 1401706f2543Smrg * button_3_down (button 3 is down) 1402706f2543Smrg * v1 -> (deliver) button_3_down 1403706f2543Smrg * ^1 -> (deliver) button_3_down 1404706f2543Smrg * v2 -> (deliver) button_3_down 1405706f2543Smrg * ^2 -> (deliver) button_3_down 1406706f2543Smrg * ^3 -> (deliver) start 1407706f2543Smrg * vo -> (deliver) button_3_down 1408706f2543Smrg * ^o -> (deliver) button_3_down 1409706f2543Smrg * <> -> (deliver) button_3_down 1410706f2543Smrg * k -> (deliver) button_3_down 1411706f2543Smrg * 1412706f2543Smrg * synthetic_2_down_13 (button 1 and 3 are down) 1413706f2543Smrg * ^1 -> (generate ^2) synthetic_2_down_3 1414706f2543Smrg * v2 -> synthetic_2_down_13 1415706f2543Smrg * ^2 -> synthetic_2_down_13 1416706f2543Smrg * ^3 -> (generate ^2) synthetic_2_down_1 1417706f2543Smrg * vo -> (deliver) synthetic_2_down_13 1418706f2543Smrg * ^o -> (deliver) synthetic_2_down_13 1419706f2543Smrg * <> -> (deliver) synthetic_2_down_13 1420706f2543Smrg * k -> (deliver) synthetic_2_down_13 1421706f2543Smrg * 1422706f2543Smrg * synthetic_2_down_3 (button 3 is down) 1423706f2543Smrg * v1 -> (deliver) synthetic_2_down_3 1424706f2543Smrg * ^1 -> (deliver) synthetic_2_down_3 1425706f2543Smrg * v2 -> synthetic_2_down_3 1426706f2543Smrg * ^2 -> synthetic_2_down_3 1427706f2543Smrg * ^3 -> start 1428706f2543Smrg * vo -> (deliver) synthetic_2_down_3 1429706f2543Smrg * ^o -> (deliver) synthetic_2_down_3 1430706f2543Smrg * <> -> (deliver) synthetic_2_down_3 1431706f2543Smrg * k -> (deliver) synthetic_2_down_3 1432706f2543Smrg * 1433706f2543Smrg * synthetic_2_down_1 (button 1 is down) 1434706f2543Smrg * ^1 -> start 1435706f2543Smrg * v2 -> synthetic_2_down_1 1436706f2543Smrg * ^2 -> synthetic_2_down_1 1437706f2543Smrg * v3 -> (deliver) synthetic_2_down_1 1438706f2543Smrg * ^3 -> (deliver) synthetic_2_down_1 1439706f2543Smrg * vo -> (deliver) synthetic_2_down_1 1440706f2543Smrg * ^o -> (deliver) synthetic_2_down_1 1441706f2543Smrg * <> -> (deliver) synthetic_2_down_1 1442706f2543Smrg * k -> (deliver) synthetic_2_down_1 1443706f2543Smrg */ 1444706f2543Smrg 1445706f2543Smrgtypedef enum _inputClass { 1446706f2543Smrg down_1, up_1, 1447706f2543Smrg down_2, up_2, 1448706f2543Smrg down_3, up_3, 1449706f2543Smrg down_o, up_o, 1450706f2543Smrg motion, outside_box, 1451706f2543Smrg keyboard, timeout, 1452706f2543Smrg num_input_class 1453706f2543Smrg} KdInputClass; 1454706f2543Smrg 1455706f2543Smrgtypedef enum _inputAction { 1456706f2543Smrg noop, 1457706f2543Smrg hold, 1458706f2543Smrg setto, 1459706f2543Smrg deliver, 1460706f2543Smrg release, 1461706f2543Smrg clearto, 1462706f2543Smrg gen_down_2, 1463706f2543Smrg gen_up_2 1464706f2543Smrg} KdInputAction; 1465706f2543Smrg 1466706f2543Smrg#define MAX_ACTIONS 2 1467706f2543Smrg 1468706f2543Smrgtypedef struct _inputTransition { 1469706f2543Smrg KdInputAction actions[MAX_ACTIONS]; 1470706f2543Smrg KdPointerState nextState; 1471706f2543Smrg} KdInputTransition; 1472706f2543Smrg 1473706f2543Smrgstatic const 1474706f2543SmrgKdInputTransition kdInputMachine[num_input_states][num_input_class] = { 1475706f2543Smrg /* start */ 1476706f2543Smrg { 1477706f2543Smrg { { hold, setto }, button_1_pend }, /* v1 */ 1478706f2543Smrg { { deliver, noop }, start }, /* ^1 */ 1479706f2543Smrg { { deliver, noop }, button_2_down }, /* v2 */ 1480706f2543Smrg { { deliver, noop }, start }, /* ^2 */ 1481706f2543Smrg { { hold, setto }, button_3_pend }, /* v3 */ 1482706f2543Smrg { { deliver, noop }, start }, /* ^3 */ 1483706f2543Smrg { { deliver, noop }, start }, /* vo */ 1484706f2543Smrg { { deliver, noop }, start }, /* ^o */ 1485706f2543Smrg { { deliver, noop }, start }, /* <> */ 1486706f2543Smrg { { deliver, noop }, start }, /* <-> */ 1487706f2543Smrg { { noop, noop }, start }, /* k */ 1488706f2543Smrg { { noop, noop }, start }, /* ... */ 1489706f2543Smrg }, 1490706f2543Smrg /* button_1_pend */ 1491706f2543Smrg { 1492706f2543Smrg { { noop, noop }, button_1_pend }, /* v1 */ 1493706f2543Smrg { { release, deliver }, start }, /* ^1 */ 1494706f2543Smrg { { release, deliver }, button_1_down }, /* v2 */ 1495706f2543Smrg { { release, deliver }, button_1_down }, /* ^2 */ 1496706f2543Smrg { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ 1497706f2543Smrg { { release, deliver }, button_1_down }, /* ^3 */ 1498706f2543Smrg { { release, deliver }, button_1_down }, /* vo */ 1499706f2543Smrg { { release, deliver }, button_1_down }, /* ^o */ 1500706f2543Smrg { { deliver, noop }, button_1_pend }, /* <> */ 1501706f2543Smrg { { release, deliver }, button_1_down }, /* <-> */ 1502706f2543Smrg { { noop, noop }, button_1_down }, /* k */ 1503706f2543Smrg { { release, noop }, button_1_down }, /* ... */ 1504706f2543Smrg }, 1505706f2543Smrg /* button_1_down */ 1506706f2543Smrg { 1507706f2543Smrg { { noop, noop }, button_1_down }, /* v1 */ 1508706f2543Smrg { { deliver, noop }, start }, /* ^1 */ 1509706f2543Smrg { { deliver, noop }, button_1_down }, /* v2 */ 1510706f2543Smrg { { deliver, noop }, button_1_down }, /* ^2 */ 1511706f2543Smrg { { deliver, noop }, button_1_down }, /* v3 */ 1512706f2543Smrg { { deliver, noop }, button_1_down }, /* ^3 */ 1513706f2543Smrg { { deliver, noop }, button_1_down }, /* vo */ 1514706f2543Smrg { { deliver, noop }, button_1_down }, /* ^o */ 1515706f2543Smrg { { deliver, noop }, button_1_down }, /* <> */ 1516706f2543Smrg { { deliver, noop }, button_1_down }, /* <-> */ 1517706f2543Smrg { { noop, noop }, button_1_down }, /* k */ 1518706f2543Smrg { { noop, noop }, button_1_down }, /* ... */ 1519706f2543Smrg }, 1520706f2543Smrg /* button_2_down */ 1521706f2543Smrg { 1522706f2543Smrg { { deliver, noop }, button_2_down }, /* v1 */ 1523706f2543Smrg { { deliver, noop }, button_2_down }, /* ^1 */ 1524706f2543Smrg { { noop, noop }, button_2_down }, /* v2 */ 1525706f2543Smrg { { deliver, noop }, start }, /* ^2 */ 1526706f2543Smrg { { deliver, noop }, button_2_down }, /* v3 */ 1527706f2543Smrg { { deliver, noop }, button_2_down }, /* ^3 */ 1528706f2543Smrg { { deliver, noop }, button_2_down }, /* vo */ 1529706f2543Smrg { { deliver, noop }, button_2_down }, /* ^o */ 1530706f2543Smrg { { deliver, noop }, button_2_down }, /* <> */ 1531706f2543Smrg { { deliver, noop }, button_2_down }, /* <-> */ 1532706f2543Smrg { { noop, noop }, button_2_down }, /* k */ 1533706f2543Smrg { { noop, noop }, button_2_down }, /* ... */ 1534706f2543Smrg }, 1535706f2543Smrg /* button_3_pend */ 1536706f2543Smrg { 1537706f2543Smrg { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ 1538706f2543Smrg { { release, deliver }, button_3_down }, /* ^1 */ 1539706f2543Smrg { { release, deliver }, button_3_down }, /* v2 */ 1540706f2543Smrg { { release, deliver }, button_3_down }, /* ^2 */ 1541706f2543Smrg { { release, deliver }, button_3_down }, /* v3 */ 1542706f2543Smrg { { release, deliver }, start }, /* ^3 */ 1543706f2543Smrg { { release, deliver }, button_3_down }, /* vo */ 1544706f2543Smrg { { release, deliver }, button_3_down }, /* ^o */ 1545706f2543Smrg { { deliver, noop }, button_3_pend }, /* <> */ 1546706f2543Smrg { { release, deliver }, button_3_down }, /* <-> */ 1547706f2543Smrg { { release, noop }, button_3_down }, /* k */ 1548706f2543Smrg { { release, noop }, button_3_down }, /* ... */ 1549706f2543Smrg }, 1550706f2543Smrg /* button_3_down */ 1551706f2543Smrg { 1552706f2543Smrg { { deliver, noop }, button_3_down }, /* v1 */ 1553706f2543Smrg { { deliver, noop }, button_3_down }, /* ^1 */ 1554706f2543Smrg { { deliver, noop }, button_3_down }, /* v2 */ 1555706f2543Smrg { { deliver, noop }, button_3_down }, /* ^2 */ 1556706f2543Smrg { { noop, noop }, button_3_down }, /* v3 */ 1557706f2543Smrg { { deliver, noop }, start }, /* ^3 */ 1558706f2543Smrg { { deliver, noop }, button_3_down }, /* vo */ 1559706f2543Smrg { { deliver, noop }, button_3_down }, /* ^o */ 1560706f2543Smrg { { deliver, noop }, button_3_down }, /* <> */ 1561706f2543Smrg { { deliver, noop }, button_3_down }, /* <-> */ 1562706f2543Smrg { { noop, noop }, button_3_down }, /* k */ 1563706f2543Smrg { { noop, noop }, button_3_down }, /* ... */ 1564706f2543Smrg }, 1565706f2543Smrg /* synthetic_2_down_13 */ 1566706f2543Smrg { 1567706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* v1 */ 1568706f2543Smrg { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ 1569706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* v2 */ 1570706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* ^2 */ 1571706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* v3 */ 1572706f2543Smrg { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ 1573706f2543Smrg { { deliver, noop }, synth_2_down_13 }, /* vo */ 1574706f2543Smrg { { deliver, noop }, synth_2_down_13 }, /* ^o */ 1575706f2543Smrg { { deliver, noop }, synth_2_down_13 }, /* <> */ 1576706f2543Smrg { { deliver, noop }, synth_2_down_13 }, /* <-> */ 1577706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* k */ 1578706f2543Smrg { { noop, noop }, synth_2_down_13 }, /* ... */ 1579706f2543Smrg }, 1580706f2543Smrg /* synthetic_2_down_3 */ 1581706f2543Smrg { 1582706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* v1 */ 1583706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* ^1 */ 1584706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* v2 */ 1585706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* ^2 */ 1586706f2543Smrg { { noop, noop }, synth_2_down_3 }, /* v3 */ 1587706f2543Smrg { { noop, noop }, start }, /* ^3 */ 1588706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* vo */ 1589706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* ^o */ 1590706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* <> */ 1591706f2543Smrg { { deliver, noop }, synth_2_down_3 }, /* <-> */ 1592706f2543Smrg { { noop, noop }, synth_2_down_3 }, /* k */ 1593706f2543Smrg { { noop, noop }, synth_2_down_3 }, /* ... */ 1594706f2543Smrg }, 1595706f2543Smrg /* synthetic_2_down_1 */ 1596706f2543Smrg { 1597706f2543Smrg { { noop, noop }, synth_2_down_1 }, /* v1 */ 1598706f2543Smrg { { noop, noop }, start }, /* ^1 */ 1599706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* v2 */ 1600706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* ^2 */ 1601706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* v3 */ 1602706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* ^3 */ 1603706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* vo */ 1604706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* ^o */ 1605706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* <> */ 1606706f2543Smrg { { deliver, noop }, synth_2_down_1 }, /* <-> */ 1607706f2543Smrg { { noop, noop }, synth_2_down_1 }, /* k */ 1608706f2543Smrg { { noop, noop }, synth_2_down_1 }, /* ... */ 1609706f2543Smrg }, 1610706f2543Smrg}; 1611706f2543Smrg 1612706f2543Smrg#define EMULATION_WINDOW 10 1613706f2543Smrg#define EMULATION_TIMEOUT 100 1614706f2543Smrg 1615706f2543Smrgstatic int 1616706f2543SmrgKdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) 1617706f2543Smrg{ 1618706f2543Smrg pi->emulationDx = pi->heldEvent.x - x; 1619706f2543Smrg pi->emulationDy = pi->heldEvent.y - y; 1620706f2543Smrg 1621706f2543Smrg return (abs (pi->emulationDx) < EMULATION_WINDOW && 1622706f2543Smrg abs (pi->emulationDy) < EMULATION_WINDOW); 1623706f2543Smrg} 1624706f2543Smrg 1625706f2543Smrgstatic KdInputClass 1626706f2543SmrgKdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) 1627706f2543Smrg{ 1628706f2543Smrg switch (type) { 1629706f2543Smrg case ButtonPress: 1630706f2543Smrg switch (b) { 1631706f2543Smrg case 1: return down_1; 1632706f2543Smrg case 2: return down_2; 1633706f2543Smrg case 3: return down_3; 1634706f2543Smrg default: return down_o; 1635706f2543Smrg } 1636706f2543Smrg break; 1637706f2543Smrg case ButtonRelease: 1638706f2543Smrg switch (b) { 1639706f2543Smrg case 1: return up_1; 1640706f2543Smrg case 2: return up_2; 1641706f2543Smrg case 3: return up_3; 1642706f2543Smrg default: return up_o; 1643706f2543Smrg } 1644706f2543Smrg break; 1645706f2543Smrg case MotionNotify: 1646706f2543Smrg if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) 1647706f2543Smrg return outside_box; 1648706f2543Smrg else 1649706f2543Smrg return motion; 1650706f2543Smrg default: 1651706f2543Smrg return keyboard; 1652706f2543Smrg } 1653706f2543Smrg return keyboard; 1654706f2543Smrg} 1655706f2543Smrg 1656706f2543Smrg#ifdef DEBUG 1657706f2543Smrgchar *kdStateNames[] = { 1658706f2543Smrg "start", 1659706f2543Smrg "button_1_pend", 1660706f2543Smrg "button_1_down", 1661706f2543Smrg "button_2_down", 1662706f2543Smrg "button_3_pend", 1663706f2543Smrg "button_3_down", 1664706f2543Smrg "synth_2_down_13", 1665706f2543Smrg "synth_2_down_3", 1666706f2543Smrg "synthetic_2_down_1", 1667706f2543Smrg "num_input_states" 1668706f2543Smrg}; 1669706f2543Smrg 1670706f2543Smrgchar *kdClassNames[] = { 1671706f2543Smrg "down_1", "up_1", 1672706f2543Smrg "down_2", "up_2", 1673706f2543Smrg "down_3", "up_3", 1674706f2543Smrg "motion", "ouside_box", 1675706f2543Smrg "keyboard", "timeout", 1676706f2543Smrg "num_input_class" 1677706f2543Smrg}; 1678706f2543Smrg 1679706f2543Smrgchar *kdActionNames[] = { 1680706f2543Smrg "noop", 1681706f2543Smrg "hold", 1682706f2543Smrg "setto", 1683706f2543Smrg "deliver", 1684706f2543Smrg "release", 1685706f2543Smrg "clearto", 1686706f2543Smrg "gen_down_2", 1687706f2543Smrg "gen_up_2", 1688706f2543Smrg}; 1689706f2543Smrg#endif /* DEBUG */ 1690706f2543Smrg 1691706f2543Smrgstatic void 1692706f2543SmrgKdQueueEvent (DeviceIntPtr pDev, InternalEvent *ev) 1693706f2543Smrg{ 1694706f2543Smrg KdAssertSigioBlocked ("KdQueueEvent"); 1695706f2543Smrg mieqEnqueue (pDev, ev); 1696706f2543Smrg} 1697706f2543Smrg 1698706f2543Smrg/* We return true if we're stealing the event. */ 1699706f2543Smrgstatic Bool 1700706f2543SmrgKdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, 1701706f2543Smrg int z, int b, int absrel) 1702706f2543Smrg{ 1703706f2543Smrg const KdInputTransition *t; 1704706f2543Smrg int a; 1705706f2543Smrg 1706706f2543Smrg c = KdClassifyInput(pi, type, x, y, z, b); 1707706f2543Smrg t = &kdInputMachine[pi->mouseState][c]; 1708706f2543Smrg for (a = 0; a < MAX_ACTIONS; a++) 1709706f2543Smrg { 1710706f2543Smrg switch (t->actions[a]) { 1711706f2543Smrg case noop: 1712706f2543Smrg break; 1713706f2543Smrg case hold: 1714706f2543Smrg pi->eventHeld = TRUE; 1715706f2543Smrg pi->emulationDx = 0; 1716706f2543Smrg pi->emulationDy = 0; 1717706f2543Smrg pi->heldEvent.type = type; 1718706f2543Smrg pi->heldEvent.x = x; 1719706f2543Smrg pi->heldEvent.y = y; 1720706f2543Smrg pi->heldEvent.z = z; 1721706f2543Smrg pi->heldEvent.flags = b; 1722706f2543Smrg pi->heldEvent.absrel = absrel; 1723706f2543Smrg return TRUE; 1724706f2543Smrg break; 1725706f2543Smrg case setto: 1726706f2543Smrg pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; 1727706f2543Smrg pi->timeoutPending = TRUE; 1728706f2543Smrg break; 1729706f2543Smrg case deliver: 1730706f2543Smrg _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, 1731706f2543Smrg pi->heldEvent.y, pi->heldEvent.z, 1732706f2543Smrg pi->heldEvent.flags, pi->heldEvent.absrel, 1733706f2543Smrg TRUE); 1734706f2543Smrg break; 1735706f2543Smrg case release: 1736706f2543Smrg pi->eventHeld = FALSE; 1737706f2543Smrg pi->timeoutPending = FALSE; 1738706f2543Smrg _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, 1739706f2543Smrg pi->heldEvent.y, pi->heldEvent.z, 1740706f2543Smrg pi->heldEvent.flags, pi->heldEvent.absrel, 1741706f2543Smrg TRUE); 1742706f2543Smrg return TRUE; 1743706f2543Smrg break; 1744706f2543Smrg case clearto: 1745706f2543Smrg pi->timeoutPending = FALSE; 1746706f2543Smrg break; 1747706f2543Smrg case gen_down_2: 1748706f2543Smrg _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, 1749706f2543Smrg TRUE); 1750706f2543Smrg pi->eventHeld = FALSE; 1751706f2543Smrg return TRUE; 1752706f2543Smrg break; 1753706f2543Smrg case gen_up_2: 1754706f2543Smrg _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, 1755706f2543Smrg TRUE); 1756706f2543Smrg return TRUE; 1757706f2543Smrg break; 1758706f2543Smrg } 1759706f2543Smrg } 1760706f2543Smrg pi->mouseState = t->nextState; 1761706f2543Smrg return FALSE; 1762706f2543Smrg} 1763706f2543Smrg 1764706f2543Smrgstatic int 1765706f2543SmrgKdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, 1766706f2543Smrg int absrel) 1767706f2543Smrg{ 1768706f2543Smrg if (pi->emulateMiddleButton) 1769706f2543Smrg return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), 1770706f2543Smrg type, x, y, z, b, absrel); 1771706f2543Smrg return FALSE; 1772706f2543Smrg} 1773706f2543Smrg 1774706f2543Smrgstatic void 1775706f2543SmrgKdReceiveTimeout (KdPointerInfo *pi) 1776706f2543Smrg{ 1777706f2543Smrg KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); 1778706f2543Smrg} 1779706f2543Smrg 1780706f2543Smrg/* 1781706f2543Smrg * kdCheckTermination 1782706f2543Smrg * 1783706f2543Smrg * This function checks for the key sequence that terminates the server. When 1784706f2543Smrg * detected, it sets the dispatchException flag and returns. The key sequence 1785706f2543Smrg * is: 1786706f2543Smrg * Control-Alt 1787706f2543Smrg * It's assumed that the server will be waken up by the caller when this 1788706f2543Smrg * function returns. 1789706f2543Smrg */ 1790706f2543Smrg 1791706f2543Smrgextern int nClients; 1792706f2543Smrg 1793706f2543Smrgvoid 1794706f2543SmrgKdReleaseAllKeys (void) 1795706f2543Smrg{ 1796706f2543Smrg#if 0 1797706f2543Smrg int key, nEvents, i; 1798706f2543Smrg KdKeyboardInfo *ki; 1799706f2543Smrg 1800706f2543Smrg KdBlockSigio (); 1801706f2543Smrg 1802706f2543Smrg for (ki = kdKeyboards; ki; ki = ki->next) { 1803706f2543Smrg for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; 1804706f2543Smrg key++) { 1805706f2543Smrg if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { 1806706f2543Smrg KdHandleKeyboardEvent(ki, KeyRelease, key); 1807706f2543Smrg GetEventList(&kdEvents); 1808706f2543Smrg nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); 1809706f2543Smrg for (i = 0; i < nEvents; i++) 1810706f2543Smrg KdQueueEvent (ki->dixdev, (kdEvents + i)->event); 1811706f2543Smrg } 1812706f2543Smrg } 1813706f2543Smrg } 1814706f2543Smrg 1815706f2543Smrg KdUnblockSigio (); 1816706f2543Smrg#endif 1817706f2543Smrg} 1818706f2543Smrg 1819706f2543Smrgstatic void 1820706f2543SmrgKdCheckLock (void) 1821706f2543Smrg{ 1822706f2543Smrg KeyClassPtr keyc = NULL; 1823706f2543Smrg Bool isSet = FALSE, shouldBeSet = FALSE; 1824706f2543Smrg KdKeyboardInfo *tmp = NULL; 1825706f2543Smrg 1826706f2543Smrg for (tmp = kdKeyboards; tmp; tmp = tmp->next) { 1827706f2543Smrg if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { 1828706f2543Smrg keyc = tmp->dixdev->key; 1829706f2543Smrg isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; 1830706f2543Smrg /* FIXME: Just use XKB indicators! */ 1831706f2543Smrg shouldBeSet = !!(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask); 1832706f2543Smrg if (isSet != shouldBeSet) 1833706f2543Smrg KdSetLed (tmp, tmp->LockLed, shouldBeSet); 1834706f2543Smrg } 1835706f2543Smrg } 1836706f2543Smrg} 1837706f2543Smrg 1838706f2543Smrgvoid 1839706f2543SmrgKdEnqueueKeyboardEvent(KdKeyboardInfo *ki, 1840706f2543Smrg unsigned char scan_code, 1841706f2543Smrg unsigned char is_up) 1842706f2543Smrg{ 1843706f2543Smrg unsigned char key_code; 1844706f2543Smrg KeyClassPtr keyc = NULL; 1845706f2543Smrg KeybdCtrl *ctrl = NULL; 1846706f2543Smrg int type, nEvents, i; 1847706f2543Smrg 1848706f2543Smrg if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) 1849706f2543Smrg return; 1850706f2543Smrg 1851706f2543Smrg keyc = ki->dixdev->key; 1852706f2543Smrg ctrl = &ki->dixdev->kbdfeed->ctrl; 1853706f2543Smrg 1854706f2543Smrg if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) 1855706f2543Smrg { 1856706f2543Smrg key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; 1857706f2543Smrg 1858706f2543Smrg /* 1859706f2543Smrg * Set up this event -- the type may be modified below 1860706f2543Smrg */ 1861706f2543Smrg if (is_up) 1862706f2543Smrg type = KeyRelease; 1863706f2543Smrg else 1864706f2543Smrg type = KeyPress; 1865706f2543Smrg 1866706f2543Smrg GetEventList(&kdEvents); 1867706f2543Smrg 1868706f2543Smrg nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); 1869706f2543Smrg for (i = 0; i < nEvents; i++) 1870706f2543Smrg KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event)); 1871706f2543Smrg } 1872706f2543Smrg else { 1873706f2543Smrg ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", 1874706f2543Smrg ki->name, scan_code, ki->minScanCode, ki->maxScanCode); 1875706f2543Smrg } 1876706f2543Smrg} 1877706f2543Smrg 1878706f2543Smrg/* 1879706f2543Smrg * kdEnqueuePointerEvent 1880706f2543Smrg * 1881706f2543Smrg * This function converts hardware mouse event information into X event 1882706f2543Smrg * information. A mouse movement event is passed off to MI to generate 1883706f2543Smrg * a MotionNotify event, if appropriate. Button events are created and 1884706f2543Smrg * passed off to MI for enqueueing. 1885706f2543Smrg */ 1886706f2543Smrg 1887706f2543Smrg/* FIXME do something a little more clever to deal with multiple axes here */ 1888706f2543Smrgvoid 1889706f2543SmrgKdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, 1890706f2543Smrg int rz) 1891706f2543Smrg{ 1892706f2543Smrg CARD32 ms; 1893706f2543Smrg unsigned char buttons; 1894706f2543Smrg int x, y, z; 1895706f2543Smrg int (*matrix)[3] = kdPointerMatrix.matrix; 1896706f2543Smrg unsigned long button; 1897706f2543Smrg int n; 1898706f2543Smrg int dixflags = 0; 1899706f2543Smrg 1900706f2543Smrg if (!pi) 1901706f2543Smrg return; 1902706f2543Smrg 1903706f2543Smrg ms = GetTimeInMillis(); 1904706f2543Smrg 1905706f2543Smrg /* we don't need to transform z, so we don't. */ 1906706f2543Smrg if (flags & KD_MOUSE_DELTA) { 1907706f2543Smrg if (pi->transformCoordinates) { 1908706f2543Smrg x = matrix[0][0] * rx + matrix[0][1] * ry; 1909706f2543Smrg y = matrix[1][0] * rx + matrix[1][1] * ry; 1910706f2543Smrg } 1911706f2543Smrg else { 1912706f2543Smrg x = rx; 1913706f2543Smrg y = ry; 1914706f2543Smrg } 1915706f2543Smrg } 1916706f2543Smrg else { 1917706f2543Smrg if (pi->transformCoordinates) { 1918706f2543Smrg x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2]; 1919706f2543Smrg y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2]; 1920706f2543Smrg } 1921706f2543Smrg else { 1922706f2543Smrg x = rx; 1923706f2543Smrg y = ry; 1924706f2543Smrg } 1925706f2543Smrg } 1926706f2543Smrg z = rz; 1927706f2543Smrg 1928706f2543Smrg if (flags & KD_MOUSE_DELTA) 1929706f2543Smrg { 1930706f2543Smrg if (x || y || z) 1931706f2543Smrg { 1932706f2543Smrg dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; 1933706f2543Smrg _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); 1934706f2543Smrg } 1935706f2543Smrg } else 1936706f2543Smrg { 1937706f2543Smrg dixflags = POINTER_ABSOLUTE; 1938706f2543Smrg if (x != pi->dixdev->last.valuators[0] || 1939706f2543Smrg y != pi->dixdev->last.valuators[1]) 1940706f2543Smrg _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); 1941706f2543Smrg } 1942706f2543Smrg 1943706f2543Smrg buttons = flags; 1944706f2543Smrg 1945706f2543Smrg for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 1946706f2543Smrg button <<= 1, n++) { 1947706f2543Smrg if (((pi->buttonState & button) ^ (buttons & button)) && 1948706f2543Smrg !(buttons & button)) { 1949706f2543Smrg _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, 1950706f2543Smrg dixflags, FALSE); 1951706f2543Smrg } 1952706f2543Smrg } 1953706f2543Smrg for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 1954706f2543Smrg button <<= 1, n++) { 1955706f2543Smrg if (((pi->buttonState & button) ^ (buttons & button)) && 1956706f2543Smrg (buttons & button)) { 1957706f2543Smrg _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, 1958706f2543Smrg dixflags, FALSE); 1959706f2543Smrg } 1960706f2543Smrg } 1961706f2543Smrg 1962706f2543Smrg pi->buttonState = buttons; 1963706f2543Smrg} 1964706f2543Smrg 1965706f2543Smrgvoid 1966706f2543Smrg_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, 1967706f2543Smrg int b, int absrel, Bool force) 1968706f2543Smrg{ 1969706f2543Smrg int nEvents = 0, i = 0; 1970706f2543Smrg int valuators[3] = { x, y, z }; 1971706f2543Smrg ValuatorMask mask; 1972706f2543Smrg 1973706f2543Smrg /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ 1974706f2543Smrg if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) 1975706f2543Smrg return; 1976706f2543Smrg 1977706f2543Smrg valuator_mask_set_range(&mask, 0, 3, valuators); 1978706f2543Smrg 1979706f2543Smrg GetEventList(&kdEvents); 1980706f2543Smrg nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask); 1981706f2543Smrg for (i = 0; i < nEvents; i++) 1982706f2543Smrg KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event)); 1983706f2543Smrg} 1984706f2543Smrg 1985706f2543Smrgvoid 1986706f2543SmrgKdBlockHandler (int screen, 1987706f2543Smrg pointer blockData, 1988706f2543Smrg pointer timeout, 1989706f2543Smrg pointer readmask) 1990706f2543Smrg{ 1991706f2543Smrg KdPointerInfo *pi; 1992706f2543Smrg int myTimeout=0; 1993706f2543Smrg 1994706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) 1995706f2543Smrg { 1996706f2543Smrg if (pi->timeoutPending) 1997706f2543Smrg { 1998706f2543Smrg int ms; 1999706f2543Smrg 2000706f2543Smrg ms = pi->emulationTimeout - GetTimeInMillis (); 2001706f2543Smrg if (ms < 1) 2002706f2543Smrg ms = 1; 2003706f2543Smrg if(ms<myTimeout || myTimeout==0) 2004706f2543Smrg myTimeout=ms; 2005706f2543Smrg } 2006706f2543Smrg } 2007706f2543Smrg /* if we need to poll for events, do that */ 2008706f2543Smrg if(kdOsFuncs->pollEvents) 2009706f2543Smrg { 2010706f2543Smrg (*kdOsFuncs->pollEvents)(); 2011706f2543Smrg myTimeout=20; 2012706f2543Smrg } 2013706f2543Smrg if(myTimeout>0) 2014706f2543Smrg AdjustWaitForDelay (timeout, myTimeout); 2015706f2543Smrg} 2016706f2543Smrg 2017706f2543Smrgvoid 2018706f2543SmrgKdWakeupHandler (int screen, 2019706f2543Smrg pointer data, 2020706f2543Smrg unsigned long lresult, 2021706f2543Smrg pointer readmask) 2022706f2543Smrg{ 2023706f2543Smrg int result = (int) lresult; 2024706f2543Smrg fd_set *pReadmask = (fd_set *) readmask; 2025706f2543Smrg int i; 2026706f2543Smrg KdPointerInfo *pi; 2027706f2543Smrg 2028706f2543Smrg if (kdInputEnabled && result > 0) 2029706f2543Smrg { 2030706f2543Smrg for (i = 0; i < kdNumInputFds; i++) 2031706f2543Smrg if (FD_ISSET (kdInputFds[i].fd, pReadmask)) 2032706f2543Smrg { 2033706f2543Smrg KdBlockSigio (); 2034706f2543Smrg (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); 2035706f2543Smrg KdUnblockSigio (); 2036706f2543Smrg } 2037706f2543Smrg } 2038706f2543Smrg for (pi = kdPointers; pi; pi = pi->next) 2039706f2543Smrg { 2040706f2543Smrg if (pi->timeoutPending) 2041706f2543Smrg { 2042706f2543Smrg if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) 2043706f2543Smrg { 2044706f2543Smrg pi->timeoutPending = FALSE; 2045706f2543Smrg KdBlockSigio (); 2046706f2543Smrg KdReceiveTimeout (pi); 2047706f2543Smrg KdUnblockSigio (); 2048706f2543Smrg } 2049706f2543Smrg } 2050706f2543Smrg } 2051706f2543Smrg if (kdSwitchPending) 2052706f2543Smrg KdProcessSwitch (); 2053706f2543Smrg} 2054706f2543Smrg 2055706f2543Smrg#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) 2056706f2543Smrg 2057706f2543Smrgstatic Bool 2058706f2543SmrgKdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 2059706f2543Smrg{ 2060706f2543Smrg ScreenPtr pScreen = *ppScreen; 2061706f2543Smrg ScreenPtr pNewScreen; 2062706f2543Smrg int n; 2063706f2543Smrg int dx, dy; 2064706f2543Smrg int best_x, best_y; 2065706f2543Smrg int n_best_x, n_best_y; 2066706f2543Smrg CARD32 ms; 2067706f2543Smrg 2068706f2543Smrg if (kdDisableZaphod || screenInfo.numScreens <= 1) 2069706f2543Smrg return FALSE; 2070706f2543Smrg 2071706f2543Smrg if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) 2072706f2543Smrg return FALSE; 2073706f2543Smrg 2074706f2543Smrg ms = GetTimeInMillis (); 2075706f2543Smrg if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) 2076706f2543Smrg return FALSE; 2077706f2543Smrg kdOffScreen = TRUE; 2078706f2543Smrg kdOffScreenTime = ms; 2079706f2543Smrg n_best_x = -1; 2080706f2543Smrg best_x = 32767; 2081706f2543Smrg n_best_y = -1; 2082706f2543Smrg best_y = 32767; 2083706f2543Smrg for (n = 0; n < screenInfo.numScreens; n++) 2084706f2543Smrg { 2085706f2543Smrg pNewScreen = screenInfo.screens[n]; 2086706f2543Smrg if (pNewScreen == pScreen) 2087706f2543Smrg continue; 2088706f2543Smrg dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; 2089706f2543Smrg dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; 2090706f2543Smrg if (*x < 0) 2091706f2543Smrg { 2092706f2543Smrg if (dx <= 0 && -dx < best_x) 2093706f2543Smrg { 2094706f2543Smrg best_x = -dx; 2095706f2543Smrg n_best_x = n; 2096706f2543Smrg } 2097706f2543Smrg } 2098706f2543Smrg else if (*x >= pScreen->width) 2099706f2543Smrg { 2100706f2543Smrg if (dx >= 0 && dx < best_x) 2101706f2543Smrg { 2102706f2543Smrg best_x = dx; 2103706f2543Smrg n_best_x = n; 2104706f2543Smrg } 2105706f2543Smrg } 2106706f2543Smrg if (*y < 0) 2107706f2543Smrg { 2108706f2543Smrg if (dy <= 0 && -dy < best_y) 2109706f2543Smrg { 2110706f2543Smrg best_y = -dy; 2111706f2543Smrg n_best_y = n; 2112706f2543Smrg } 2113706f2543Smrg } 2114706f2543Smrg else if (*y >= pScreen->height) 2115706f2543Smrg { 2116706f2543Smrg if (dy >= 0 && dy < best_y) 2117706f2543Smrg { 2118706f2543Smrg best_y = dy; 2119706f2543Smrg n_best_y = n; 2120706f2543Smrg } 2121706f2543Smrg } 2122706f2543Smrg } 2123706f2543Smrg if (best_y < best_x) 2124706f2543Smrg n_best_x = n_best_y; 2125706f2543Smrg if (n_best_x == -1) 2126706f2543Smrg return FALSE; 2127706f2543Smrg pNewScreen = screenInfo.screens[n_best_x]; 2128706f2543Smrg 2129706f2543Smrg if (*x < 0) 2130706f2543Smrg *x += pNewScreen->width; 2131706f2543Smrg if (*y < 0) 2132706f2543Smrg *y += pNewScreen->height; 2133706f2543Smrg 2134706f2543Smrg if (*x >= pScreen->width) 2135706f2543Smrg *x -= pScreen->width; 2136706f2543Smrg if (*y >= pScreen->height) 2137706f2543Smrg *y -= pScreen->height; 2138706f2543Smrg 2139706f2543Smrg *ppScreen = pNewScreen; 2140706f2543Smrg return TRUE; 2141706f2543Smrg} 2142706f2543Smrg 2143706f2543Smrgstatic void 2144706f2543SmrgKdCrossScreen(ScreenPtr pScreen, Bool entering) 2145706f2543Smrg{ 2146706f2543Smrg} 2147706f2543Smrg 2148706f2543Smrgint KdCurScreen; /* current event screen */ 2149706f2543Smrg 2150706f2543Smrgstatic void 2151706f2543SmrgKdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 2152706f2543Smrg{ 2153706f2543Smrg KdBlockSigio (); 2154706f2543Smrg KdCurScreen = pScreen->myNum; 2155706f2543Smrg miPointerWarpCursor(pDev, pScreen, x, y); 2156706f2543Smrg KdUnblockSigio (); 2157706f2543Smrg} 2158706f2543Smrg 2159706f2543SmrgmiPointerScreenFuncRec kdPointerScreenFuncs = 2160706f2543Smrg{ 2161706f2543Smrg KdCursorOffScreen, 2162706f2543Smrg KdCrossScreen, 2163706f2543Smrg KdWarpCursor 2164706f2543Smrg}; 2165706f2543Smrg 2166706f2543Smrgvoid 2167706f2543SmrgProcessInputEvents (void) 2168706f2543Smrg{ 2169706f2543Smrg mieqProcessInputEvents(); 2170706f2543Smrg miPointerUpdateSprite(inputInfo.pointer); 2171706f2543Smrg if (kdSwitchPending) 2172706f2543Smrg KdProcessSwitch (); 2173706f2543Smrg KdCheckLock (); 2174706f2543Smrg} 2175706f2543Smrg 2176706f2543Smrg/* At the moment, absolute/relative is up to the client. */ 2177706f2543Smrgint 2178706f2543SmrgSetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) 2179706f2543Smrg{ 2180706f2543Smrg return BadMatch; 2181706f2543Smrg} 2182706f2543Smrg 2183706f2543Smrgint 2184706f2543SmrgSetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, 2185706f2543Smrg int *valuators, int first_valuator, int num_valuators) 2186706f2543Smrg{ 2187706f2543Smrg return BadMatch; 2188706f2543Smrg} 2189706f2543Smrg 2190706f2543Smrgint 2191706f2543SmrgChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, 2192706f2543Smrg xDeviceCtl *control) 2193706f2543Smrg{ 2194706f2543Smrg switch (control->control) { 2195706f2543Smrg case DEVICE_RESOLUTION: 2196706f2543Smrg /* FIXME do something more intelligent here */ 2197706f2543Smrg return BadMatch; 2198706f2543Smrg 2199706f2543Smrg case DEVICE_ABS_CALIB: 2200706f2543Smrg case DEVICE_ABS_AREA: 2201706f2543Smrg return Success; 2202706f2543Smrg 2203706f2543Smrg case DEVICE_CORE: 2204706f2543Smrg return BadMatch; 2205706f2543Smrg case DEVICE_ENABLE: 2206706f2543Smrg return Success; 2207706f2543Smrg 2208706f2543Smrg default: 2209706f2543Smrg return BadMatch; 2210706f2543Smrg } 2211706f2543Smrg 2212706f2543Smrg /* NOTREACHED */ 2213706f2543Smrg return BadImplementation; 2214706f2543Smrg} 2215706f2543Smrg 2216706f2543Smrgint 2217706f2543SmrgNewInputDeviceRequest(InputOption *options, InputAttributes *attrs, 2218706f2543Smrg DeviceIntPtr *pdev) 2219706f2543Smrg{ 2220706f2543Smrg InputOption *option = NULL; 2221706f2543Smrg KdPointerInfo *pi = NULL; 2222706f2543Smrg KdKeyboardInfo *ki = NULL; 2223706f2543Smrg 2224706f2543Smrg for (option = options; option; option = option->next) { 2225706f2543Smrg if (strcmp(option->key, "type") == 0) { 2226706f2543Smrg if (strcmp(option->value, "pointer") == 0) { 2227706f2543Smrg pi = KdNewPointer(); 2228706f2543Smrg if (!pi) 2229706f2543Smrg return BadAlloc; 2230706f2543Smrg } 2231706f2543Smrg else if (strcmp(option->value, "keyboard") == 0) { 2232706f2543Smrg ki = KdNewKeyboard(); 2233706f2543Smrg if (!ki) 2234706f2543Smrg return BadAlloc; 2235706f2543Smrg } 2236706f2543Smrg else { 2237706f2543Smrg ErrorF("unrecognised device type!\n"); 2238706f2543Smrg return BadValue; 2239706f2543Smrg } 2240706f2543Smrg } 2241706f2543Smrg#ifdef CONFIG_HAL 2242706f2543Smrg else if (strcmp(option->key, "_source") == 0 && 2243706f2543Smrg strcmp(option->value, "server/hal") == 0) 2244706f2543Smrg { 2245706f2543Smrg ErrorF("Ignoring device from HAL.\n"); 2246706f2543Smrg return BadValue; 2247706f2543Smrg } 2248706f2543Smrg#endif 2249706f2543Smrg#ifdef CONFIG_UDEV 2250706f2543Smrg else if (strcmp(option->key, "_source") == 0 && 2251706f2543Smrg strcmp(option->value, "server/udev") == 0) 2252706f2543Smrg { 2253706f2543Smrg ErrorF("Ignoring device from udev.\n"); 2254706f2543Smrg return BadValue; 2255706f2543Smrg } 2256706f2543Smrg#endif 2257706f2543Smrg } 2258706f2543Smrg 2259706f2543Smrg if (!ki && !pi) { 2260706f2543Smrg ErrorF("unrecognised device identifier!\n"); 2261706f2543Smrg return BadValue; 2262706f2543Smrg } 2263706f2543Smrg 2264706f2543Smrg /* FIXME: change this code below to use KdParseKbdOptions and 2265706f2543Smrg * KdParsePointerOptions */ 2266706f2543Smrg for (option = options; option; option = option->next) { 2267706f2543Smrg if (strcmp(option->key, "device") == 0) { 2268706f2543Smrg if (pi && option->value) 2269706f2543Smrg pi->path = strdup(option->value); 2270706f2543Smrg else if (ki && option->value) 2271706f2543Smrg ki->path = strdup(option->value); 2272706f2543Smrg } 2273706f2543Smrg else if (strcmp(option->key, "driver") == 0) { 2274706f2543Smrg if (pi) { 2275706f2543Smrg pi->driver = KdFindPointerDriver(option->value); 2276706f2543Smrg if (!pi->driver) { 2277706f2543Smrg ErrorF("couldn't find driver!\n"); 2278706f2543Smrg KdFreePointer(pi); 2279706f2543Smrg return BadValue; 2280706f2543Smrg } 2281706f2543Smrg pi->options = options; 2282706f2543Smrg } 2283706f2543Smrg else if (ki) { 2284706f2543Smrg ki->driver = KdFindKeyboardDriver(option->value); 2285706f2543Smrg if (!ki->driver) { 2286706f2543Smrg ErrorF("couldn't find driver!\n"); 2287706f2543Smrg KdFreeKeyboard(ki); 2288706f2543Smrg return BadValue; 2289706f2543Smrg } 2290706f2543Smrg ki->options = options; 2291706f2543Smrg } 2292706f2543Smrg } 2293706f2543Smrg } 2294706f2543Smrg 2295706f2543Smrg if (pi) { 2296706f2543Smrg if (KdAddPointer(pi) != Success || 2297706f2543Smrg ActivateDevice(pi->dixdev, TRUE) != Success || 2298706f2543Smrg EnableDevice(pi->dixdev, TRUE) != TRUE) { 2299706f2543Smrg ErrorF("couldn't add or enable pointer\n"); 2300706f2543Smrg return BadImplementation; 2301706f2543Smrg } 2302706f2543Smrg } 2303706f2543Smrg else if (ki) { 2304706f2543Smrg if (KdAddKeyboard(ki) != Success || 2305706f2543Smrg ActivateDevice(ki->dixdev, TRUE) != Success || 2306706f2543Smrg EnableDevice(ki->dixdev, TRUE) != TRUE) { 2307706f2543Smrg ErrorF("couldn't add or enable keyboard\n"); 2308706f2543Smrg return BadImplementation; 2309706f2543Smrg } 2310706f2543Smrg } 2311706f2543Smrg 2312706f2543Smrg if (pi) { 2313706f2543Smrg *pdev = pi->dixdev; 2314706f2543Smrg } else if(ki) { 2315706f2543Smrg *pdev = ki->dixdev; 2316706f2543Smrg } 2317706f2543Smrg 2318706f2543Smrg return Success; 2319706f2543Smrg} 2320706f2543Smrg 2321706f2543Smrgvoid 2322706f2543SmrgDeleteInputDeviceRequest(DeviceIntPtr pDev) 2323706f2543Smrg{ 2324706f2543Smrg RemoveDevice(pDev, TRUE); 2325706f2543Smrg} 2326