135c4bbdfSmrg/**
235c4bbdfSmrg * Copyright © 2011 Red Hat, Inc.
335c4bbdfSmrg *
435c4bbdfSmrg *  Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg *  copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg *  to deal in the Software without restriction, including without limitation
735c4bbdfSmrg *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg *  and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg *  Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg *  The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg *  paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg *  Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2135c4bbdfSmrg *  DEALINGS IN THE SOFTWARE.
2235c4bbdfSmrg */
2335c4bbdfSmrg
24ed6184dfSmrg/* Test relies on assert() */
25ed6184dfSmrg#undef NDEBUG
26ed6184dfSmrg
2735c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H
2835c4bbdfSmrg#include <dix-config.h>
2935c4bbdfSmrg#endif
3035c4bbdfSmrg
3135c4bbdfSmrg#include <stdint.h>
3235c4bbdfSmrg#include "inputstr.h"
3335c4bbdfSmrg#include "assert.h"
3435c4bbdfSmrg#include "scrnintstr.h"
3535c4bbdfSmrg
361b5d61b8Smrg#include "tests-common.h"
371b5d61b8Smrg
3835c4bbdfSmrgstatic void
3935c4bbdfSmrgtouch_grow_queue(void)
4035c4bbdfSmrg{
4135c4bbdfSmrg    DeviceIntRec dev;
4235c4bbdfSmrg    ValuatorClassRec val;
4335c4bbdfSmrg    TouchClassRec touch;
4435c4bbdfSmrg    size_t size, new_size;
4535c4bbdfSmrg    int i;
4635c4bbdfSmrg
4735c4bbdfSmrg    memset(&dev, 0, sizeof(dev));
4835c4bbdfSmrg    dev.name = xnfstrdup("test device");
4935c4bbdfSmrg    dev.id = 2;
5035c4bbdfSmrg    dev.valuator = &val;
5135c4bbdfSmrg    val.numAxes = 5;
5235c4bbdfSmrg    dev.touch = &touch;
5335c4bbdfSmrg    inputInfo.devices = &dev;
5435c4bbdfSmrg
5535c4bbdfSmrg    size = 5;
5635c4bbdfSmrg
5735c4bbdfSmrg    dev.last.num_touches = size;
5835c4bbdfSmrg    dev.last.touches = calloc(dev.last.num_touches, sizeof(*dev.last.touches));
5935c4bbdfSmrg    assert(dev.last.touches);
6035c4bbdfSmrg    for (i = 0; i < size; i++) {
6135c4bbdfSmrg        dev.last.touches[i].active = TRUE;
6235c4bbdfSmrg        dev.last.touches[i].ddx_id = i;
6335c4bbdfSmrg        dev.last.touches[i].client_id = i * 2;
6435c4bbdfSmrg    }
6535c4bbdfSmrg
661b5d61b8Smrg    /* no more space, should've reallocated and succeeded */
671b5d61b8Smrg    assert(TouchBeginDDXTouch(&dev, 1234) != NULL);
6835c4bbdfSmrg
6935c4bbdfSmrg    new_size = size + size / 2 + 1;
7035c4bbdfSmrg    assert(dev.last.num_touches == new_size);
7135c4bbdfSmrg
7235c4bbdfSmrg    /* make sure we haven't touched those */
7335c4bbdfSmrg    for (i = 0; i < size; i++) {
7435c4bbdfSmrg        DDXTouchPointInfoPtr t = &dev.last.touches[i];
7535c4bbdfSmrg
7635c4bbdfSmrg        assert(t->active == TRUE);
7735c4bbdfSmrg        assert(t->ddx_id == i);
7835c4bbdfSmrg        assert(t->client_id == i * 2);
7935c4bbdfSmrg    }
8035c4bbdfSmrg
811b5d61b8Smrg    assert(dev.last.touches[size].active == TRUE);
821b5d61b8Smrg    assert(dev.last.touches[size].ddx_id == 1234);
831b5d61b8Smrg    assert(dev.last.touches[size].client_id == 1);
841b5d61b8Smrg
8535c4bbdfSmrg    /* make sure those are zero-initialized */
861b5d61b8Smrg    for (i = size + 1; i < new_size; i++) {
8735c4bbdfSmrg        DDXTouchPointInfoPtr t = &dev.last.touches[i];
8835c4bbdfSmrg
8935c4bbdfSmrg        assert(t->active == FALSE);
9035c4bbdfSmrg        assert(t->client_id == 0);
9135c4bbdfSmrg        assert(t->ddx_id == 0);
9235c4bbdfSmrg    }
9335c4bbdfSmrg
9435c4bbdfSmrg    free(dev.name);
9535c4bbdfSmrg}
9635c4bbdfSmrg
9735c4bbdfSmrgstatic void
9835c4bbdfSmrgtouch_find_ddxid(void)
9935c4bbdfSmrg{
10035c4bbdfSmrg    DeviceIntRec dev;
1011b5d61b8Smrg    DDXTouchPointInfoPtr ti, ti2;
10235c4bbdfSmrg    ValuatorClassRec val;
10335c4bbdfSmrg    TouchClassRec touch;
10435c4bbdfSmrg    int size = 5;
10535c4bbdfSmrg    int i;
10635c4bbdfSmrg
10735c4bbdfSmrg    memset(&dev, 0, sizeof(dev));
10835c4bbdfSmrg    dev.name = xnfstrdup("test device");
10935c4bbdfSmrg    dev.id = 2;
11035c4bbdfSmrg    dev.valuator = &val;
11135c4bbdfSmrg    val.numAxes = 5;
11235c4bbdfSmrg    dev.touch = &touch;
11335c4bbdfSmrg    dev.last.num_touches = size;
11435c4bbdfSmrg    dev.last.touches = calloc(dev.last.num_touches, sizeof(*dev.last.touches));
11535c4bbdfSmrg    inputInfo.devices = &dev;
11635c4bbdfSmrg    assert(dev.last.touches);
11735c4bbdfSmrg
11835c4bbdfSmrg    dev.last.touches[0].active = TRUE;
11935c4bbdfSmrg    dev.last.touches[0].ddx_id = 10;
12035c4bbdfSmrg    dev.last.touches[0].client_id = 20;
12135c4bbdfSmrg
12235c4bbdfSmrg    /* existing */
12335c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 10, FALSE);
12435c4bbdfSmrg    assert(ti == &dev.last.touches[0]);
12535c4bbdfSmrg
12635c4bbdfSmrg    /* non-existing */
12735c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 20, FALSE);
12835c4bbdfSmrg    assert(ti == NULL);
12935c4bbdfSmrg
13035c4bbdfSmrg    /* Non-active */
13135c4bbdfSmrg    dev.last.touches[0].active = FALSE;
13235c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 10, FALSE);
13335c4bbdfSmrg    assert(ti == NULL);
13435c4bbdfSmrg
13535c4bbdfSmrg    /* create on number 2 */
13635c4bbdfSmrg    dev.last.touches[0].active = TRUE;
13735c4bbdfSmrg
13835c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 20, TRUE);
13935c4bbdfSmrg    assert(ti == &dev.last.touches[1]);
14035c4bbdfSmrg    assert(ti->active);
14135c4bbdfSmrg    assert(ti->ddx_id == 20);
14235c4bbdfSmrg
14335c4bbdfSmrg    /* set all to active */
14435c4bbdfSmrg    for (i = 0; i < size; i++)
14535c4bbdfSmrg        dev.last.touches[i].active = TRUE;
14635c4bbdfSmrg
1471b5d61b8Smrg    /* Try to create more, succeed */
14835c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 30, TRUE);
1491b5d61b8Smrg    assert(ti != NULL);
1501b5d61b8Smrg    ti2 = TouchFindByDDXID(&dev, 30, TRUE);
1511b5d61b8Smrg    assert(ti == ti2);
1521b5d61b8Smrg    /* make sure we have resized */
1531b5d61b8Smrg    assert(dev.last.num_touches == 8); /* EQ grows from 5 to 8 */
15435c4bbdfSmrg
15535c4bbdfSmrg    /* stop one touchpoint, try to create, succeed */
15635c4bbdfSmrg    dev.last.touches[2].active = FALSE;
1571b5d61b8Smrg    ti = TouchFindByDDXID(&dev, 35, TRUE);
15835c4bbdfSmrg    assert(ti == &dev.last.touches[2]);
15935c4bbdfSmrg    ti = TouchFindByDDXID(&dev, 40, TRUE);
1601b5d61b8Smrg    assert(ti == &dev.last.touches[size+1]);
16135c4bbdfSmrg
16235c4bbdfSmrg    free(dev.name);
16335c4bbdfSmrg}
16435c4bbdfSmrg
16535c4bbdfSmrgstatic void
16635c4bbdfSmrgtouch_begin_ddxtouch(void)
16735c4bbdfSmrg{
16835c4bbdfSmrg    DeviceIntRec dev;
16935c4bbdfSmrg    DDXTouchPointInfoPtr ti;
17035c4bbdfSmrg    ValuatorClassRec val;
17135c4bbdfSmrg    TouchClassRec touch;
17235c4bbdfSmrg    int ddx_id = 123;
17335c4bbdfSmrg    unsigned int last_client_id = 0;
17435c4bbdfSmrg    int size = 5;
17535c4bbdfSmrg
17635c4bbdfSmrg    memset(&dev, 0, sizeof(dev));
17735c4bbdfSmrg    dev.name = xnfstrdup("test device");
17835c4bbdfSmrg    dev.id = 2;
17935c4bbdfSmrg    dev.valuator = &val;
18035c4bbdfSmrg    val.numAxes = 5;
18135c4bbdfSmrg    touch.mode = XIDirectTouch;
18235c4bbdfSmrg    dev.touch = &touch;
18335c4bbdfSmrg    dev.last.num_touches = size;
18435c4bbdfSmrg    dev.last.touches = calloc(dev.last.num_touches, sizeof(*dev.last.touches));
18535c4bbdfSmrg    inputInfo.devices = &dev;
18635c4bbdfSmrg    assert(dev.last.touches);
18735c4bbdfSmrg
18835c4bbdfSmrg    ti = TouchBeginDDXTouch(&dev, ddx_id);
18935c4bbdfSmrg    assert(ti);
19035c4bbdfSmrg    assert(ti->ddx_id == ddx_id);
19135c4bbdfSmrg    /* client_id == ddx_id can happen in real life, but not in this test */
19235c4bbdfSmrg    assert(ti->client_id != ddx_id);
19335c4bbdfSmrg    assert(ti->active);
19435c4bbdfSmrg    assert(ti->client_id > last_client_id);
19535c4bbdfSmrg    assert(ti->emulate_pointer);
19635c4bbdfSmrg    last_client_id = ti->client_id;
19735c4bbdfSmrg
19835c4bbdfSmrg    ddx_id += 10;
19935c4bbdfSmrg    ti = TouchBeginDDXTouch(&dev, ddx_id);
20035c4bbdfSmrg    assert(ti);
20135c4bbdfSmrg    assert(ti->ddx_id == ddx_id);
20235c4bbdfSmrg    /* client_id == ddx_id can happen in real life, but not in this test */
20335c4bbdfSmrg    assert(ti->client_id != ddx_id);
20435c4bbdfSmrg    assert(ti->active);
20535c4bbdfSmrg    assert(ti->client_id > last_client_id);
20635c4bbdfSmrg    assert(!ti->emulate_pointer);
20735c4bbdfSmrg    last_client_id = ti->client_id;
20835c4bbdfSmrg
20935c4bbdfSmrg    free(dev.name);
21035c4bbdfSmrg}
21135c4bbdfSmrg
21235c4bbdfSmrgstatic void
21335c4bbdfSmrgtouch_begin_touch(void)
21435c4bbdfSmrg{
21535c4bbdfSmrg    DeviceIntRec dev;
21635c4bbdfSmrg    TouchClassRec touch;
21735c4bbdfSmrg    ValuatorClassRec val;
21835c4bbdfSmrg    TouchPointInfoPtr ti;
21935c4bbdfSmrg    int touchid = 12434;
22035c4bbdfSmrg    int sourceid = 23;
22135c4bbdfSmrg    SpriteInfoRec sprite;
22235c4bbdfSmrg    ScreenRec screen;
22335c4bbdfSmrg
22435c4bbdfSmrg    screenInfo.screens[0] = &screen;
22535c4bbdfSmrg
22635c4bbdfSmrg    memset(&dev, 0, sizeof(dev));
22735c4bbdfSmrg    dev.name = xnfstrdup("test device");
22835c4bbdfSmrg    dev.id = 2;
22935c4bbdfSmrg
23035c4bbdfSmrg    memset(&sprite, 0, sizeof(sprite));
23135c4bbdfSmrg    dev.spriteInfo = &sprite;
23235c4bbdfSmrg
23335c4bbdfSmrg    memset(&touch, 0, sizeof(touch));
23435c4bbdfSmrg    touch.num_touches = 0;
23535c4bbdfSmrg
23635c4bbdfSmrg    memset(&val, 0, sizeof(val));
23735c4bbdfSmrg    dev.valuator = &val;
23835c4bbdfSmrg    val.numAxes = 2;
23935c4bbdfSmrg
24035c4bbdfSmrg    ti = TouchBeginTouch(&dev, sourceid, touchid, TRUE);
24135c4bbdfSmrg    assert(!ti);
24235c4bbdfSmrg
24335c4bbdfSmrg    dev.touch = &touch;
24435c4bbdfSmrg    ti = TouchBeginTouch(&dev, sourceid, touchid, TRUE);
24535c4bbdfSmrg    assert(ti);
24635c4bbdfSmrg    assert(ti->client_id == touchid);
24735c4bbdfSmrg    assert(ti->active);
24835c4bbdfSmrg    assert(ti->sourceid == sourceid);
24935c4bbdfSmrg    assert(ti->emulate_pointer);
25035c4bbdfSmrg
25135c4bbdfSmrg    assert(touch.num_touches == 1);
25235c4bbdfSmrg
25335c4bbdfSmrg    free(dev.name);
25435c4bbdfSmrg}
25535c4bbdfSmrg
25635c4bbdfSmrgstatic void
25735c4bbdfSmrgtouch_init(void)
25835c4bbdfSmrg{
25935c4bbdfSmrg    DeviceIntRec dev;
26035c4bbdfSmrg    Atom labels[2] = { 0 };
26135c4bbdfSmrg    int rc;
26235c4bbdfSmrg    SpriteInfoRec sprite;
26335c4bbdfSmrg    ScreenRec screen;
26435c4bbdfSmrg
26535c4bbdfSmrg    screenInfo.screens[0] = &screen;
26635c4bbdfSmrg
26735c4bbdfSmrg    memset(&dev, 0, sizeof(dev));
26835c4bbdfSmrg    dev.name = xnfstrdup("test device");
26935c4bbdfSmrg
27035c4bbdfSmrg    memset(&sprite, 0, sizeof(sprite));
27135c4bbdfSmrg    dev.spriteInfo = &sprite;
27235c4bbdfSmrg
27335c4bbdfSmrg    InitAtoms();
27435c4bbdfSmrg    rc = InitTouchClassDeviceStruct(&dev, 1, XIDirectTouch, 2);
27535c4bbdfSmrg    assert(rc == FALSE);
27635c4bbdfSmrg
27735c4bbdfSmrg    InitValuatorClassDeviceStruct(&dev, 2, labels, 10, Absolute);
27835c4bbdfSmrg    rc = InitTouchClassDeviceStruct(&dev, 1, XIDirectTouch, 2);
27935c4bbdfSmrg    assert(rc == TRUE);
28035c4bbdfSmrg    assert(dev.touch);
28135c4bbdfSmrg
28235c4bbdfSmrg    free(dev.name);
28335c4bbdfSmrg}
28435c4bbdfSmrg
28535c4bbdfSmrgint
2861b5d61b8Smrgtouch_test(void)
28735c4bbdfSmrg{
2881b5d61b8Smrg    printf("touch_test: start...\n");
28935c4bbdfSmrg    touch_grow_queue();
29035c4bbdfSmrg    touch_find_ddxid();
29135c4bbdfSmrg    touch_begin_ddxtouch();
29235c4bbdfSmrg    touch_init();
29335c4bbdfSmrg    touch_begin_touch();
29435c4bbdfSmrg
2951b5d61b8Smrg    printf("touch_test: exiting successfully\n");
29635c4bbdfSmrg    return 0;
29735c4bbdfSmrg}
298