Compare commits

..

19 Commits

Author SHA1 Message Date
Enrico Weigelt, metux IT consult
62f01c47f3 (!64) fix struct name clash with Xserver SDK
> /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c: In function 'xf86libinput_set_pressure_range':
> /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c:465:53: warning: declaration of 'range' shadows a global declaration [-Wshadow]
>   465 |                                 const struct range *range)
>       |                                 ~~~~~~~~~~~~~~~~~~~~^~~~~
> In file included from /usr/include/xorg/xf86.h:44,
>                  from /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c:36:
> /usr/include/xorg/xf86str.h:110:3: note: shadowed declaration is here
>   110 | } range;
>       |   ^~~~~

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
d8536737f1 (!66) fix warning on unhandled values
> /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c:2617:9: warning: enumeration value 'LIBINPUT_EVENT_TABLET_PAD_KEY' not handled in switch [-Wswitch]
>  2617 |         switch (type) {
>       |         ^~~~~~
> /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c:2617:9: warning: enumeration value 'LIBINPUT_EVENT_GESTURE_HOLD_BEGIN' not handled in switch [-Wswitch]
> /builds/metux/xf86-input-libinput/_builddir/../src/xf86libinput.c:2617:9: warning: enumeration value 'LIBINPUT_EVENT_GESTURE_HOLD_END' not handled in switch [-Wswitch]

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
c65932fa4a (!68) disable pointless warnings
Add -Wno-declaration-after-statement for suppressing pointless warnings
on declarations after statement.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
7389ff0bda (!69) util-strings: drop unused safe_atou()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
28aa704a2e (!69) util-strings: drop unused zalloc()
Not used anywhere. And crashing the Xserver on alloc failure really
isn't a good idea anyways.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
64ba08fc54 (!69) util-strings: drop unused safe_atoi_base()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
b695a892d3 (!69) util-strings: drop unused safe_atoi()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
b952981d05 (!69) util-strings: drop unused safe_strdup()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
060022b4b3 (!69) util-strings: drop unused strv_join()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
3f1207ebeb (!69) util-strings: drop unused strv_from_argv()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
1ca5d08407 (!69) util-strings: drop unused streq() and strneq()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
7721621c89 (!69) util-strings: drop unused kv_double_from_string()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
8644b2724a (!69) util-strings: drop unused strstrip()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
559204d69b (!69) util-strings: drop unused strendswith()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
1b581c5739 (!69) util-strings: drop unused strstartswith()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
d1984c55d7 (!69) util-strings: drop unused safe_basename()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
ef54aca082 (!69) util-strings: drop unused trunkname()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
40e01ab7be (!69) util-strings: drop unused str_sanitize()
Not used anywhere.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
Enrico Weigelt, metux IT consult
e732b6a8e7 (!69) util-strings: don't crash the Xserver on memory alloc failure
It's only consumer already properly checking for NULL return value,
so can directly use calloc() here, instead of zalloc() which is
crashing the Xserver.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2025-12-09 13:28:53 +01:00
4 changed files with 25 additions and 403 deletions

View File

@@ -43,6 +43,8 @@ m4_ifndef([XORG_MACROS_VERSION],
XORG_MACROS_VERSION(1.8)
XORG_DEFAULT_OPTIONS
CFLAGS="$CFLAGS -Wno-declaration-after-statement"
# Obtain compiler/linker options from server and required extensions
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.19] xproto [inputproto >= 2.2])
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.11.0])

View File

@@ -59,36 +59,6 @@ next_word(const char **state, size_t *len, const char *separators)
return next;
}
/**
* Return a null-terminated string array with the contents of argv
* duplicated.
*
* Use strv_free() to free the array.
*
* @return A null-terminated string array or NULL on errors
*/
char**
strv_from_argv(int argc, char **argv)
{
char **strv = NULL;
assert(argc >= 0);
if (argc == 0)
return NULL;
strv = zalloc((argc + 1) * sizeof *strv);
for (int i = 0; i < argc; i++) {
char *copy = safe_strdup(argv[i]);
if (!copy) {
strv_free(strv);
return NULL;
}
strv[i] = copy;
}
return strv;
}
/**
* Return a null-terminated string array with the tokens in the input
* string, e.g. "one two\tthree" with a separator list of " \t" will return
@@ -122,7 +92,9 @@ strv_from_string(const char *in, const char *separators, size_t *num_elements)
}
size_t strv_len = nelems + 1; /* NULL-terminated */
char **strv = zalloc(strv_len * sizeof *strv);
char **strv = calloc(strv_len, sizeof(*strv));
if (!strv)
return NULL;
size_t idx = 0;
const char *word;
@@ -142,103 +114,3 @@ strv_from_string(const char *in, const char *separators, size_t *num_elements)
return strv;
}
/**
* Return a newly allocated string with all elements joined by the
* joiner, same as Python's string.join() basically.
* A strv of ["one", "two", "three", NULL] with a joiner of ", " results
* in "one, two, three".
*
* An empty strv ([NULL]) returns NULL, same for passing NULL as either
* argument.
*
* @param strv Input string array
* @param joiner Joiner between the elements in the final string
*
* @return A null-terminated string joining all elements
*/
char *
strv_join(char **strv, const char *joiner)
{
char **s;
char *str;
size_t slen = 0;
size_t count = 0;
if (!strv || !joiner)
return NULL;
if (strv[0] == NULL)
return NULL;
for (s = strv, count = 0; *s; s++, count++) {
slen += strlen(*s);
}
assert(slen < 1000);
assert(strlen(joiner) < 1000);
assert(count > 0);
assert(count < 100);
slen += (count - 1) * strlen(joiner);
str = zalloc(slen + 1); /* trailing \0 */
for (s = strv; *s; s++) {
strcat(str, *s);
--count;
if (count > 0)
strcat(str, joiner);
}
return str;
}
/**
* Return a pointer to the basename within filename.
* If the filename the empty string or a directory (i.e. the last char of
* filename is '/') NULL is returned.
*/
const char *
safe_basename(const char *filename)
{
const char *basename;
if (*filename == '\0')
return NULL;
basename = strrchr(filename, '/');
if (basename == NULL)
return filename;
if (*(basename + 1) == '\0')
return NULL;
return basename + 1;
}
/**
* Similar to basename() but returns the trunk only without the (last)
* trailing suffix, so that:
*
* - foo.c returns foo
* - foo.a.b returns foo.a
* - foo returns foo
* - foo/ returns ""
*
* @return an allocated string representing the trunk name of the file
*/
char *
trunkname(const char *filename)
{
const char *base = safe_basename(filename);
char *suffix;
if (base == NULL)
return safe_strdup("");
suffix = rindex(base, '.');
if (suffix == NULL)
return safe_strdup(base);
else
return strndup(base, suffix-base);
}

View File

@@ -43,120 +43,6 @@
#include "util-macros.h"
static inline bool
streq(const char *str1, const char *str2)
{
/* one NULL, one not NULL is always false */
if (str1 && str2)
return strcmp(str1, str2) == 0;
return str1 == str2;
}
static inline bool
strneq(const char *str1, const char *str2, int n)
{
/* one NULL, one not NULL is always false */
if (str1 && str2)
return strncmp(str1, str2, n) == 0;
return str1 == str2;
}
static inline void *
zalloc(size_t size)
{
void *p;
/* We never need to alloc anything more than 1,5 MB so we can assume
* if we ever get above that something's going wrong */
if (size > 1536 * 1024)
assert(!"bug: internal malloc size limit exceeded");
p = calloc(1, size);
if (!p)
abort();
return p;
}
/**
* strdup guaranteed to succeed. If the input string is NULL, the output
* string is NULL. If the input string is a string pointer, we strdup or
* abort on failure.
*/
static inline char*
safe_strdup(const char *str)
{
char *s;
if (!str)
return NULL;
s = strdup(str);
if (!s)
abort();
return s;
}
static inline bool
safe_atoi_base(const char *str, int *val, int base)
{
char *endptr;
long v;
assert(base == 10 || base == 16 || base == 8);
errno = 0;
v = strtol(str, &endptr, base);
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if (v > INT_MAX || v < INT_MIN)
return false;
*val = v;
return true;
}
static inline bool
safe_atoi(const char *str, int *val)
{
return safe_atoi_base(str, val, 10);
}
static inline bool
safe_atou_base(const char *str, unsigned int *val, int base)
{
char *endptr;
unsigned long v;
assert(base == 10 || base == 16 || base == 8);
errno = 0;
v = strtoul(str, &endptr, base);
if (errno > 0)
return false;
if (str == endptr)
return false;
if (*str != '\0' && *endptr != '\0')
return false;
if ((long)v < 0)
return false;
*val = v;
return true;
}
static inline bool
safe_atou(const char *str, unsigned int *val)
{
return safe_atou_base(str, val, 10);
}
static inline bool
safe_atod(const char *str, double *val)
{
@@ -211,9 +97,7 @@ safe_atod(const char *str, double *val)
return true;
}
char **strv_from_argv(int argc, char **argv);
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
char *strv_join(char **strv, const char *joiner);
static inline void
strv_free(char **strv) {
@@ -253,7 +137,10 @@ double_array_from_string(const char *in,
if(!strv)
return result;
double *numv = zalloc(sizeof(double) * nelem);
double *numv = calloc(nelem, sizeof(double));
if (!numv)
goto out;
for (size_t idx = 0; idx < nelem; idx++) {
double val;
if (!safe_atod(strv[idx], &val))
@@ -271,150 +158,3 @@ out:
free(numv);
return result;
}
struct key_value_str{
char *key;
char *value;
};
struct key_value_double {
double key;
double value;
};
static inline ssize_t
kv_double_from_string(const char *string,
const char *pair_separator,
const char *kv_separator,
struct key_value_double **result_out)
{
struct key_value_double *result = NULL;
if (!pair_separator || pair_separator[0] == '\0' ||
!kv_separator || kv_separator[0] == '\0')
return -1;
size_t npairs;
char **pairs = strv_from_string(string, pair_separator, &npairs);
if (!pairs || npairs == 0)
goto error;
result = zalloc(npairs * sizeof *result);
for (size_t idx = 0; idx < npairs; idx++) {
char *pair = pairs[idx];
size_t nelem;
char **kv = strv_from_string(pair, kv_separator, &nelem);
double k, v;
if (!kv || nelem != 2 ||
!safe_atod(kv[0], &k) ||
!safe_atod(kv[1], &v)) {
strv_free(kv);
goto error;
}
result[idx].key = k;
result[idx].value = v;
strv_free(kv);
}
strv_free(pairs);
*result_out = result;
return npairs;
error:
strv_free(pairs);
free(result);
return -1;
}
/**
* Strip any of the characters in what from the beginning and end of the
* input string.
*
* @return a newly allocated string with none of "what" at the beginning or
* end of string
*/
static inline char *
strstrip(const char *input, const char *what)
{
char *str, *last;
str = safe_strdup(&input[strspn(input, what)]);
last = str;
for (char *c = str; *c != '\0'; c++) {
if (!strchr(what, *c))
last = c + 1;
}
*last = '\0';
return str;
}
/**
* Return true if str ends in suffix, false otherwise. If the suffix is the
* empty string, strendswith() always returns false.
*/
static inline bool
strendswith(const char *str, const char *suffix)
{
size_t slen = strlen(str);
size_t suffixlen = strlen(suffix);
size_t offset;
if (slen == 0 || suffixlen == 0 || suffixlen > slen)
return false;
offset = slen - suffixlen;
return strneq(&str[offset], suffix, suffixlen);
}
static inline bool
strstartswith(const char *str, const char *prefix)
{
size_t prefixlen = strlen(prefix);
return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
}
const char *
safe_basename(const char *filename);
char *
trunkname(const char *filename);
/**
* Return a copy of str with all % converted to %% to make the string
* acceptable as printf format.
*/
static inline char *
str_sanitize(const char *str)
{
if (!str)
return NULL;
if (!strchr(str, '%'))
return strdup(str);
size_t slen = min(strlen(str), 512);
char *sanitized = zalloc(2 * slen + 1);
const char *src = str;
char *dst = sanitized;
for (size_t i = 0; i < slen; i++) {
if (*src == '%')
*dst++ = '%';
*dst++ = *src++;
}
*dst = '\0';
return sanitized;
}

View File

@@ -141,6 +141,10 @@ struct accel_points {
};
#endif
struct xf86libinput_pressure_range {
float min, max;
};
struct xf86libinput {
InputInfoPtr pInfo;
char *path;
@@ -199,9 +203,7 @@ struct xf86libinput {
float rotation_angle;
struct bezier_control_point pressurecurve[4];
struct range {
float min, max;
} pressure_range;
struct xf86libinput_pressure_range pressure_range;
struct ratio {
int x, y;
} area;
@@ -467,7 +469,7 @@ xf86libinput_set_pressurecurve(struct xf86libinput *driver_data,
static inline bool
xf86libinput_set_pressure_range(struct xf86libinput *driver_data,
const struct range *rangeopt)
const struct xf86libinput_pressure_range *rangeopt)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
@@ -939,7 +941,7 @@ LibinputApplyConfigPressureRange(DeviceIntPtr dev,
#if HAVE_LIBINPUT_PRESSURE_RANGE
InputInfoPtr pInfo = dev->public.devicePrivate;
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
struct range *rangeopt = &driver_data->options.pressure_range;
struct xf86libinput_pressure_range *rangeopt = &driver_data->options.pressure_range;
if (!subdevice_has_capabilities(dev, CAP_TABLET_TOOL))
return;
@@ -2739,6 +2741,12 @@ xf86libinput_handle_event(struct libinput_event *event)
break;
case LIBINPUT_EVENT_SWITCH_TOGGLE:
break;
// new libinput events we don't handle yet
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
case LIBINPUT_EVENT_GESTURE_HOLD_END:
case LIBINPUT_EVENT_TABLET_PAD_KEY:
break;
}
out:
@@ -3685,7 +3693,7 @@ out:
static void
xf86libinput_parse_pressure_range_option(InputInfoPtr pInfo,
struct xf86libinput *driver_data,
struct range *rangeopt)
struct xf86libinput_pressure_range *rangeopt)
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
@@ -5384,7 +5392,7 @@ LibinputSetPropertyPressureRange(DeviceIntPtr dev,
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
float *vals;
struct range rangeopt = { 0.0, 1.0 };
struct xf86libinput_pressure_range rangeopt = { 0.0, 1.0 };
if (val->format != 32 || val->size != 2 || val->type != prop_float)
return BadMatch;
@@ -6663,7 +6671,7 @@ LibinputInitPressureRangeProperty(DeviceIntPtr dev,
{
#if HAVE_LIBINPUT_PRESSURE_RANGE
struct libinput_tablet_tool *tool = driver_data->tablet_tool;
const struct range *rangeopt = &driver_data->options.pressure_range;
const struct xf86libinput_pressure_range *rangeopt = &driver_data->options.pressure_range;
float data[2] = {
rangeopt->min,
rangeopt->max,