mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
Add support for signed 24.8 decimal numbers
'fixed' is a signed decimal type which offers a sign bit, 23 bits of integer precision, and 8 bits of decimal precision. This is exposed as an opaque struct with conversion helpers to and from double and int on the C API side. Signed-off-by: Daniel Stone <daniel@fooishbar.org>
This commit is contained in:
parent
c49f632dae
commit
c5aba11acc
6 changed files with 81 additions and 3 deletions
|
|
@ -18,7 +18,7 @@ libwayland_util_la_SOURCES = \
|
||||||
wayland-os.h \
|
wayland-os.h \
|
||||||
wayland-private.h
|
wayland-private.h
|
||||||
|
|
||||||
libwayland_server_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt
|
libwayland_server_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
|
||||||
libwayland_server_la_SOURCES = \
|
libwayland_server_la_SOURCES = \
|
||||||
wayland-protocol.c \
|
wayland-protocol.c \
|
||||||
wayland-server.c \
|
wayland-server.c \
|
||||||
|
|
@ -26,7 +26,7 @@ libwayland_server_la_SOURCES = \
|
||||||
data-device.c \
|
data-device.c \
|
||||||
event-loop.c
|
event-loop.c
|
||||||
|
|
||||||
libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt
|
libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
|
||||||
libwayland_client_la_SOURCES = \
|
libwayland_client_la_SOURCES = \
|
||||||
wayland-protocol.c \
|
wayland-protocol.c \
|
||||||
wayland-client.c
|
wayland-client.c
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -428,6 +429,13 @@ wl_closure_vmarshal(struct wl_closure *closure,
|
||||||
|
|
||||||
for (i = 2; i < count; i++) {
|
for (i = 2; i < count; i++) {
|
||||||
switch (message->signature[i - 2]) {
|
switch (message->signature[i - 2]) {
|
||||||
|
case 'f':
|
||||||
|
closure->types[i] = &ffi_type_sint32;
|
||||||
|
closure->args[i] = p;
|
||||||
|
if (end - p < 1)
|
||||||
|
goto err;
|
||||||
|
*p++ = va_arg(ap, wl_fixed_t);
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
closure->types[i] = &ffi_type_uint32;
|
closure->types[i] = &ffi_type_uint32;
|
||||||
closure->args[i] = p;
|
closure->args[i] = p;
|
||||||
|
|
@ -611,6 +619,10 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
closure->types[i] = &ffi_type_sint32;
|
closure->types[i] = &ffi_type_sint32;
|
||||||
closure->args[i] = p++;
|
closure->args[i] = p++;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
closure->types[i] = &ffi_type_sint32;
|
||||||
|
closure->args[i] = p++;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
closure->types[i] = &ffi_type_pointer;
|
closure->types[i] = &ffi_type_pointer;
|
||||||
length = *p++;
|
length = *p++;
|
||||||
|
|
@ -812,6 +824,7 @@ void
|
||||||
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
|
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
|
||||||
{
|
{
|
||||||
union wl_value *value;
|
union wl_value *value;
|
||||||
|
int32_t si;
|
||||||
int i;
|
int i;
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
unsigned int time;
|
unsigned int time;
|
||||||
|
|
@ -835,7 +848,12 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
|
||||||
fprintf(stderr, "%u", value->uint32);
|
fprintf(stderr, "%u", value->uint32);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
fprintf(stderr, "%d", value->uint32);
|
si = (int32_t) value->uint32;
|
||||||
|
fprintf(stderr, "%d", si);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
si = (int32_t) value->uint32;
|
||||||
|
fprintf(stderr, "%f", (double) si / 256.0);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
fprintf(stderr, "\"%s\"", value->string);
|
fprintf(stderr, "\"%s\"", value->string);
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ enum arg_type {
|
||||||
NEW_ID,
|
NEW_ID,
|
||||||
INT,
|
INT,
|
||||||
UNSIGNED,
|
UNSIGNED,
|
||||||
|
FIXED,
|
||||||
STRING,
|
STRING,
|
||||||
OBJECT,
|
OBJECT,
|
||||||
ARRAY,
|
ARRAY,
|
||||||
|
|
@ -334,6 +335,8 @@ start_element(void *data, const char *element_name, const char **atts)
|
||||||
arg->type = INT;
|
arg->type = INT;
|
||||||
else if (strcmp(type, "uint") == 0)
|
else if (strcmp(type, "uint") == 0)
|
||||||
arg->type = UNSIGNED;
|
arg->type = UNSIGNED;
|
||||||
|
else if (strcmp(type, "fixed") == 0)
|
||||||
|
arg->type = FIXED;
|
||||||
else if (strcmp(type, "string") == 0)
|
else if (strcmp(type, "string") == 0)
|
||||||
arg->type = STRING;
|
arg->type = STRING;
|
||||||
else if (strcmp(type, "array") == 0)
|
else if (strcmp(type, "array") == 0)
|
||||||
|
|
@ -484,6 +487,9 @@ emit_type(struct arg *a)
|
||||||
case UNSIGNED:
|
case UNSIGNED:
|
||||||
printf("uint32_t ");
|
printf("uint32_t ");
|
||||||
break;
|
break;
|
||||||
|
case FIXED:
|
||||||
|
printf("wl_fixed_t ");
|
||||||
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
printf("const char *");
|
printf("const char *");
|
||||||
break;
|
break;
|
||||||
|
|
@ -972,6 +978,9 @@ emit_messages(struct wl_list *message_list,
|
||||||
case UNSIGNED:
|
case UNSIGNED:
|
||||||
printf("u");
|
printf("u");
|
||||||
break;
|
break;
|
||||||
|
case FIXED:
|
||||||
|
printf("f");
|
||||||
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
printf("s");
|
printf("s");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ struct wl_input_device {
|
||||||
* The variable arguments' types are:
|
* The variable arguments' types are:
|
||||||
* - type=uint: uint32_t
|
* - type=uint: uint32_t
|
||||||
* - type=int: int32_t
|
* - type=int: int32_t
|
||||||
|
* - type=fixed: wl_fixed_t
|
||||||
* - type=string: (const char *) to a nil-terminated string
|
* - type=string: (const char *) to a nil-terminated string
|
||||||
* - type=array: (struct wl_array *)
|
* - type=array: (struct wl_array *)
|
||||||
* - type=fd: int, that is an open file descriptor
|
* - type=fd: int, that is an open file descriptor
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
@ -165,6 +166,29 @@ void wl_array_release(struct wl_array *array);
|
||||||
void *wl_array_add(struct wl_array *array, size_t size);
|
void *wl_array_add(struct wl_array *array, size_t size);
|
||||||
void wl_array_copy(struct wl_array *array, struct wl_array *source);
|
void wl_array_copy(struct wl_array *array, struct wl_array *source);
|
||||||
|
|
||||||
|
typedef int32_t wl_fixed_t;
|
||||||
|
#define WL_FIXED_INVALID_VALUE ~0L
|
||||||
|
|
||||||
|
static inline double wl_fixed_to_double(wl_fixed_t f)
|
||||||
|
{
|
||||||
|
return (double) f / 256.0;
|
||||||
|
};
|
||||||
|
static inline wl_fixed_t wl_fixed_from_double(double d)
|
||||||
|
{
|
||||||
|
if (d >= (1 << 23))
|
||||||
|
return WL_FIXED_INVALID_VALUE;
|
||||||
|
return (wl_fixed_t) round (d * 256.0);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int wl_fixed_to_int(wl_fixed_t f)
|
||||||
|
{
|
||||||
|
return f / 256;
|
||||||
|
}
|
||||||
|
static inline wl_fixed_t wl_fixed_from_int(int i)
|
||||||
|
{
|
||||||
|
return wl_fixed_from_double(i);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
* OF THIS SOFTWARE.
|
* OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -287,6 +288,13 @@ validate_demarshal_h(struct marshal_data *data,
|
||||||
close(data->value.h);
|
close(data->value.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
validate_demarshal_f(struct marshal_data *data,
|
||||||
|
struct wl_object *object, wl_fixed_t f)
|
||||||
|
{
|
||||||
|
assert(data->value.i == f);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demarshal(struct marshal_data *data, const char *format,
|
demarshal(struct marshal_data *data, const char *format,
|
||||||
uint32_t *msg, void (*func)(void))
|
uint32_t *msg, void (*func)(void))
|
||||||
|
|
@ -335,6 +343,12 @@ TEST(connection_demarshal)
|
||||||
memcpy(&msg[3], data.value.s, msg[2]);
|
memcpy(&msg[3], data.value.s, msg[2]);
|
||||||
demarshal(&data, "s", msg, (void *) validate_demarshal_s);
|
demarshal(&data, "s", msg, (void *) validate_demarshal_s);
|
||||||
|
|
||||||
|
data.value.i = wl_fixed_from_double(-90000.2390);
|
||||||
|
msg[0] = 400200;
|
||||||
|
msg[1] = 12;
|
||||||
|
msg[2] = data.value.i;
|
||||||
|
demarshal(&data, "f", msg, (void *) validate_demarshal_f);
|
||||||
|
|
||||||
release_marshal_data(&data);
|
release_marshal_data(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,6 +414,18 @@ TEST(connection_marshal_demarshal)
|
||||||
marshal_demarshal(&data, (void *) validate_demarshal_h,
|
marshal_demarshal(&data, (void *) validate_demarshal_h,
|
||||||
8, "h", data.value.h);
|
8, "h", data.value.h);
|
||||||
|
|
||||||
|
data.value.i = wl_fixed_from_double(1234.5678);
|
||||||
|
marshal_demarshal(&data, (void *) validate_demarshal_f,
|
||||||
|
12, "f", data.value.i);
|
||||||
|
|
||||||
|
data.value.i = wl_fixed_from_double(-90000.2390);
|
||||||
|
marshal_demarshal(&data, (void *) validate_demarshal_f,
|
||||||
|
12, "f", data.value.i);
|
||||||
|
|
||||||
|
data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
|
||||||
|
marshal_demarshal(&data, (void *) validate_demarshal_f,
|
||||||
|
12, "f", data.value.i);
|
||||||
|
|
||||||
release_marshal_data(&data);
|
release_marshal_data(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue