mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -07:00
Add some ugly events to setsu
This commit is contained in:
parent
092355ff00
commit
aabb305eef
3 changed files with 187 additions and 16 deletions
|
@ -19,9 +19,26 @@
|
||||||
#define _SETSU_H
|
#define _SETSU_H
|
||||||
|
|
||||||
typedef struct setsu_t Setsu;
|
typedef struct setsu_t Setsu;
|
||||||
|
typedef struct setsu_device_t SetsuDevice;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SETSU_EVENT_DOWN,
|
||||||
|
SETSU_EVENT_UP,
|
||||||
|
SETSU_EVENT_POSITION_X,
|
||||||
|
SETSU_EVENT_POSITION_Y
|
||||||
|
} SetsuEventType;
|
||||||
|
|
||||||
|
typedef struct setsu_event_t {
|
||||||
|
SetsuDevice *dev;
|
||||||
|
unsigned int tracking_id;
|
||||||
|
SetsuEventType type;
|
||||||
|
unsigned int value;
|
||||||
|
} SetsuEvent;
|
||||||
|
|
||||||
|
typedef void (*SetsuEventCb)(SetsuEvent *event, void *user);
|
||||||
|
|
||||||
Setsu *setsu_new();
|
Setsu *setsu_new();
|
||||||
void setsu_free(Setsu *setsu);
|
void setsu_free(Setsu *setsu);
|
||||||
void setsu_poll(Setsu *setsu);
|
void setsu_poll(Setsu *setsu, SetsuEventCb cb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#define SETSU_LOG(...) fprintf(stderr, __VA_ARGS__)
|
#define SETSU_LOG(...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define SLOTS_COUNT 16
|
||||||
|
|
||||||
typedef struct setsu_device_t
|
typedef struct setsu_device_t
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,12 @@ typedef struct setsu_device_t
|
||||||
char *path;
|
char *path;
|
||||||
int fd;
|
int fd;
|
||||||
struct libevdev *evdev;
|
struct libevdev *evdev;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool down;
|
||||||
|
unsigned int tracking_id;
|
||||||
|
} slots[SLOTS_COUNT];
|
||||||
|
unsigned int slot_cur;
|
||||||
} SetsuDevice;
|
} SetsuDevice;
|
||||||
|
|
||||||
struct setsu_t
|
struct setsu_t
|
||||||
|
@ -53,8 +60,8 @@ static void scan(Setsu *setsu);
|
||||||
static void update_device(Setsu *setsu, struct udev_device *dev, bool added);
|
static void update_device(Setsu *setsu, struct udev_device *dev, bool added);
|
||||||
static SetsuDevice *connect(Setsu *setsu, const char *path);
|
static SetsuDevice *connect(Setsu *setsu, const char *path);
|
||||||
static void disconnect(Setsu *setsu, SetsuDevice *dev);
|
static void disconnect(Setsu *setsu, SetsuDevice *dev);
|
||||||
static void poll_device(Setsu *setsu, SetsuDevice *dev);
|
static void poll_device(Setsu *setsu, SetsuDevice *dev, SetsuEventCb cb);
|
||||||
static void device_event(Setsu *setsu, SetsuDevice *dev, struct input_event *ev);
|
static void device_event(Setsu *setsu, SetsuDevice *dev, struct input_event *ev, SetsuEventCb cb);
|
||||||
|
|
||||||
Setsu *setsu_new()
|
Setsu *setsu_new()
|
||||||
{
|
{
|
||||||
|
@ -166,10 +173,9 @@ static void update_device(Setsu *setsu, struct udev_device *dev, bool added)
|
||||||
|
|
||||||
static SetsuDevice *connect(Setsu *setsu, const char *path)
|
static SetsuDevice *connect(Setsu *setsu, const char *path)
|
||||||
{
|
{
|
||||||
SetsuDevice *dev = malloc(sizeof(SetsuDevice));
|
SetsuDevice *dev = calloc(1, sizeof(SetsuDevice));
|
||||||
if(!dev)
|
if(!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
memset(dev, 0, sizeof(*dev));
|
|
||||||
dev->fd = -1;
|
dev->fd = -1;
|
||||||
dev->path = strdup(path);
|
dev->path = strdup(path);
|
||||||
if(!dev->path)
|
if(!dev->path)
|
||||||
|
@ -182,7 +188,12 @@ static SetsuDevice *connect(Setsu *setsu, const char *path)
|
||||||
if(libevdev_new_from_fd(dev->fd, &dev->evdev) < 0)
|
if(libevdev_new_from_fd(dev->fd, &dev->evdev) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
SETSU_LOG("connected to %s\n", libevdev_get_name(dev->evdev));
|
// TODO: expose these values:
|
||||||
|
int min_x = libevdev_get_abs_minimum(dev->evdev, ABS_X);
|
||||||
|
int min_y = libevdev_get_abs_minimum(dev->evdev, ABS_Y);
|
||||||
|
int max_x = libevdev_get_abs_maximum(dev->evdev, ABS_X);
|
||||||
|
int max_y = libevdev_get_abs_maximum(dev->evdev, ABS_Y);
|
||||||
|
SETSU_LOG("connected to %s: %d %d -> %d %d\n", libevdev_get_name(dev->evdev), min_x, min_y, max_x, max_y);
|
||||||
|
|
||||||
dev->next = setsu->dev;
|
dev->next = setsu->dev;
|
||||||
setsu->dev = dev;
|
setsu->dev = dev;
|
||||||
|
@ -217,13 +228,13 @@ static void disconnect(Setsu *setsu, SetsuDevice *dev)
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setsu_poll(Setsu *setsu)
|
void setsu_poll(Setsu *setsu, SetsuEventCb cb)
|
||||||
{
|
{
|
||||||
for(SetsuDevice *dev = setsu->dev; dev; dev = dev->next)
|
for(SetsuDevice *dev = setsu->dev; dev; dev = dev->next)
|
||||||
poll_device(setsu, dev);
|
poll_device(setsu, dev, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void poll_device(Setsu *setsu, SetsuDevice *dev)
|
static void poll_device(Setsu *setsu, SetsuDevice *dev, SetsuEventCb cb)
|
||||||
{
|
{
|
||||||
bool sync = false;
|
bool sync = false;
|
||||||
while(true)
|
while(true)
|
||||||
|
@ -240,7 +251,7 @@ static void poll_device(Setsu *setsu, SetsuDevice *dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(r == LIBEVDEV_READ_STATUS_SUCCESS || (sync && r == LIBEVDEV_READ_STATUS_SYNC))
|
if(r == LIBEVDEV_READ_STATUS_SUCCESS || (sync && r == LIBEVDEV_READ_STATUS_SYNC))
|
||||||
device_event(setsu, dev, &ev);
|
device_event(setsu, dev, &ev, cb);
|
||||||
else if(r == LIBEVDEV_READ_STATUS_SYNC)
|
else if(r == LIBEVDEV_READ_STATUS_SYNC)
|
||||||
sync = true;
|
sync = true;
|
||||||
else
|
else
|
||||||
|
@ -251,11 +262,50 @@ static void poll_device(Setsu *setsu, SetsuDevice *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_event(Setsu *setsu, SetsuDevice *dev, struct input_event *ev)
|
static void send_event(Setsu *setsu, SetsuDevice *dev, SetsuEventCb cb, SetsuEventType type, unsigned int value)
|
||||||
{
|
{
|
||||||
printf("Event: %s %s %d\n",
|
SetsuEvent event;
|
||||||
libevdev_event_type_get_name(ev->type),
|
event.dev = dev;
|
||||||
libevdev_event_code_get_name(ev->type, ev->code),
|
event.tracking_id = dev->slots[dev->slot_cur].tracking_id;
|
||||||
ev->value);
|
event.type = type;
|
||||||
|
event.value = value;
|
||||||
|
cb(&event, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void device_event(Setsu *setsu, SetsuDevice *dev, struct input_event *ev, SetsuEventCb cb)
|
||||||
|
{
|
||||||
|
if(ev->type == EV_ABS)
|
||||||
|
{
|
||||||
|
switch(ev->code)
|
||||||
|
{
|
||||||
|
case ABS_MT_SLOT:
|
||||||
|
if((unsigned int)ev->value >= SLOTS_COUNT)
|
||||||
|
{
|
||||||
|
SETSU_LOG("slot too high\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dev->slot_cur = ev->value;
|
||||||
|
break;
|
||||||
|
case ABS_MT_TRACKING_ID:
|
||||||
|
if(ev->value == -1)
|
||||||
|
{
|
||||||
|
dev->slots[dev->slot_cur].down = false;
|
||||||
|
send_event(setsu, dev, cb, SETSU_EVENT_UP, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dev->slots[dev->slot_cur].down = true;
|
||||||
|
dev->slots[dev->slot_cur].tracking_id = ev->value;
|
||||||
|
send_event(setsu, dev, cb, SETSU_EVENT_DOWN, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ABS_MT_POSITION_X:
|
||||||
|
send_event(setsu, dev, cb, SETSU_EVENT_POSITION_X, ev->value);
|
||||||
|
break;
|
||||||
|
case ABS_MT_POSITION_Y:
|
||||||
|
send_event(setsu, dev, cb, SETSU_EVENT_POSITION_Y, ev->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,24 +19,128 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
Setsu *setsu;
|
Setsu *setsu;
|
||||||
|
|
||||||
|
#define WIDTH 1920
|
||||||
|
#define HEIGHT 942
|
||||||
|
#define TOUCHES_MAX 8
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool down;
|
||||||
|
unsigned int tracking_id;
|
||||||
|
unsigned int x, y;
|
||||||
|
} touches[TOUCHES_MAX];
|
||||||
|
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
void quit()
|
void quit()
|
||||||
{
|
{
|
||||||
setsu_free(setsu);
|
setsu_free(setsu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_state()
|
||||||
|
{
|
||||||
|
for(size_t i=0; i<TOUCHES_MAX; i++)
|
||||||
|
{
|
||||||
|
if(touches[i].down)
|
||||||
|
{
|
||||||
|
// printf("%8u, %8u\n", touches[i].x, touches[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCALE 16
|
||||||
|
char buf[(1 + WIDTH/SCALE)*(HEIGHT/SCALE) + 1];
|
||||||
|
size_t i = 0;
|
||||||
|
for(size_t y=0; y<HEIGHT/SCALE; y++)
|
||||||
|
{
|
||||||
|
for(size_t x=0; x<WIDTH/SCALE; x++)
|
||||||
|
{
|
||||||
|
for(size_t t=0; t<TOUCHES_MAX; t++)
|
||||||
|
{
|
||||||
|
if(touches[t].down && touches[t].x / SCALE == x && touches[t].y / SCALE == y)
|
||||||
|
{
|
||||||
|
buf[i++] = 'X';
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf[i++] = '.';
|
||||||
|
beach:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
buf[i++] = '\n';
|
||||||
|
}
|
||||||
|
buf[i++] = '\0';
|
||||||
|
// printf("%zu, %zu\n", i, sizeof(buf));
|
||||||
|
assert(i == sizeof(buf));
|
||||||
|
printf("\033[2J%s", buf);
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void event(SetsuEvent *event, void *user)
|
||||||
|
{
|
||||||
|
dirty = true;
|
||||||
|
switch(event->type)
|
||||||
|
{
|
||||||
|
case SETSU_EVENT_DOWN:
|
||||||
|
for(size_t i=0; i<TOUCHES_MAX; i++)
|
||||||
|
{
|
||||||
|
if(!touches[i].down)
|
||||||
|
{
|
||||||
|
touches[i].down = true;
|
||||||
|
touches[i].tracking_id = event->tracking_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SETSU_EVENT_POSITION_X:
|
||||||
|
case SETSU_EVENT_POSITION_Y:
|
||||||
|
case SETSU_EVENT_UP:
|
||||||
|
for(size_t i=0; i<TOUCHES_MAX; i++)
|
||||||
|
{
|
||||||
|
if(touches[i].down && touches[i].tracking_id == event->tracking_id)
|
||||||
|
{
|
||||||
|
switch(event->type)
|
||||||
|
{
|
||||||
|
case SETSU_EVENT_POSITION_X:
|
||||||
|
touches[i].x = event->value;
|
||||||
|
break;
|
||||||
|
case SETSU_EVENT_POSITION_Y:
|
||||||
|
touches[i].y = event->value;
|
||||||
|
break;
|
||||||
|
case SETSU_EVENT_UP:
|
||||||
|
touches[i].down = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
memset(touches, 0, sizeof(touches));
|
||||||
setsu = setsu_new();
|
setsu = setsu_new();
|
||||||
if(!setsu)
|
if(!setsu)
|
||||||
{
|
{
|
||||||
printf("Failed to init setsu\n");
|
printf("Failed to init setsu\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
dirty = true;
|
||||||
while(1)
|
while(1)
|
||||||
setsu_poll(setsu);
|
{
|
||||||
|
if(dirty)
|
||||||
|
print_state();
|
||||||
|
dirty = false;
|
||||||
|
setsu_poll(setsu, event);
|
||||||
|
}
|
||||||
atexit(quit);
|
atexit(quit);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue