mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-25 16:16:28 +00:00
[client] evdev: handle device removal and hot-plug
This commit is contained in:
parent
afbd844be8
commit
35e6a6e81a
@ -95,20 +95,104 @@ void evdev_earlyInit(void)
|
||||
option_register(options);
|
||||
}
|
||||
|
||||
static bool evdev_grabDevice(EvdevDevice * device)
|
||||
{
|
||||
if (device->grabbed)
|
||||
return true;
|
||||
|
||||
if (ioctl(device->fd, EVIOCGRAB, (void *)1) < 0)
|
||||
{
|
||||
DEBUG_ERROR("EVIOCGRAB=1 failed: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Grabbed %s", device->path);
|
||||
device->grabbed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool evdev_openDevice(EvdevDevice * device, bool quiet)
|
||||
{
|
||||
device->fd = open(device->path, O_RDWR);
|
||||
if (device->fd < 0)
|
||||
{
|
||||
if (errno != ENOENT || !quiet)
|
||||
DEBUG_ERROR("Unable to open %s (%s)", device->path, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
struct epoll_event event =
|
||||
{
|
||||
.events = EPOLLIN,
|
||||
.data.ptr = device
|
||||
};
|
||||
|
||||
if (epoll_ctl(state.epoll, EPOLL_CTL_ADD, device->fd, &event) != 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to add fd to epoll");
|
||||
goto err;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Opened: %s", device->path);
|
||||
|
||||
if (state.grabbed)
|
||||
evdev_grabDevice(device);
|
||||
|
||||
return true;
|
||||
|
||||
err:
|
||||
close(device->fd);
|
||||
device->fd = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int evdev_thread(void * opaque)
|
||||
{
|
||||
struct epoll_event * events = alloca(sizeof(*events) * state.deviceCount);
|
||||
DEBUG_INFO("evdev_thread Started");
|
||||
while(app_isRunning())
|
||||
{
|
||||
int openDevices = 0;
|
||||
for(int i = 0; i < state.deviceCount; ++i)
|
||||
{
|
||||
EvdevDevice * dev = &state.devices[i];
|
||||
if (dev->fd <= 0)
|
||||
{
|
||||
if (evdev_openDevice(dev, true))
|
||||
++openDevices;
|
||||
}
|
||||
else
|
||||
++openDevices;
|
||||
}
|
||||
|
||||
if (openDevices == 0)
|
||||
{
|
||||
usleep(1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
int waiting = epoll_wait(state.epoll, events, state.deviceCount, 100);
|
||||
for(int i = 0; i < waiting; ++i)
|
||||
{
|
||||
struct input_event ev;
|
||||
size_t n = read(events[i].data.fd, &ev, sizeof(ev));
|
||||
EvdevDevice * device = (EvdevDevice *)events[i].data.ptr;
|
||||
|
||||
size_t n = read(device->fd, &ev, sizeof(ev));
|
||||
if (n != sizeof(ev))
|
||||
{
|
||||
DEBUG_WARN("Failed to read evdev event");
|
||||
if (errno == ENODEV)
|
||||
{
|
||||
DEBUG_WARN("Device was removed: %s", device->path);
|
||||
epoll_ctl(state.epoll, EPOLL_CTL_DEL, device->fd, NULL);
|
||||
close(device->fd);
|
||||
device->fd = 0;
|
||||
device->grabbed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG_WARN("Failed to read evdev event: %s (%s)",
|
||||
device->path, strerror(errno));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -185,28 +269,10 @@ bool evdev_start(void)
|
||||
for(int i = 0; i < state.deviceCount; ++i)
|
||||
{
|
||||
EvdevDevice * device = &state.devices[i];
|
||||
device->fd = open(device->path, O_RDWR);
|
||||
if (device->fd < 0)
|
||||
{
|
||||
DEBUG_ERROR("Unable to open %s (%s)", device->path, strerror(errno));
|
||||
if (!evdev_openDevice(device, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
struct epoll_event event =
|
||||
{
|
||||
.events = EPOLLIN,
|
||||
.data.fd = device->fd
|
||||
};
|
||||
|
||||
if (epoll_ctl(state.epoll, EPOLL_CTL_ADD, device->fd, &event) != 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to add fd to epoll");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Opened: %s", device->path);
|
||||
}
|
||||
|
||||
if (!lgCreateThread("Evdev", evdev_thread, NULL, &state.thread))
|
||||
{
|
||||
DEBUG_ERROR("Failed to create the evdev thread");
|
||||
@ -269,18 +335,10 @@ void evdev_grabKeyboard(void)
|
||||
|
||||
for(EvdevDevice * device = state.devices; device->path; ++device)
|
||||
{
|
||||
if (device->fd <= 0 || device->grabbed)
|
||||
continue;
|
||||
|
||||
if (ioctl(device->fd, EVIOCGRAB, (void *)1) < 0)
|
||||
{
|
||||
DEBUG_ERROR("EVIOCGRAB=1 failed: %s", strerror(errno));
|
||||
continue;
|
||||
if (device->fd > 0)
|
||||
evdev_grabDevice(device);
|
||||
}
|
||||
|
||||
DEBUG_INFO("Grabbed %s", device->path);
|
||||
device->grabbed = true;
|
||||
}
|
||||
state.grabbed = true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user