libei/src/libeis-device.c
Peter Hutterer 5d99d858bf libeis: a device in NEW state must be disconnected too
NEW means "client has sent request" which means we have a ref to it internally
and we have to disconnect it accordingly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-08-07 15:05:40 +10:00

142 lines
3.5 KiB
C

/*
* Copyright © 2020 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include <errno.h>
#include "util-macros.h"
#include "util-bits.h"
#include "libeis-private.h"
static void
eis_device_destroy(struct eis_device *device)
{
}
OBJECT_IMPLEMENT_REF(eis_device);
OBJECT_IMPLEMENT_UNREF(eis_device);
OBJECT_IMPLEMENT_CREATE(eis_device);
static
OBJECT_IMPLEMENT_PARENT(eis_device, eis_client);
_public_ struct eis_client *
eis_device_get_client(struct eis_device *device)
{
return eis_device_parent(device);
}
struct eis_device *
eis_device_new(struct eis_client *client,
uint32_t id,
uint32_t capabilities)
{
struct eis_device *device = eis_device_create(&client->object);
device->capabilities = capabilities;
device->id = id;
device->state = EIS_DEVICE_STATE_NEW;
return device;
}
_public_
bool
eis_device_has_capability(struct eis_device *device,
enum eis_device_capability cap)
{
switch (cap) {
case EIS_DEVICE_CAP_POINTER:
case EIS_DEVICE_CAP_POINTER_ABSOLUTE:
case EIS_DEVICE_CAP_KEYBOARD:
case EIS_DEVICE_CAP_TOUCH:
return flag_is_set(device->capabilities, cap);
}
return false;
}
int
eis_device_pointer_rel(struct eis_device *device,
int x, int y)
{
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
return -EINVAL;
eis_queue_pointer_rel_event(device, x, y);
return 0;
}
int
eis_device_pointer_button(struct eis_device *device,
uint32_t button, bool is_press)
{
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
return -EINVAL;
eis_queue_pointer_button_event(device, button, is_press);
return 0;
}
int
eis_device_keyboard_key(struct eis_device *device,
uint32_t key, bool is_press)
{
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
return -EINVAL;
eis_queue_keyboard_key_event(device, key, is_press);
return 0;
}
_public_ void
eis_device_connect(struct eis_device *device)
{
if (device->state != EIS_DEVICE_STATE_NEW)
return;
device->state = EIS_DEVICE_STATE_ACCEPTED;
eis_client_connect_device(eis_device_get_client(device), device);
}
_public_ void
eis_device_disconnect(struct eis_device *device)
{
if (device->state == EIS_DEVICE_STATE_REMOVED)
return;
device->state = EIS_DEVICE_STATE_REMOVED;
eis_client_disconnect_device(eis_device_get_client(device), device);
}