getevents.c revision 4202a189
1/*
2 * Copyright © 2006 Nokia Corporation
3 * Copyright © 2006-2007 Daniel Stone
4 * Copyright © 2008 Red Hat, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors: Daniel Stone <daniel@fooishbar.org>
26 *          Peter Hutterer <peter.hutterer@who-t.net>
27 */
28
29#ifdef HAVE_DIX_CONFIG_H
30#include <dix-config.h>
31#endif
32
33#include <X11/X.h>
34#include <X11/keysym.h>
35#include <X11/Xproto.h>
36#include <math.h>
37
38#include "misc.h"
39#include "resource.h"
40#include "inputstr.h"
41#include "scrnintstr.h"
42#include "cursorstr.h"
43#include "dixstruct.h"
44#include "globals.h"
45#include "dixevents.h"
46#include "mipointer.h"
47#include "eventstr.h"
48#include "eventconvert.h"
49
50#include <X11/extensions/XKBproto.h>
51#include "xkbsrv.h"
52
53#ifdef PANORAMIX
54#include "panoramiX.h"
55#include "panoramiXsrv.h"
56#endif
57
58#include <X11/extensions/XI.h>
59#include <X11/extensions/XIproto.h>
60#include <pixman.h>
61#include "exglobals.h"
62#include "exevents.h"
63#include "exglobals.h"
64#include "extnsionst.h"
65#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
66
67/* Number of motion history events to store. */
68#define MOTION_HISTORY_SIZE 256
69
70/* InputEventList is the container list for all input events generated by the
71 * DDX. The DDX is expected to call GetEventList() and then pass the list into
72 * Get{Pointer|Keyboard}Events.
73 */
74EventListPtr InputEventList = NULL;
75int InputEventListLen = 0;
76
77int
78GetEventList(EventListPtr* list)
79{
80    *list = InputEventList;
81    return InputEventListLen;
82}
83
84/**
85 * Pick some arbitrary size for Xi motion history.
86 */
87int
88GetMotionHistorySize(void)
89{
90    return MOTION_HISTORY_SIZE;
91}
92
93void
94set_button_down(DeviceIntPtr pDev, int button, int type)
95{
96    if (type == BUTTON_PROCESSED)
97        SetBit(pDev->button->down, button);
98    else
99        SetBit(pDev->button->postdown, button);
100}
101
102void
103set_button_up(DeviceIntPtr pDev, int button, int type)
104{
105    if (type == BUTTON_PROCESSED)
106        ClearBit(pDev->button->down, button);
107    else
108        ClearBit(pDev->button->postdown, button);
109}
110
111Bool
112button_is_down(DeviceIntPtr pDev, int button, int type)
113{
114    int ret = 0;
115
116    if (type & BUTTON_PROCESSED)
117        ret |= !!BitIsOn(pDev->button->down, button);
118    if (type & BUTTON_POSTED)
119        ret |= !!BitIsOn(pDev->button->postdown, button);
120
121    return ret;
122}
123
124void
125set_key_down(DeviceIntPtr pDev, int key_code, int type)
126{
127    if (type == KEY_PROCESSED)
128        SetBit(pDev->key->down, key_code);
129    else
130        SetBit(pDev->key->postdown, key_code);
131}
132
133void
134set_key_up(DeviceIntPtr pDev, int key_code, int type)
135{
136    if (type == KEY_PROCESSED)
137        ClearBit(pDev->key->down, key_code);
138    else
139        ClearBit(pDev->key->postdown, key_code);
140}
141
142Bool
143key_is_down(DeviceIntPtr pDev, int key_code, int type)
144{
145    int ret = 0;
146
147    if (type & KEY_PROCESSED)
148        ret |= !!BitIsOn(pDev->key->down, key_code);
149    if (type & KEY_POSTED)
150        ret |= !!BitIsOn(pDev->key->postdown, key_code);
151
152    return ret;
153}
154
155static Bool
156key_autorepeats(DeviceIntPtr pDev, int key_code)
157{
158    return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
159              (1 << (key_code & 7)));
160}
161
162static void
163init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
164{
165    memset(event, 0, sizeof(DeviceEvent));
166    event->header = ET_Internal;
167    event->length = sizeof(DeviceEvent);
168    event->time = ms;
169    event->deviceid = dev->id;
170    event->sourceid = dev->id;
171}
172
173static void
174init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
175{
176    memset(event, 0, sizeof(RawDeviceEvent));
177    event->header = ET_Internal;
178    event->length = sizeof(RawDeviceEvent);
179    event->type = ET_RawKeyPress - ET_KeyPress + type;
180    event->time = ms;
181    event->deviceid = dev->id;
182    event->sourceid = dev->id;
183    event->detail.button = detail;
184}
185
186static void
187set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
188{
189    int i;
190    for (i = first; i < first + num; i++)
191        SetBit(event->valuators.mask, i);
192
193    memcpy(&data[first], valuators, num * sizeof(uint32_t));
194}
195
196
197static void
198set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
199              int num_valuators, int *valuators)
200{
201    int i;
202
203    for (i = first_valuator; i < first_valuator + num_valuators; i++)
204    {
205        SetBit(event->valuators.mask, i);
206        if (dev->valuator->mode == Absolute)
207            SetBit(event->valuators.mode, i);
208        event->valuators.data_frac[i] =
209            dev->last.remainder[i] * (1 << 16) * (1 << 16);
210    }
211
212    memcpy(&event->valuators.data[first_valuator],
213           valuators, num_valuators * sizeof(uint32_t));
214
215}
216
217void
218CreateClassesChangedEvent(EventList* event,
219                          DeviceIntPtr master,
220                          DeviceIntPtr slave,
221                          int type)
222{
223    int i;
224    DeviceChangedEvent *dce;
225    CARD32 ms = GetTimeInMillis();
226
227    dce = (DeviceChangedEvent*)event->event;
228    memset(dce, 0, sizeof(DeviceChangedEvent));
229    dce->deviceid = slave->id;
230    dce->masterid = master->id;
231    dce->header = ET_Internal;
232    dce->length = sizeof(DeviceChangedEvent);
233    dce->type = ET_DeviceChanged;
234    dce->time = ms;
235    dce->flags = type;
236    dce->flags |= DEVCHANGE_SLAVE_SWITCH;
237    dce->sourceid = slave->id;
238
239    if (slave->button)
240    {
241        dce->buttons.num_buttons = slave->button->numButtons;
242        for (i = 0; i < dce->buttons.num_buttons; i++)
243            dce->buttons.names[i] = slave->button->labels[i];
244    }
245    if (slave->valuator)
246    {
247        dce->num_valuators = slave->valuator->numAxes;
248        for (i = 0; i < dce->num_valuators; i++)
249        {
250            dce->valuators[i].min = slave->valuator->axes[i].min_value;
251            dce->valuators[i].max = slave->valuator->axes[i].max_value;
252            dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
253            /* This should, eventually, be a per-axis mode */
254            dce->valuators[i].mode = slave->valuator->mode;
255            dce->valuators[i].name = slave->valuator->axes[i].label;
256        }
257    }
258    if (slave->key)
259    {
260        dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
261        dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
262    }
263}
264
265/**
266 * Rescale the coord between the two axis ranges.
267 */
268static int
269rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to,
270                    int defmax)
271{
272    int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return;
273    float value;
274
275    if(from && from->min_value < from->max_value) {
276        fmin = from->min_value;
277        fmax = from->max_value;
278    }
279    if(to && to->min_value < to->max_value) {
280        tmin = to->min_value;
281        tmax = to->max_value;
282    }
283
284    if(fmin == tmin && fmax == tmax) {
285        if (remainder_return)
286            *remainder_return = remainder;
287        return coord;
288    }
289
290    if(fmax == fmin) { /* avoid division by 0 */
291        if (remainder_return)
292            *remainder_return = 0.0;
293        return 0;
294    }
295
296    value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
297    coord_return = lroundf(value);
298    if (remainder_return)
299        *remainder_return = value - coord_return;
300    return coord_return;
301}
302
303/**
304 * Update all coordinates when changing to a different SD
305 * to ensure that relative reporting will work as expected
306 * without loss of precision.
307 *
308 * pDev->last.valuators will be in absolute device coordinates after this
309 * function.
310 */
311static void
312updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
313{
314    ScreenPtr scr = miPointerGetScreen(pDev);
315    int i;
316    DeviceIntPtr lastSlave;
317
318    /* master->last.valuators[0]/[1] is in screen coords and the actual
319     * position of the pointer */
320    pDev->last.valuators[0] = master->last.valuators[0];
321    pDev->last.valuators[1] = master->last.valuators[1];
322
323    if (!pDev->valuator)
324        return;
325
326    /* scale back to device coordinates */
327    if(pDev->valuator->numAxes > 0)
328        pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0],
329                        &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width);
330    if(pDev->valuator->numAxes > 1)
331        pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1],
332                        &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height);
333
334    /* calculate the other axis as well based on info from the old
335     * slave-device. If the old slave had less axes than this one,
336     * last.valuators is reset to 0.
337     */
338    if ((lastSlave = master->last.slave) && lastSlave->valuator) {
339        for (i = 2; i < pDev->valuator->numAxes; i++) {
340            if (i >= lastSlave->valuator->numAxes)
341                pDev->last.valuators[i] = 0;
342            else
343                pDev->last.valuators[i] =
344                    rescaleValuatorAxis(pDev->last.valuators[i],
345                            pDev->last.remainder[i],
346                            &pDev->last.remainder[i],
347                            lastSlave->valuator->axes + i,
348                            pDev->valuator->axes + i, 0);
349        }
350    }
351
352}
353
354/**
355 * Allocate the motion history buffer.
356 */
357void
358AllocateMotionHistory(DeviceIntPtr pDev)
359{
360    int size;
361    free(pDev->valuator->motion);
362
363    if (pDev->valuator->numMotionEvents < 1)
364        return;
365
366    /* An MD must have a motion history size large enough to keep all
367     * potential valuators, plus the respective range of the valuators.
368     * 3 * INT32 for (min_val, max_val, curr_val))
369     */
370    if (IsMaster(pDev))
371        size = sizeof(INT32) * 3 * MAX_VALUATORS;
372    else
373        size = sizeof(INT32) * pDev->valuator->numAxes;
374
375    size += sizeof(Time);
376
377    pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size);
378    pDev->valuator->first_motion = 0;
379    pDev->valuator->last_motion = 0;
380    if (!pDev->valuator->motion)
381        ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
382                pDev->name, size * pDev->valuator->numMotionEvents);
383}
384
385/**
386 * Dump the motion history between start and stop into the supplied buffer.
387 * Only records the event for a given screen in theory, but in practice, we
388 * sort of ignore this.
389 *
390 * If core is set, we only generate x/y, in INT16, scaled to screen coords.
391 */
392int
393GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
394                 unsigned long stop, ScreenPtr pScreen, BOOL core)
395{
396    char *ibuff = NULL, *obuff;
397    int i = 0, ret = 0;
398    int j, coord;
399    Time current;
400    /* The size of a single motion event. */
401    int size;
402    int dflt;
403    AxisInfo from, *to; /* for scaling */
404    INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
405    INT16 *corebuf;
406    AxisInfo core_axis = {0};
407
408    if (!pDev->valuator || !pDev->valuator->numMotionEvents)
409        return 0;
410
411    if (core && !pScreen)
412        return 0;
413
414    if (IsMaster(pDev))
415        size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
416    else
417        size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
418
419    *buff = malloc(size * pDev->valuator->numMotionEvents);
420    if (!(*buff))
421        return 0;
422    obuff = (char *)*buff;
423
424    for (i = pDev->valuator->first_motion;
425         i != pDev->valuator->last_motion;
426         i = (i + 1) % pDev->valuator->numMotionEvents) {
427        /* We index the input buffer by which element we're accessing, which
428         * is not monotonic, and the output buffer by how many events we've
429         * written so far. */
430        ibuff = (char *) pDev->valuator->motion + (i * size);
431        memcpy(&current, ibuff, sizeof(Time));
432
433        if (current > stop) {
434            return ret;
435        }
436        else if (current >= start) {
437            if (core)
438            {
439                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
440
441                icbuf = (INT32*)(ibuff + sizeof(Time));
442                corebuf = (INT16*)(obuff + sizeof(Time));
443
444                /* fetch x coordinate + range */
445                memcpy(&from.min_value, icbuf++, sizeof(INT32));
446                memcpy(&from.max_value, icbuf++, sizeof(INT32));
447                memcpy(&coord, icbuf++, sizeof(INT32));
448
449                /* scale to screen coords */
450                to = &core_axis;
451                to->max_value = pScreen->width;
452                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width);
453
454                memcpy(corebuf, &coord, sizeof(INT16));
455                corebuf++;
456
457                /* fetch y coordinate + range */
458                memcpy(&from.min_value, icbuf++, sizeof(INT32));
459                memcpy(&from.max_value, icbuf++, sizeof(INT32));
460                memcpy(&coord, icbuf++, sizeof(INT32));
461
462                to->max_value = pScreen->height;
463                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height);
464                memcpy(corebuf, &coord, sizeof(INT16));
465
466            } else if (IsMaster(pDev))
467            {
468                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
469
470                ocbuf = (INT32*)(obuff + sizeof(Time));
471                icbuf = (INT32*)(ibuff + sizeof(Time));
472                for (j = 0; j < MAX_VALUATORS; j++)
473                {
474                    if (j >= pDev->valuator->numAxes)
475                        break;
476
477                    /* fetch min/max/coordinate */
478                    memcpy(&from.min_value, icbuf++, sizeof(INT32));
479                    memcpy(&from.max_value, icbuf++, sizeof(INT32));
480                    memcpy(&coord, icbuf++, sizeof(INT32));
481
482                    to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
483
484                    /* x/y scaled to screen if no range is present */
485                    if (j == 0 && (from.max_value < from.min_value))
486                        from.max_value = pScreen->width;
487                    else if (j == 1 && (from.max_value < from.min_value))
488                        from.max_value = pScreen->height;
489
490                    if (j == 0 && (to->max_value < to->min_value))
491                        dflt = pScreen->width;
492                    else if (j == 1 && (to->max_value < to->min_value))
493                        dflt = pScreen->height;
494                    else
495                        dflt = 0;
496
497                    /* scale from stored range into current range */
498                    coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0);
499                    memcpy(ocbuf, &coord, sizeof(INT32));
500                    ocbuf++;
501                }
502            } else
503                memcpy(obuff, ibuff, size);
504
505            /* don't advance by size here. size may be different to the
506             * actually written size if the MD has less valuators than MAX */
507            if (core)
508                obuff += sizeof(INT32) + sizeof(Time);
509            else
510                obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
511            ret++;
512        }
513    }
514
515    return ret;
516}
517
518
519/**
520 * Update the motion history for a specific device, with the list of
521 * valuators.
522 *
523 * Layout of the history buffer:
524 *   for SDs: [time] [val0] [val1] ... [valn]
525 *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
526 *
527 * For events that have some valuators unset (first_valuator > 0):
528 *      min_val == max_val == val == 0.
529 */
530static void
531updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
532                    int num_valuators, int *valuators)
533{
534    char *buff = (char *) pDev->valuator->motion;
535    ValuatorClassPtr v;
536    int i;
537
538    if (!pDev->valuator->numMotionEvents)
539        return;
540
541    v = pDev->valuator;
542    if (IsMaster(pDev))
543    {
544        buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
545                v->last_motion;
546
547        memcpy(buff, &ms, sizeof(Time));
548        buff += sizeof(Time);
549
550        memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
551        buff += 3 * sizeof(INT32) * first_valuator;
552
553        for (i = first_valuator; i < first_valuator + num_valuators; i++)
554        {
555            if (i >= v->numAxes)
556                break;
557            memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
558            buff += sizeof(INT32);
559            memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
560            buff += sizeof(INT32);
561            memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
562            buff += sizeof(INT32);
563        }
564    } else
565    {
566
567        buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
568            pDev->valuator->last_motion;
569
570        memcpy(buff, &ms, sizeof(Time));
571        buff += sizeof(Time);
572
573        memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
574        buff += sizeof(INT32) * first_valuator;
575
576        memcpy(buff, valuators, sizeof(INT32) * num_valuators);
577    }
578
579    pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
580        pDev->valuator->numMotionEvents;
581    /* If we're wrapping around, just keep the circular buffer going. */
582    if (pDev->valuator->first_motion == pDev->valuator->last_motion)
583        pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
584                                       pDev->valuator->numMotionEvents;
585
586    return;
587}
588
589
590/**
591 * Returns the maximum number of events GetKeyboardEvents,
592 * GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
593 *
594 * This MUST be absolutely constant, from init until exit.
595 */
596int
597GetMaximumEventsNum(void) {
598    /* One raw event
599     * One device event
600     * One possible device changed event
601     */
602    return 3;
603}
604
605
606/**
607 * Clip an axis to its bounds, which are declared in the call to
608 * InitValuatorAxisClassStruct.
609 */
610static void
611clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
612{
613    AxisInfoPtr axis;
614
615    if (axisNum >= pDev->valuator->numAxes)
616        return;
617
618    axis = pDev->valuator->axes + axisNum;
619
620    /* If a value range is defined, clip. If not, do nothing */
621    if (axis->max_value <= axis->min_value)
622        return;
623
624    if (*val < axis->min_value)
625        *val = axis->min_value;
626    if (*val > axis->max_value)
627        *val = axis->max_value;
628}
629
630/**
631 * Clip every axis in the list of valuators to its bounds.
632 */
633static void
634clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
635              int *valuators)
636{
637    int i;
638
639    for (i = 0; i < num_valuators; i++)
640        clipAxis(pDev, i + first_valuator, &(valuators[i]));
641}
642
643/**
644 * Create the DCCE event (does not update the master's device state yet, this
645 * is done in the event processing).
646 * Pull in the coordinates from the MD if necessary.
647 *
648 * @param events Pointer to a pre-allocated event list.
649 * @param dev The slave device that generated an event.
650 * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
651 * @param num_events The current number of events, returns the number of
652 *        events if a DCCE was generated.
653 * @return The updated @events pointer.
654 */
655EventListPtr
656UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
657{
658    DeviceIntPtr master;
659
660    master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ?  MASTER_POINTER : MASTER_KEYBOARD);
661
662    if (master && master->last.slave != dev)
663    {
664        CreateClassesChangedEvent(events, master, dev, type);
665        if (IsPointerDevice(master))
666        {
667            updateSlaveDeviceCoords(master, dev);
668            master->last.numValuators = dev->last.numValuators;
669        }
670        master->last.slave = dev;
671        (*num_events)++;
672        events++;
673    }
674    return events;
675}
676
677/**
678 * Move the device's pointer to the position given in the valuators.
679 *
680 * @param dev The device which's pointer is to be moved.
681 * @param x Returns the x position of the pointer after the move.
682 * @param y Returns the y position of the pointer after the move.
683 * @param first The first valuator in @valuators
684 * @param num Total number of valuators in @valuators.
685 * @param valuators Valuator data for each axis between @first and
686 *        @first+@num.
687 */
688static void
689moveAbsolute(DeviceIntPtr dev, int *x, int *y,
690             int first, int num, int *valuators)
691{
692    int i;
693
694
695    if (num >= 1 && first == 0)
696        *x = *(valuators + 0);
697    else
698        *x = dev->last.valuators[0];
699
700    if (first <= 1 && num >= (2 - first))
701        *y = *(valuators + 1 - first);
702    else
703        *y = dev->last.valuators[1];
704
705    clipAxis(dev, 0, x);
706    clipAxis(dev, 1, y);
707
708    i = (first > 2) ? 0 : 2;
709    for (; i < num; i++)
710    {
711        dev->last.valuators[i + first] = valuators[i];
712        clipAxis(dev, i, &dev->last.valuators[i + first]);
713    }
714}
715
716/**
717 * Move the device's pointer by the values given in @valuators.
718 *
719 * @param dev The device which's pointer is to be moved.
720 * @param x Returns the x position of the pointer after the move.
721 * @param y Returns the y position of the pointer after the move.
722 * @param first The first valuator in @valuators
723 * @param num Total number of valuators in @valuators.
724 * @param valuators Valuator data for each axis between @first and
725 *        @first+@num.
726 */
727static void
728moveRelative(DeviceIntPtr dev, int *x, int *y,
729             int first, int num, int *valuators)
730{
731    int i;
732
733    *x = dev->last.valuators[0];
734    *y = dev->last.valuators[1];
735
736    if (num >= 1 && first == 0)
737        *x += *(valuators +0);
738
739    if (first <= 1 && num >= (2 - first))
740        *y += *(valuators + 1 - first);
741
742    /* if attached, clip both x and y to the defined limits (usually
743     * co-ord space limit). If it is attached, we need x/y to go over the
744     * limits to be able to change screens. */
745    if(dev->u.master && dev->valuator->mode == Absolute) {
746        clipAxis(dev, 0, x);
747        clipAxis(dev, 1, y);
748    }
749
750    /* calc other axes, clip, drop back into valuators */
751    i = (first > 2) ? 0 : 2;
752    for (; i < num; i++)
753    {
754        dev->last.valuators[i + first] += valuators[i];
755        if (dev->valuator->mode == Absolute)
756            clipAxis(dev, i, &dev->last.valuators[i + first]);
757        valuators[i] = dev->last.valuators[i + first];
758    }
759}
760
761/**
762 * Accelerate the data in valuators based on the device's acceleration scheme.
763 *
764 * @param dev The device which's pointer is to be moved.
765 * @param first The first valuator in @valuators
766 * @param num Total number of valuators in @valuators.
767 * @param valuators Valuator data for each axis between @first and
768 *        @first+@num.
769 * @param ms Current time.
770 */
771static void
772accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
773{
774    if (dev->valuator->accelScheme.AccelSchemeProc)
775        dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms);
776}
777
778/**
779 * If we have HW cursors, this actually moves the visible sprite. If not, we
780 * just do all the screen crossing, etc.
781 *
782 * We scale from device to screen coordinates here, call
783 * miPointerSetPosition() and then scale back into device coordinates (if
784 * needed). miPSP will change x/y if the screen was crossed.
785 *
786 * @param dev The device to be moved.
787 * @param x Pointer to current x-axis value, may be modified.
788 * @param y Pointer to current y-axis value, may be modified.
789 * @param x_frac Fractional part of current x-axis value, may be modified.
790 * @param y_frac Fractional part of current y-axis value, may be modified.
791 * @param scr Screen the device's sprite is currently on.
792 * @param screenx Screen x coordinate the sprite is on after the update.
793 * @param screeny Screen y coordinate the sprite is on after the update.
794 * @param screenx_frac Fractional part of screen x coordinate, as above.
795 * @param screeny_frac Fractional part of screen y coordinate, as above.
796 */
797static void
798positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
799               ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
800{
801    int old_screenx, old_screeny;
802
803    /* scale x&y to screen */
804    if (dev->valuator->numAxes > 0) {
805        *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac,
806                dev->valuator->axes + 0, NULL, scr->width);
807    } else {
808        *screenx = dev->last.valuators[0];
809        *screenx_frac = dev->last.remainder[0];
810    }
811
812    if (dev->valuator->numAxes > 1) {
813        *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac,
814                dev->valuator->axes + 1, NULL, scr->height);
815    } else {
816        *screeny = dev->last.valuators[1];
817        *screeny_frac = dev->last.remainder[1];
818    }
819
820    /* Hit the left screen edge? */
821    if (*screenx <= 0 && *screenx_frac < 0.0f)
822    {
823        *screenx_frac = 0.0f;
824        x_frac = 0.0f;
825    }
826    if (*screeny <= 0 && *screeny_frac < 0.0f)
827    {
828        *screeny_frac = 0.0f;
829        y_frac = 0.0f;
830    }
831
832
833    old_screenx = *screenx;
834    old_screeny = *screeny;
835    /* This takes care of crossing screens for us, as well as clipping
836     * to the current screen. */
837    miPointerSetPosition(dev, screenx, screeny);
838
839    if (dev->u.master) {
840        dev->u.master->last.valuators[0] = *screenx;
841        dev->u.master->last.valuators[1] = *screeny;
842        dev->u.master->last.remainder[0] = *screenx_frac;
843        dev->u.master->last.remainder[1] = *screeny_frac;
844    }
845
846    /* Crossed screen? Scale back to device coordiantes */
847    if(*screenx != old_screenx)
848    {
849        scr = miPointerGetScreen(dev);
850        *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL,
851                                dev->valuator->axes + 0, scr->width);
852    }
853    if(*screeny != old_screeny)
854    {
855        scr = miPointerGetScreen(dev);
856        *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL,
857                                 dev->valuator->axes + 1, scr->height);
858    }
859
860    /* dropy x/y (device coordinates) back into valuators for next event */
861    dev->last.valuators[0] = *x;
862    dev->last.valuators[1] = *y;
863    dev->last.remainder[0] = x_frac;
864    dev->last.remainder[1] = y_frac;
865}
866
867/**
868 * Update the motion history for the device and (if appropriate) for its
869 * master device.
870 * @param dev Slave device to update.
871 * @param first First valuator to append to history.
872 * @param num Total number of valuators to append to history.
873 * @param ms Current time
874 */
875static void
876updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
877{
878    updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
879    if (dev->u.master)
880    {
881        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
882        updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]);
883    }
884}
885
886/**
887 * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
888 * valuators.
889 */
890int
891GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
892    return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
893}
894
895
896/**
897 * Returns a set of keyboard events for KeyPress/KeyRelease, optionally
898 * also with valuator events.  Handles Xi and XKB.
899 *
900 * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
901 * event (ProcessOtherEvent).
902 *
903 * events is not NULL-terminated; the return value is the number of events.
904 * The DDX is responsible for allocating the event structure in the first
905 * place via GetMaximumEventsNum(), and for freeing it.
906 *
907 * This function does not change the core keymap to that of the device;
908 * that is done by SwitchCoreKeyboard, which is called from
909 * mieqProcessInputEvents.  If replacing that function, take care to call
910 * SetCoreKeyboard before processInputProc, so keymaps are altered to suit.
911 */
912int
913GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
914                          int key_code, int first_valuator,
915                          int num_valuators, int *valuators_in) {
916    int num_events = 0;
917    CARD32 ms = 0;
918    DeviceEvent *event;
919    RawDeviceEvent *raw;
920    int valuators[MAX_VALUATORS];
921
922    /* refuse events from disabled devices */
923    if (!pDev->enabled)
924        return 0;
925
926    if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
927        num_valuators > MAX_VALUATORS ||
928       (type != KeyPress && type != KeyRelease) ||
929       (key_code < 8 || key_code > 255))
930        return 0;
931
932    num_events = 1;
933
934    events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
935
936    /* Handle core repeating, via press/release/press/release. */
937    if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
938        /* If autorepeating is disabled either globally or just for that key,
939         * or we have a modifier, don't generate a repeat event. */
940        if (!pDev->kbdfeed->ctrl.autoRepeat ||
941            !key_autorepeats(pDev, key_code) ||
942            pDev->key->xkbInfo->desc->map->modmap[key_code])
943            return 0;
944    }
945
946    ms = GetTimeInMillis();
947
948    raw = (RawDeviceEvent*)events->event;
949    events++;
950    num_events++;
951
952    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
953
954    init_raw(pDev, raw, ms, type, key_code);
955    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
956                      raw->valuators.data_raw);
957
958    if (num_valuators)
959        clipValuators(pDev, first_valuator, num_valuators, valuators);
960
961    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
962                      raw->valuators.data);
963
964    event = (DeviceEvent*) events->event;
965    init_event(pDev, event, ms);
966    event->detail.key = key_code;
967
968    if (type == KeyPress) {
969        event->type = ET_KeyPress;
970	set_key_down(pDev, key_code, KEY_POSTED);
971    }
972    else if (type == KeyRelease) {
973        event->type = ET_KeyRelease;
974	set_key_up(pDev, key_code, KEY_POSTED);
975    }
976
977    if (num_valuators)
978        clipValuators(pDev, first_valuator, num_valuators, valuators);
979
980    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
981
982    return num_events;
983}
984
985/**
986 * Initialize an event list and fill with 32 byte sized events.
987 * This event list is to be passed into GetPointerEvents() and
988 * GetKeyboardEvents().
989 *
990 * @param num_events Number of elements in list.
991 */
992EventListPtr
993InitEventList(int num_events)
994{
995    EventListPtr events;
996    int i;
997
998    events = (EventListPtr)calloc(num_events, sizeof(EventList));
999    if (!events)
1000        return NULL;
1001
1002    for (i = 0; i < num_events; i++)
1003    {
1004        events[i].evlen = sizeof(InternalEvent);
1005        events[i].event = calloc(1, sizeof(InternalEvent));
1006        if (!events[i].event)
1007        {
1008            /* rollback */
1009            while(i--)
1010                free(events[i].event);
1011            free(events);
1012            events = NULL;
1013            break;
1014        }
1015    }
1016
1017    return events;
1018}
1019
1020/**
1021 * Free an event list.
1022 *
1023 * @param list The list to be freed.
1024 * @param num_events Number of elements in list.
1025 */
1026void
1027FreeEventList(EventListPtr list, int num_events)
1028{
1029    if (!list)
1030        return;
1031    while(num_events--)
1032        free(list[num_events].event);
1033    free(list);
1034}
1035
1036static void
1037transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
1038{
1039    struct pixman_f_vector p;
1040
1041    /* p' = M * p in homogeneous coordinates */
1042    p.v[0] = v[0];
1043    p.v[1] = v[1];
1044    p.v[2] = 1.0;
1045
1046    pixman_f_transform_point(&dev->transform, &p);
1047
1048    v[0] = lround(p.v[0]);
1049    v[1] = lround(p.v[1]);
1050}
1051
1052/**
1053 * Generate a series of xEvents (filled into the EventList) representing
1054 * pointer motion, or button presses.  Xi and XKB-aware.
1055 *
1056 * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
1057 * event (ProcessOtherEvent).
1058 *
1059 * events is not NULL-terminated; the return value is the number of events.
1060 * The DDX is responsible for allocating the event structure in the first
1061 * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
1062 *
1063 * In the generated events rootX/Y will be in absolute screen coords and
1064 * the valuator information in the absolute or relative device coords.
1065 *
1066 * last.valuators[x] of the device is always in absolute device coords.
1067 * last.valuators[x] of the master device is in absolute screen coords.
1068 *
1069 * master->last.valuators[x] for x > 2 is undefined.
1070 */
1071int
1072GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
1073                 int flags, int first_valuator, int num_valuators,
1074                 int *valuators_in) {
1075    int num_events = 1;
1076    CARD32 ms;
1077    DeviceEvent *event;
1078    RawDeviceEvent    *raw;
1079    int x = 0, y = 0, /* device coords */
1080        cx, cy; /* only screen coordinates */
1081    float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
1082    ScreenPtr scr = miPointerGetScreen(pDev);
1083    int valuators[MAX_VALUATORS];
1084
1085    /* refuse events from disabled devices */
1086    if (!pDev->enabled)
1087        return 0;
1088
1089    ms = GetTimeInMillis(); /* before pointer update to help precision */
1090
1091    if (!scr || !pDev->valuator || first_valuator < 0 ||
1092        num_valuators > MAX_VALUATORS ||
1093        ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
1094        (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
1095        (type != MotionNotify && !pDev->button) ||
1096        ((type == ButtonPress || type == ButtonRelease) && !buttons) ||
1097        (type == MotionNotify && num_valuators <= 0))
1098        return 0;
1099
1100    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
1101
1102    raw = (RawDeviceEvent*)events->event;
1103    events++;
1104    num_events++;
1105
1106    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
1107
1108    init_raw(pDev, raw, ms, type, buttons);
1109    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
1110                      raw->valuators.data_raw);
1111
1112    if (flags & POINTER_ABSOLUTE)
1113    {
1114        if (flags & POINTER_SCREEN) /* valuators are in screen coords */
1115        {
1116
1117            if (num_valuators >= 1 && first_valuator == 0)
1118                valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL,
1119                        pDev->valuator->axes + 0,
1120                        scr->width);
1121            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
1122                valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL,
1123                        pDev->valuator->axes + 1,
1124                        scr->height);
1125        }
1126
1127        transformAbsolute(pDev, valuators);
1128        moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
1129    } else {
1130        if (flags & POINTER_ACCELERATE) {
1131            accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
1132            /* The pointer acceleration code modifies the fractional part
1133             * in-place, so we need to extract this information first */
1134            x_frac = pDev->last.remainder[0];
1135            y_frac = pDev->last.remainder[1];
1136        }
1137        moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
1138    }
1139
1140    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
1141            raw->valuators.data);
1142
1143    positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
1144    updateHistory(pDev, first_valuator, num_valuators, ms);
1145
1146    /* Update the valuators with the true value sent to the client*/
1147    if (num_valuators >= 1 && first_valuator == 0)
1148        valuators[0] = x;
1149    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
1150        valuators[1 - first_valuator] = y;
1151
1152    if (num_valuators)
1153        clipValuators(pDev, first_valuator, num_valuators, valuators);
1154
1155    event = (DeviceEvent*) events->event;
1156    init_event(pDev, event, ms);
1157
1158    if (type == MotionNotify) {
1159        event->type = ET_Motion;
1160        event->detail.button = 0;
1161    }
1162    else {
1163        if (type == ButtonPress) {
1164            event->type = ET_ButtonPress;
1165            set_button_down(pDev, buttons, BUTTON_POSTED);
1166        }
1167        else if (type == ButtonRelease) {
1168            event->type = ET_ButtonRelease;
1169            set_button_up(pDev, buttons, BUTTON_POSTED);
1170        }
1171        event->detail.button = buttons;
1172    }
1173
1174    event->root_x = cx; /* root_x/y always in screen coords */
1175    event->root_y = cy;
1176    event->root_x_frac = cx_frac;
1177    event->root_y_frac = cy_frac;
1178
1179    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
1180
1181    return num_events;
1182}
1183
1184
1185/**
1186 * Post ProximityIn/ProximityOut events, accompanied by valuators.
1187 *
1188 * events is not NULL-terminated; the return value is the number of events.
1189 * The DDX is responsible for allocating the event structure in the first
1190 * place via GetMaximumEventsNum(), and for freeing it.
1191 */
1192int
1193GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
1194                   int first_valuator, int num_valuators, int *valuators_in)
1195{
1196    int num_events = 1;
1197    DeviceEvent *event;
1198    int valuators[MAX_VALUATORS];
1199
1200    /* refuse events from disabled devices */
1201    if (!pDev->enabled)
1202        return 0;
1203
1204    /* Sanity checks. */
1205    if (type != ProximityIn && type != ProximityOut)
1206        return 0;
1207    if (!pDev->valuator)
1208        return 0;
1209    /* Do we need to send a DeviceValuator event? */
1210    if ((pDev->valuator->mode & 1) == Relative)
1211        num_valuators = 0;
1212
1213    /* You fail. */
1214    if (first_valuator < 0 || num_valuators > MAX_VALUATORS ||
1215        (num_valuators + first_valuator) > pDev->valuator->numAxes)
1216        return 0;
1217
1218    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
1219
1220    event = (DeviceEvent *) events->event;
1221    init_event(pDev, event, GetTimeInMillis());
1222    event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
1223
1224    if (num_valuators) {
1225        memcpy(valuators, valuators_in, num_valuators * sizeof(int));
1226        clipValuators(pDev, first_valuator, num_valuators, valuators);
1227    }
1228
1229    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
1230
1231    return num_events;
1232}
1233
1234/**
1235 * Synthesize a single motion event for the core pointer.
1236 *
1237 * Used in cursor functions, e.g. when cursor confinement changes, and we need
1238 * to shift the pointer to get it inside the new bounds.
1239 */
1240void
1241PostSyntheticMotion(DeviceIntPtr pDev,
1242                    int x,
1243                    int y,
1244                    int screen,
1245                    unsigned long time)
1246{
1247    DeviceEvent ev;
1248
1249#ifdef PANORAMIX
1250    /* Translate back to the sprite screen since processInputProc
1251       will translate from sprite screen to screen 0 upon reentry
1252       to the DIX layer. */
1253    if (!noPanoramiXExtension) {
1254        x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x;
1255        y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y;
1256    }
1257#endif
1258
1259    memset(&ev, 0, sizeof(DeviceEvent));
1260    init_event(pDev, &ev, time);
1261    ev.root_x = x;
1262    ev.root_y = y;
1263    ev.type = ET_Motion;
1264    ev.time = time;
1265
1266    /* FIXME: MD/SD considerations? */
1267    (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev);
1268}
1269