dix: add helper functions to duplicate and free InputAttributes.
No special memory handling is used to give drivers the maximum flexibility with the data. Drivers should be able to call realloc on the product string if needed and perform similar operations. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Dan Nicholson <dbn.lists@gmail.com> Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
bf78e11839
commit
86303a338a
|
@ -331,3 +331,82 @@ int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
|
|||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the InputAttributes in the most obvious way.
|
||||
* No special memory handling is used to give drivers the maximum
|
||||
* flexibility with the data. Drivers should be able to call realloc on the
|
||||
* product string if needed and perform similar operations.
|
||||
*/
|
||||
InputAttributes*
|
||||
DuplicateInputAttributes(InputAttributes *attrs)
|
||||
{
|
||||
InputAttributes *new_attr;
|
||||
int ntags = 0;
|
||||
char **tags, **new_tags;
|
||||
|
||||
if (!attrs)
|
||||
return NULL;
|
||||
|
||||
if (!(new_attr = calloc(1, sizeof(InputAttributes))))
|
||||
goto unwind;
|
||||
|
||||
if (attrs->product && !(new_attr->product = strdup(attrs->product)))
|
||||
goto unwind;
|
||||
if (attrs->vendor && !(new_attr->vendor = strdup(attrs->vendor)))
|
||||
goto unwind;
|
||||
if (attrs->device && !(new_attr->device = strdup(attrs->device)))
|
||||
goto unwind;
|
||||
|
||||
new_attr->flags = attrs->flags;
|
||||
|
||||
if ((tags = attrs->tags))
|
||||
{
|
||||
while(*tags++)
|
||||
ntags++;
|
||||
|
||||
new_attr->tags = calloc(ntags + 1, sizeof(char*));
|
||||
if (!new_attr->tags)
|
||||
goto unwind;
|
||||
|
||||
tags = attrs->tags;
|
||||
new_tags = new_attr->tags;
|
||||
|
||||
while(*tags)
|
||||
{
|
||||
*new_tags = strdup(*tags);
|
||||
if (!*new_tags)
|
||||
goto unwind;
|
||||
|
||||
tags++;
|
||||
new_tags++;
|
||||
}
|
||||
}
|
||||
|
||||
return new_attr;
|
||||
|
||||
unwind:
|
||||
FreeInputAttributes(new_attr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
FreeInputAttributes(InputAttributes *attrs)
|
||||
{
|
||||
char **tags;
|
||||
|
||||
if (!attrs)
|
||||
return;
|
||||
|
||||
free(attrs->product);
|
||||
free(attrs->vendor);
|
||||
free(attrs->device);
|
||||
|
||||
if ((tags = attrs->tags))
|
||||
while(*tags)
|
||||
free(*tags++);
|
||||
|
||||
free(attrs->tags);
|
||||
free(attrs);
|
||||
}
|
||||
|
||||
|
|
|
@ -518,6 +518,8 @@ extern int AllocXTestDevice(ClientPtr client,
|
|||
extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master);
|
||||
extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master);
|
||||
extern void SendDevicePresenceEvent(int deviceid, int type);
|
||||
extern _X_EXPORT InputAttributes *DuplicateInputAttributes(InputAttributes *attrs);
|
||||
extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs);
|
||||
|
||||
/* misc event helpers */
|
||||
extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
|
||||
|
|
102
test/input.c
102
test/input.c
|
@ -771,11 +771,112 @@ static void xi_unregister_handlers(void)
|
|||
|
||||
}
|
||||
|
||||
static void cmp_attr_fields(InputAttributes *attr1,
|
||||
InputAttributes *attr2)
|
||||
{
|
||||
char **tags1, **tags2;
|
||||
|
||||
g_assert(attr1 && attr2);
|
||||
g_assert(attr1 != attr2);
|
||||
g_assert(attr1->flags == attr2->flags);
|
||||
|
||||
if (attr1->product != NULL)
|
||||
{
|
||||
g_assert(attr1->product != attr2->product);
|
||||
g_assert(strcmp(attr1->product, attr2->product) == 0);
|
||||
} else
|
||||
g_assert(attr2->product == NULL);
|
||||
|
||||
if (attr1->vendor != NULL)
|
||||
{
|
||||
g_assert(attr1->vendor != attr2->vendor);
|
||||
g_assert(strcmp(attr1->vendor, attr2->vendor) == 0);
|
||||
} else
|
||||
g_assert(attr2->vendor == NULL);
|
||||
|
||||
if (attr1->device != NULL)
|
||||
{
|
||||
g_assert(attr1->device != attr2->device);
|
||||
g_assert(strcmp(attr1->device, attr2->device) == 0);
|
||||
} else
|
||||
g_assert(attr2->device == NULL);
|
||||
|
||||
tags1 = attr1->tags;
|
||||
tags2 = attr2->tags;
|
||||
if (!tags1)
|
||||
{
|
||||
g_assert(!tags2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for identical content, but duplicated */
|
||||
while (*tags1)
|
||||
{
|
||||
g_assert(*tags1 != *tags2);
|
||||
g_assert(strcmp(*tags1, *tags2) == 0);
|
||||
tags1++;
|
||||
tags2++;
|
||||
}
|
||||
|
||||
g_assert(!*tags2);
|
||||
|
||||
/* check for not sharing memory */
|
||||
tags1 = attr1->tags;
|
||||
while (*tags1)
|
||||
{
|
||||
tags2 = attr2->tags;
|
||||
while (*tags2)
|
||||
g_assert(*tags1 != *tags2++);
|
||||
|
||||
tags1++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dix_input_attributes(void)
|
||||
{
|
||||
InputAttributes orig = {0};
|
||||
InputAttributes *new;
|
||||
char *tags[4] = {"tag1", "tag2", "tag2", NULL};
|
||||
|
||||
new = DuplicateInputAttributes(NULL);
|
||||
g_assert(!new);
|
||||
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
g_assert(memcpy(&orig, new, sizeof(InputAttributes)));
|
||||
|
||||
orig.product = "product name";
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
cmp_attr_fields(&orig, new);
|
||||
FreeInputAttributes(new);
|
||||
|
||||
orig.vendor = "vendor name";
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
cmp_attr_fields(&orig, new);
|
||||
FreeInputAttributes(new);
|
||||
|
||||
orig.device = "device path";
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
cmp_attr_fields(&orig, new);
|
||||
FreeInputAttributes(new);
|
||||
|
||||
orig.flags = 0xF0;
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
cmp_attr_fields(&orig, new);
|
||||
FreeInputAttributes(new);
|
||||
|
||||
orig.tags = tags;
|
||||
new = DuplicateInputAttributes(&orig);
|
||||
cmp_attr_fields(&orig, new);
|
||||
FreeInputAttributes(new);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
g_test_init(&argc, &argv,NULL);
|
||||
g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
|
||||
|
||||
g_test_add_func("/dix/input/attributes", dix_input_attributes);
|
||||
g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
|
||||
g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
|
||||
g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
|
||||
|
@ -784,5 +885,6 @@ int main(int argc, char** argv)
|
|||
g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
|
||||
g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
|
||||
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user