forked from drath/libratbag
For protocol debugging, it's a lot easier to go have a simple helper than having to go through the whole of libratbag. And remove the page-dump helper from the main code. Note that this tool needs a /dev/hidraw device directly, not an event node. It is a debugging tool after all. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
204 lines
5.2 KiB
C
204 lines
5.2 KiB
C
/*
|
|
* Copyright © 2008 Kristian Høgsberg
|
|
* Copyright © 2013-2015 Red Hat, Inc.
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice appear in supporting documentation, and
|
|
* that the name of the copyright holders not be used in advertising or
|
|
* publicity pertaining to distribution of the software without specific,
|
|
* written prior permission. The copyright holders make no representations
|
|
* about the suitability of this software for any purpose. It is provided "as
|
|
* is" without express or implied warranty.
|
|
*
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
* OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#ifndef LIBRATBAG_UTIL_H
|
|
#define LIBRATBAG_UTIL_H
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <libudev.h>
|
|
|
|
/*
|
|
* This list data structure is a verbatim copy from wayland-util.h from the
|
|
* Wayland project; except that wl_ prefix has been removed.
|
|
*/
|
|
|
|
struct list {
|
|
struct list *prev;
|
|
struct list *next;
|
|
};
|
|
|
|
void list_init(struct list *list);
|
|
void list_insert(struct list *list, struct list *elm);
|
|
void list_remove(struct list *elm);
|
|
int list_empty(const struct list *list);
|
|
|
|
#ifdef __GNUC__
|
|
#define container_of(ptr, sample, member) \
|
|
(__typeof__(sample))((char *)(ptr) - \
|
|
((char *)&(sample)->member - (char *)(sample)))
|
|
#else
|
|
#define container_of(ptr, sample, member) \
|
|
(void *)((char *)(ptr) - \
|
|
((char *)&(sample)->member - (char *)(sample)))
|
|
#endif
|
|
|
|
#define list_for_each(pos, head, member) \
|
|
for (pos = 0, pos = container_of((head)->next, pos, member); \
|
|
&pos->member != (head); \
|
|
pos = container_of(pos->member.next, pos, member))
|
|
|
|
#define list_for_each_safe(pos, tmp, head, member) \
|
|
for (pos = 0, tmp = 0, \
|
|
pos = container_of((head)->next, pos, member), \
|
|
tmp = container_of((pos)->member.next, tmp, member); \
|
|
&pos->member != (head); \
|
|
pos = tmp, \
|
|
tmp = container_of(pos->member.next, tmp, member))
|
|
|
|
#define LONG_BITS (sizeof(long) * 8)
|
|
#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
|
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
|
#define ARRAY_FOR_EACH(_arr, _elem) \
|
|
for (size_t _i = 0; _i < ARRAY_LENGTH(_arr) && (_elem = &_arr[_i]); _i++)
|
|
#define AS_MASK(v) (1 << (v))
|
|
|
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
|
#define streq(s1, s2) (strcmp((s1), (s2)) == 0)
|
|
#define strneq(s1, s2, n) (strncmp((s1), (s2), (n)) == 0)
|
|
|
|
static inline void
|
|
cleanup_free(void *p) {
|
|
free(*(void**)p);
|
|
}
|
|
|
|
static inline void
|
|
cleanup_close(int *p) {
|
|
close(*p);
|
|
}
|
|
static inline void
|
|
cleanup_udev_unref(struct udev **udev) {
|
|
if (*udev)
|
|
udev_unref(*udev);
|
|
}
|
|
|
|
static inline void
|
|
cleanup_udev_device_unref(struct udev_device **udev_device) {
|
|
if (*udev_device)
|
|
udev_device_unref(*udev_device);
|
|
}
|
|
|
|
#define _cleanup_(x) __attribute__((cleanup(x)))
|
|
#define _cleanup_free_ _cleanup_(cleanup_free)
|
|
#define _cleanup_close_ _cleanup_(cleanup_close)
|
|
#define _cleanup_udev_unref_ _cleanup_(cleanup_udev_unref)
|
|
#define _cleanup_udev_device_unref_ _cleanup_(cleanup_udev_device_unref)
|
|
|
|
static inline char*
|
|
strncpy_safe(char *dest, const char *src, size_t n)
|
|
{
|
|
strncpy(dest, src, n);
|
|
dest[n - 1] = '\0';
|
|
return dest;
|
|
}
|
|
|
|
#define LIBRATBAG_EXPORT __attribute__ ((visibility("default")))
|
|
|
|
static inline void *
|
|
zalloc(size_t size)
|
|
{
|
|
void *p = calloc(1, size);
|
|
|
|
if (!p)
|
|
abort();
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
* returns NULL if str is NULL, otherwise guarantees a successful strdup.
|
|
*/
|
|
static inline char *
|
|
strdup_safe(const char *str)
|
|
{
|
|
char *s;
|
|
|
|
if (!str)
|
|
return NULL;
|
|
|
|
s = strdup(str);
|
|
if (!s)
|
|
abort();
|
|
|
|
return s;
|
|
}
|
|
|
|
static inline int
|
|
snprintf_safe(char *buf, size_t n, const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
int rc;
|
|
|
|
va_start(args, fmt);
|
|
rc = vsnprintf(buf, n, fmt, args);
|
|
va_end(args);
|
|
|
|
if (rc < 0 || n < (size_t)rc)
|
|
abort();
|
|
|
|
return rc;
|
|
}
|
|
|
|
#define sprintf_safe(buf, fmt, ...) \
|
|
snprintf_safe(buf, ARRAY_LENGTH(buf), fmt, __VA_ARGS__)
|
|
|
|
static inline void
|
|
msleep(unsigned int ms)
|
|
{
|
|
usleep(ms * 1000);
|
|
}
|
|
|
|
static inline int
|
|
long_bit_is_set(const unsigned long *array, int bit)
|
|
{
|
|
return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
|
|
}
|
|
|
|
static inline void
|
|
long_set_bit(unsigned long *array, int bit)
|
|
{
|
|
array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
|
|
}
|
|
|
|
static inline void
|
|
long_clear_bit(unsigned long *array, int bit)
|
|
{
|
|
array[bit / LONG_BITS] &= ~(1LL << (bit % LONG_BITS));
|
|
}
|
|
|
|
static inline void
|
|
long_set_bit_state(unsigned long *array, int bit, int state)
|
|
{
|
|
if (state)
|
|
long_set_bit(array, bit);
|
|
else
|
|
long_clear_bit(array, bit);
|
|
}
|
|
|
|
const char *
|
|
udev_prop_value(struct udev_device *device,
|
|
const char *property_name);
|
|
#endif /* LIBRATBAG_UTIL_H */
|