xf86Xinput.c revision 05b261ec
1/*
2 * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is  hereby granted without fee, provided that
6 * the  above copyright   notice appear  in   all  copies and  that both  that
7 * copyright  notice   and   this  permission   notice  appear  in  supporting
8 * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific,  written      prior  permission.     Frederic  Lepied   makes  no
11 * representations about the suitability of this software for any purpose.  It
12 * is provided "as is" without express or implied warranty.
13 *
14 * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
16 * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
19 * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23/*
24 * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a
27 * copy of this software and associated documentation files (the "Software"),
28 * to deal in the Software without restriction, including without limitation
29 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
30 * and/or sell copies of the Software, and to permit persons to whom the
31 * Software is furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
40 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41 * OTHER DEALINGS IN THE SOFTWARE.
42 *
43 * Except as contained in this notice, the name of the copyright holder(s)
44 * and author(s) shall not be used in advertising or otherwise to promote
45 * the sale, use or other dealings in this Software without prior written
46 * authorization from the copyright holder(s) and author(s).
47 */
48
49#ifdef HAVE_XORG_CONFIG_H
50#include <xorg-config.h>
51#endif
52
53#include <X11/Xfuncproto.h>
54#include <X11/Xmd.h>
55#ifdef XINPUT
56#include <X11/extensions/XI.h>
57#include <X11/extensions/XIproto.h>
58#endif
59#include "xf86.h"
60#include "xf86Priv.h"
61#include "xf86Xinput.h"
62#ifdef XINPUT
63#include "XIstubs.h"
64#include "xf86Optrec.h"
65#endif
66#include "mipointer.h"
67#include "xf86InPriv.h"
68
69#ifdef DPMSExtension
70#define DPMS_SERVER
71#include <X11/extensions/dpms.h>
72#include "dpmsproc.h"
73#endif
74
75#include "exevents.h"	/* AddInputDevice */
76#include "exglobals.h"
77
78#define EXTENSION_PROC_ARGS void *
79#include "extnsionst.h"
80#include "extinit.h"	/* LookupDeviceIntRec */
81
82#include "windowstr.h"	/* screenIsSaved */
83
84#include <stdarg.h>
85
86#include <X11/Xpoll.h>
87
88#include "mi.h"
89
90#ifdef XFreeXDGA
91#include "dgaproc.h"
92#endif
93
94xEvent *xf86Events = NULL;
95
96static Bool
97xf86SendDragEvents(DeviceIntPtr	device)
98{
99    LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
100
101    if (device->button && device->button->buttonsDown > 0)
102        return (local->flags & XI86_SEND_DRAG_EVENTS);
103    else
104        return (TRUE);
105}
106
107/***********************************************************************
108 *
109 * xf86ProcessCommonOptions --
110 *
111 *	Process global options.
112 *
113 ***********************************************************************
114 */
115_X_EXPORT void
116xf86ProcessCommonOptions(LocalDevicePtr local,
117                         pointer	list)
118{
119    if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
120        !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
121        !xf86SetBoolOption(list, "CorePointer", 1) ||
122        !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
123        xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
124    } else {
125        local->flags |= XI86_ALWAYS_CORE;
126        xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
127    }
128
129    if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
130        local->flags |= XI86_SEND_DRAG_EVENTS;
131    } else {
132        xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
133    }
134
135    /* Backwards compatibility. */
136    local->history_size = GetMotionHistorySize();
137}
138
139/***********************************************************************
140 *
141 * xf86ActivateDevice --
142 *
143 *	Initialize an input device.
144 *
145 ***********************************************************************
146 */
147_X_EXPORT void
148xf86ActivateDevice(LocalDevicePtr local)
149{
150    DeviceIntPtr	dev;
151
152    if (local->flags & XI86_CONFIGURED) {
153        dev = AddInputDevice(local->device_control, TRUE);
154
155        if (dev == NULL)
156            FatalError("Too many input devices");
157
158        local->atom = MakeAtom(local->type_name,
159                               strlen(local->type_name),
160                               TRUE);
161        AssignTypeAndName(dev, local->atom, local->name);
162        dev->public.devicePrivate = (pointer) local;
163        local->dev = dev;
164
165        dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
166        RegisterOtherDevice(dev);
167
168#ifdef XKB
169        if (!noXkbExtension)
170            XkbSetExtension(dev, ProcessKeyboardEvent);
171#endif
172
173        if (serverGeneration == 1)
174            xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
175                    local->name, local->type_name);
176    }
177}
178
179
180#ifdef XINPUT
181/***********************************************************************
182 *
183 * Caller:	ProcXOpenDevice
184 *
185 * This is the implementation-dependent routine to open an input device.
186 * Some implementations open all input devices when the server is first
187 * initialized, and never close them.  Other implementations open only
188 * the X pointer and keyboard devices during server initialization,
189 * and only open other input devices when some client makes an
190 * XOpenDevice request.  This entry point is for the latter type of
191 * implementation.
192 *
193 * If the physical device is not already open, do it here.  In this case,
194 * you need to keep track of the fact that one or more clients has the
195 * device open, and physically close it when the last client that has
196 * it open does an XCloseDevice.
197 *
198 * The default implementation is to do nothing (assume all input devices
199 * are opened during X server initialization and kept open).
200 *
201 ***********************************************************************
202 */
203
204void
205OpenInputDevice(DeviceIntPtr	dev,
206                ClientPtr	client,
207                int		*status)
208{
209    if (!dev->inited)
210        ActivateDevice(dev);
211
212    *status = Success;
213}
214
215void
216CloseInputDevice(DeviceIntPtr dev,
217                 ClientPtr client)
218{
219}
220
221/****************************************************************************
222 *
223 * Caller:	ProcXSetDeviceMode
224 *
225 * Change the mode of an extension device.
226 * This function is used to change the mode of a device from reporting
227 * relative motion to reporting absolute positional information, and
228 * vice versa.
229 * The default implementation below is that no such devices are supported.
230 *
231 ***********************************************************************
232 */
233
234int
235SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
236{
237  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
238
239  if (local->switch_mode) {
240    return (*local->switch_mode)(client, dev, mode);
241  }
242  else
243    return BadMatch;
244}
245
246
247/***********************************************************************
248 *
249 * Caller:	ProcXSetDeviceValuators
250 *
251 * Set the value of valuators on an extension input device.
252 * This function is used to set the initial value of valuators on
253 * those input devices that are capable of reporting either relative
254 * motion or an absolute position, and allow an initial position to be set.
255 * The default implementation below is that no such devices are supported.
256 *
257 ***********************************************************************
258 */
259
260int
261SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
262                    int first_valuator, int num_valuators)
263{
264    LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
265
266    if (local->set_device_valuators)
267	return (*local->set_device_valuators)(local, valuators, first_valuator,
268					      num_valuators);
269
270    return BadMatch;
271}
272
273
274/***********************************************************************
275 *
276 * Caller:	ProcXChangeDeviceControl
277 *
278 * Change the specified device controls on an extension input device.
279 *
280 ***********************************************************************
281 */
282
283int
284ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
285{
286  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
287
288  if (!local->control_proc) {
289      switch (control->control) {
290      case DEVICE_CORE:
291      case DEVICE_RESOLUTION:
292      case DEVICE_ABS_CALIB:
293      case DEVICE_ABS_AREA:
294      case DEVICE_ENABLE:
295        return Success;
296      default:
297        return BadMatch;
298      }
299  }
300  else {
301      return (*local->control_proc)(local, control);
302  }
303}
304
305void
306AddOtherInputDevices()
307{
308}
309#endif
310
311int
312NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
313{
314    IDevRec *idev = NULL;
315    InputDriverPtr drv = NULL;
316    InputInfoPtr pInfo = NULL;
317    InputOption *option = NULL;
318    DeviceIntPtr dev = NULL;
319    int rval = Success;
320    int is_auto = 0;
321
322    idev = xcalloc(sizeof(*idev), 1);
323    if (!idev)
324        return BadAlloc;
325
326    for (option = options; option; option = option->next) {
327        if (strcasecmp(option->key, "driver") == 0) {
328            if (idev->driver) {
329                rval = BadRequest;
330                goto unwind;
331            }
332            /* Memory leak for every attached device if we don't
333             * test if the module is already loaded first */
334            drv = xf86LookupInputDriver(option->value);
335            if (!drv)
336                if (xf86LoadOneModule(option->value, NULL))
337                    drv = xf86LookupInputDriver(option->value);
338            if (!drv) {
339                xf86Msg(X_ERROR, "No input driver matching `%s'\n",
340                        option->value);
341                rval = BadName;
342                goto unwind;
343            }
344            idev->driver = xstrdup(option->value);
345            if (!idev->driver) {
346                rval = BadAlloc;
347                goto unwind;
348            }
349        }
350
351        if (strcasecmp(option->key, "name") == 0 ||
352            strcasecmp(option->key, "identifier") == 0) {
353            if (idev->identifier) {
354                rval = BadRequest;
355                goto unwind;
356            }
357            idev->identifier = xstrdup(option->value);
358            if (!idev->identifier) {
359                rval = BadAlloc;
360                goto unwind;
361            }
362        }
363
364        /* Right now, the only automatic config we know of is HAL. */
365        if (strcmp(option->key, "_source") == 0 &&
366            strcmp(option->value, "server/hal") == 0) {
367            if (!xf86Info.autoAddDevices) {
368                rval = BadMatch;
369                goto unwind;
370            }
371
372            is_auto = 1;
373        }
374    }
375    if (!idev->driver || !idev->identifier) {
376        xf86Msg(X_ERROR, "No input driver/identifier specified (ignoring)\n");
377        rval = BadRequest;
378        goto unwind;
379    }
380
381    if (!drv->PreInit) {
382        xf86Msg(X_ERROR,
383                "Input driver `%s' has no PreInit function (ignoring)\n",
384                drv->driverName);
385        rval = BadImplementation;
386        goto unwind;
387    }
388
389    for (option = options; option; option = option->next) {
390        /* Steal option key/value strings from the provided list.
391         * We need those strings, the InputOption list doesn't. */
392        idev->commonOptions = xf86addNewOption(idev->commonOptions,
393                                               option->key, option->value);
394        option->key = NULL;
395        option->value = NULL;
396    }
397
398    pInfo = drv->PreInit(drv, idev, 0);
399
400    if (!pInfo) {
401        xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
402        rval = BadMatch;
403        goto unwind;
404    }
405    else if (!(pInfo->flags & XI86_CONFIGURED)) {
406        xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
407                idev->identifier);
408        rval = BadMatch;
409        goto unwind;
410    }
411
412    xf86ActivateDevice(pInfo);
413
414    dev = pInfo->dev;
415    ActivateDevice(dev);
416    /* Enable it if it's properly initialised, we're currently in the VT, and
417     * either it's a manual request, or we're automatically enabling devices. */
418    if (dev->inited && dev->startup && xf86Screens[0]->vtSema &&
419        (!is_auto || xf86Info.autoEnableDevices))
420        EnableDevice(dev);
421
422    *pdev = dev;
423    return Success;
424
425unwind:
426    if(pInfo) {
427        if(drv->UnInit)
428            drv->UnInit(drv, pInfo, 0);
429        else
430            xf86DeleteInput(pInfo, 0);
431    }
432    if(idev->driver)
433        xfree(idev->driver);
434    if(idev->identifier)
435        xfree(idev->identifier);
436    xf86optionListFree(idev->commonOptions);
437    xfree(idev);
438    return rval;
439}
440
441void
442DeleteInputDeviceRequest(DeviceIntPtr pDev)
443{
444    LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
445    InputDriverPtr drv = pInfo->drv;
446    IDevRec *idev = pInfo->conf_idev;
447
448    RemoveDevice(pDev);
449
450    if(drv->UnInit)
451        drv->UnInit(drv, pInfo, 0);
452    else
453        xf86DeleteInput(pInfo, 0);
454
455    xfree(idev->driver);
456    xfree(idev->identifier);
457    xf86optionListFree(idev->commonOptions);
458    xfree(idev);
459}
460
461/*
462 * convenient functions to post events
463 */
464
465_X_EXPORT void
466xf86PostMotionEvent(DeviceIntPtr	device,
467                    int			is_absolute,
468                    int			first_valuator,
469                    int			num_valuators,
470                    ...)
471{
472    va_list var;
473    int i = 0;
474    static int *valuators = NULL;
475    static int n_valuators = 0;
476
477    if (num_valuators > n_valuators) {
478	xfree (valuators);
479	valuators = NULL;
480    }
481
482    if (!valuators) {
483	valuators = xcalloc(sizeof(int), num_valuators);
484	n_valuators = num_valuators;
485    }
486
487    va_start(var, num_valuators);
488    for (i = 0; i < num_valuators; i++)
489        valuators[i] = va_arg(var, int);
490    va_end(var);
491
492    xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
493}
494
495_X_EXPORT void
496xf86PostMotionEventP(DeviceIntPtr	device,
497                    int			is_absolute,
498                    int			first_valuator,
499                    int			num_valuators,
500                    int			*valuators)
501{
502    int i = 0, nevents = 0;
503    int dx, dy;
504    Bool drag = xf86SendDragEvents(device);
505    xEvent *xE = NULL;
506    int index;
507    int flags = 0;
508
509    if (is_absolute)
510        flags = POINTER_ABSOLUTE;
511    else
512        flags = POINTER_RELATIVE | POINTER_ACCELERATE;
513
514#if XFreeXDGA
515    if (first_valuator == 0 && num_valuators >= 2) {
516        if (miPointerGetScreen(inputInfo.pointer)) {
517            index = miPointerGetScreen(inputInfo.pointer)->myNum;
518            if (is_absolute) {
519                dx = valuators[0] - device->valuator->lastx;
520                dy = valuators[1] - device->valuator->lasty;
521            }
522            else {
523                dx = valuators[0];
524                dy = valuators[1];
525            }
526            if (DGAStealMotionEvent(index, dx, dy))
527                return;
528        }
529    }
530#endif
531
532    if (!xf86Events)
533        xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
534    if (!xf86Events)
535        FatalError("Couldn't allocate event store\n");
536
537    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
538                               flags, first_valuator, num_valuators,
539                               valuators);
540
541    for (i = 0; i < nevents; i++) {
542        xE = xf86Events + i;
543        /* Don't post core motion events for devices not registered to send
544         * drag events. */
545        if (xE->u.u.type != MotionNotify || drag) {
546            mieqEnqueue(device, xf86Events + i);
547        }
548    }
549}
550
551_X_EXPORT void
552xf86PostProximityEvent(DeviceIntPtr	device,
553                       int		is_in,
554                       int		first_valuator,
555                       int		num_valuators,
556                       ...)
557{
558    va_list var;
559    int i, nevents, *valuators = NULL;
560
561    valuators = xcalloc(sizeof(int), num_valuators);
562
563    va_start(var, num_valuators);
564    for (i = 0; i < num_valuators; i++)
565        valuators[i] = va_arg(var, int);
566    va_end(var);
567
568    if (!xf86Events)
569        xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
570    if (!xf86Events)
571        FatalError("Couldn't allocate event store\n");
572
573    nevents = GetProximityEvents(xf86Events, device,
574                                 is_in ? ProximityIn : ProximityOut,
575                                 first_valuator, num_valuators, valuators);
576    for (i = 0; i < nevents; i++)
577        mieqEnqueue(device, xf86Events + i);
578
579    xfree(valuators);
580}
581
582_X_EXPORT void
583xf86PostButtonEvent(DeviceIntPtr	device,
584                    int			is_absolute,
585                    int			button,
586                    int			is_down,
587                    int			first_valuator,
588                    int			num_valuators,
589                    ...)
590{
591    va_list var;
592    int *valuators = NULL;
593    int i = 0, nevents = 0;
594    int index;
595
596#if XFreeXDGA
597    if (miPointerGetScreen(inputInfo.pointer)) {
598        index = miPointerGetScreen(inputInfo.pointer)->myNum;
599        if (DGAStealButtonEvent(index, button, is_down))
600            return;
601    }
602#endif
603
604    valuators = xcalloc(sizeof(int), num_valuators);
605
606    va_start(var, num_valuators);
607    for (i = 0; i < num_valuators; i++)
608        valuators[i] = va_arg(var, int);
609    va_end(var);
610
611    if (!xf86Events)
612        xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
613    if (!xf86Events)
614        FatalError("Couldn't allocate event store\n");
615
616    nevents = GetPointerEvents(xf86Events, device,
617                               is_down ? ButtonPress : ButtonRelease, button,
618                               is_absolute ? POINTER_ABSOLUTE :
619                                             POINTER_RELATIVE,
620                               first_valuator, num_valuators, valuators);
621
622    for (i = 0; i < nevents; i++)
623        mieqEnqueue(device, xf86Events + i);
624
625    xfree(valuators);
626}
627
628_X_EXPORT void
629xf86PostKeyEvent(DeviceIntPtr	device,
630                 unsigned int	key_code,
631                 int		is_down,
632                 int		is_absolute,
633                 int		first_valuator,
634                 int		num_valuators,
635                 ...)
636{
637    va_list var;
638    int i = 0, nevents = 0, *valuators = NULL;
639
640    /* instil confidence in the user */
641    DebugF("this function has never been tested properly.  if things go quite "
642           "badly south after this message, then xf86PostKeyEvent is "
643           "broken.\n");
644
645    if (!xf86Events)
646        xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
647    if (!xf86Events)
648        FatalError("Couldn't allocate event store\n");
649
650    if (is_absolute) {
651        valuators = xcalloc(sizeof(int), num_valuators);
652        va_start(var, num_valuators);
653        for (i = 0; i < num_valuators; i++)
654            valuators[i] = va_arg(var, int);
655        va_end(var);
656
657        nevents = GetKeyboardValuatorEvents(xf86Events, device,
658                                            is_down ? KeyPress : KeyRelease,
659                                            key_code, first_valuator,
660                                            num_valuators, valuators);
661        xfree(valuators);
662    }
663    else {
664        nevents = GetKeyboardEvents(xf86Events, device,
665                                    is_down ? KeyPress : KeyRelease,
666                                    key_code);
667    }
668
669    for (i = 0; i < nevents; i++)
670        mieqEnqueue(device, xf86Events + i);
671}
672
673_X_EXPORT void
674xf86PostKeyboardEvent(DeviceIntPtr      device,
675                      unsigned int      key_code,
676                      int               is_down)
677{
678    int nevents = 0, i = 0;
679    int index;
680
681#if XFreeXDGA
682    if (miPointerGetScreen(inputInfo.pointer)) {
683        index = miPointerGetScreen(inputInfo.pointer)->myNum;
684        if (DGAStealKeyEvent(index, key_code, is_down))
685            return;
686    }
687#endif
688
689    if (!xf86Events)
690        xf86Events = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
691    if (!xf86Events)
692        FatalError("Couldn't allocate event store\n");
693
694    nevents = GetKeyboardEvents(xf86Events, device,
695                                is_down ? KeyPress : KeyRelease, key_code);
696
697    for (i = 0; i < nevents; i++)
698        mieqEnqueue(device, xf86Events + i);
699}
700
701_X_EXPORT LocalDevicePtr
702xf86FirstLocalDevice()
703{
704    return xf86InputDevs;
705}
706
707/*
708 * Cx     - raw data from touch screen
709 * Sxhigh - scaled highest dimension
710 *          (remember, this is of rows - 1 because of 0 origin)
711 * Sxlow  - scaled lowest dimension
712 * Rxhigh - highest raw value from touch screen calibration
713 * Rxlow  - lowest raw value from touch screen calibration
714 *
715 * This function is the same for X or Y coordinates.
716 * You may have to reverse the high and low values to compensate for
717 * different orgins on the touch screen vs X.
718 */
719
720_X_EXPORT int
721xf86ScaleAxis(int	Cx,
722              int	Sxhigh,
723              int	Sxlow,
724              int	Rxhigh,
725              int	Rxlow )
726{
727    int X;
728    int dSx = Sxhigh - Sxlow;
729    int dRx = Rxhigh - Rxlow;
730
731    dSx = Sxhigh - Sxlow;
732    if (dRx) {
733	X = ((dSx * (Cx - Rxlow)) / dRx) + Sxlow;
734    }
735    else {
736	X = 0;
737	ErrorF ("Divide by Zero in xf86ScaleAxis");
738    }
739
740    if (X > Sxlow)
741	X = Sxlow;
742    if (X < Sxhigh)
743	X = Sxhigh;
744
745    return (X);
746}
747
748/*
749 * This function checks the given screen against the current screen and
750 * makes changes if appropriate. It should be called from an XInput driver's
751 * ReadInput function before any events are posted, if the device is screen
752 * specific like a touch screen.
753 */
754_X_EXPORT void
755xf86XInputSetScreen(LocalDevicePtr	local,
756		    int			screen_number,
757		    int			x,
758		    int			y)
759{
760    if (miPointerGetScreen(local->dev) !=
761          screenInfo.screens[screen_number]) {
762	miPointerSetScreen(local->dev, screen_number, x, y);
763    }
764}
765
766
767_X_EXPORT void
768xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
769			   int resolution, int min_res, int max_res)
770{
771    if (!dev || !dev->valuator)
772        return;
773
774    InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution, min_res,
775			   max_res);
776}
777
778/*
779 * Set the valuator values to be in synch with dix/event.c
780 * DefineInitialRootWindow().
781 */
782_X_EXPORT void
783xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
784{
785    if (axnum == 0) {
786	dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
787        dev->valuator->lastx = dev->valuator->axisVal[0];
788    }
789    else if (axnum == 1) {
790	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
791        dev->valuator->lasty = dev->valuator->axisVal[1];
792    }
793}
794
795
796/**
797 * Deactivate a device. Call this function from the driver if you receive a
798 * read error or something else that spoils your day.
799 * Device will be moved to the off_devices list, but it will still be there
800 * until you really clean up after it.
801 * Notifies the client about an inactive device.
802 *
803 * @param panic True if device is unrecoverable and needs to be removed.
804 */
805_X_EXPORT void
806xf86DisableDevice(DeviceIntPtr dev, Bool panic)
807{
808    devicePresenceNotify ev;
809    DeviceIntRec dummyDev;
810
811    if(!panic)
812    {
813        DisableDevice(dev);
814    } else
815    {
816        ev.type = DevicePresenceNotify;
817        ev.time = currentTime.milliseconds;
818        ev.devchange = DeviceUnrecoverable;
819        ev.deviceid = dev->id;
820        dummyDev.id = 0;
821        SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
822                (xEvent *) &ev, 1);
823
824        DeleteInputDeviceRequest(dev);
825    }
826}
827
828/**
829 * Reactivate a device. Call this function from the driver if you just found
830 * out that the read error wasn't quite that bad after all.
831 * Device will be re-activated, and an event sent to the client.
832 */
833_X_EXPORT void
834xf86EnableDevice(DeviceIntPtr dev)
835{
836    EnableDevice(dev);
837}
838
839/* end of xf86Xinput.c */
840