2457a0682f98f28e8ce0efa7a664498e31fe7d28
[platform/core/uifw/libds-tizen.git] / src / libds / backend / libinput / input.c
1 #include <assert.h>
2
3 #include "libds/log.h"
4 #include "backend.h"
5
6 static const struct ds_input_device_interface input_device_iface;
7
8 static bool
9 ds_input_device_is_libinput(struct ds_input_device *ds_dev)
10 {
11     return ds_dev->iface == &input_device_iface;
12 }
13
14 static struct ds_libinput_input_device *
15 get_libinput_input_device_from_input_device(struct ds_input_device *ds_dev)
16 {
17     assert(ds_input_device_is_libinput(ds_dev));
18     return (struct ds_libinput_input_device *)ds_dev;
19 }
20
21 static void
22 input_device_iface_destroy(struct ds_input_device *ds_dev)
23 {
24     struct ds_libinput_input_device *dev;
25
26     dev = get_libinput_input_device_from_input_device(ds_dev);
27
28     free(dev);
29 }
30
31 static const struct ds_input_device_interface input_device_iface =
32 {
33     .destroy = input_device_iface_destroy,
34 };
35
36 static struct ds_keyboard *
37 create_ds_keyboard()
38 {
39     struct ds_keyboard *kbd;
40     kbd = calloc(1, sizeof *kbd);
41     if (!kbd) {
42         ds_err("Could not allocate memory");
43         return NULL;
44     }
45     ds_keyboard_init(kbd, NULL);
46
47     return kbd;
48 }
49
50 static struct ds_pointer *
51 create_ds_pointer()
52 {
53     struct ds_pointer *pointer;
54     pointer = calloc(1, sizeof *pointer);
55     if (!pointer) {
56         ds_err("Could not allocate memory");
57         return NULL;
58     }
59     ds_pointer_init(pointer, NULL);
60
61     return pointer;
62 }
63
64 static struct ds_touch *
65 create_ds_touch()
66 {
67     struct ds_touch *touch;
68     touch = calloc(1, sizeof *touch);
69     if (!touch) {
70         ds_err("Could not allocate memory");
71         return NULL;
72     }
73     ds_touch_init(touch, NULL);
74
75     return touch;
76 }
77
78 static void
79 handle_device_added(struct ds_libinput_backend *backend,
80        struct libinput_device *libinput_dev)
81 {
82     int vendor, product;
83     const char *name;
84     struct ds_libinput_input_device *dev;
85
86     vendor = libinput_device_get_id_vendor(libinput_dev);
87     product = libinput_device_get_id_product(libinput_dev);
88     name = libinput_device_get_name(libinput_dev);
89     ds_log(DS_DBG, "Adding %s [%d:%d]", name, vendor, product);
90
91     dev = calloc(1, sizeof(struct ds_libinput_input_device));
92     if (dev == NULL) {
93         ds_log(DS_ERR, "failed to allocate ds_libinput_input_device");
94         return;
95     }
96
97     dev->handle = libinput_dev;
98     dev->backend = backend;
99     libinput_device_ref(libinput_dev);
100     libinput_device_set_user_data(libinput_dev, dev);
101
102     wl_list_insert(&backend->devices, &dev->link);
103
104     if (libinput_device_has_capability(
105                 libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
106         ds_input_device_init(&dev->base, DS_INPUT_DEVICE_KEYBOARD,
107                 &input_device_iface, name, vendor, product);
108         dev->base.keyboard = create_ds_keyboard();
109
110         wl_signal_emit(&backend->base.events.new_input,
111                 &dev->base);
112     }
113
114     if (libinput_device_has_capability(
115                 libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) {
116         ds_input_device_init(&dev->base, DS_INPUT_DEVICE_POINTER,
117                 &input_device_iface, name, vendor, product);
118         dev->base.pointer = create_ds_pointer();
119
120         wl_signal_emit(&backend->base.events.new_input,
121                 &dev->base);
122     }
123
124     if (libinput_device_has_capability(
125                 libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
126         ds_input_device_init(&dev->base, DS_INPUT_DEVICE_TOUCH,
127                 &input_device_iface, name, vendor, product);
128         dev->base.touch = create_ds_touch();
129
130         wl_signal_emit(&backend->base.events.new_input,
131                 &dev->base);
132     }
133 }
134
135 static void
136 handle_device_removed(struct ds_libinput_backend *backend,
137         struct libinput_device *libinput_dev)
138 {
139     int vendor, product;
140     const char *name;
141     struct ds_libinput_input_device *dev;
142
143     vendor = libinput_device_get_id_vendor(libinput_dev);
144     product = libinput_device_get_id_product(libinput_dev);
145     name = libinput_device_get_name(libinput_dev);
146     ds_log(DS_DBG, "Removing %s [%d:%d]", name, vendor, product);
147
148     dev = libinput_device_get_user_data(libinput_dev);
149     if (dev == NULL) {
150         ds_log(DS_ERR, "libinput_device has no ds_libinput_input_device");
151         return;
152     }
153
154     destroy_libinput_input_device(dev);
155 }
156
157 void
158 handle_libinput_event(struct ds_libinput_backend *backend,
159         struct libinput_event *event)
160 {
161     struct libinput_device *libinput_dev;
162     struct ds_libinput_input_device *dev;
163     enum libinput_event_type event_type;
164
165     libinput_dev = libinput_event_get_device(event);
166     event_type = libinput_event_get_type(event);
167     dev = libinput_device_get_user_data(libinput_dev);
168
169     switch (event_type) {
170         case LIBINPUT_EVENT_DEVICE_ADDED:
171             handle_device_added(backend, libinput_dev);
172             break;
173         case LIBINPUT_EVENT_DEVICE_REMOVED:
174             handle_device_removed(backend, libinput_dev);
175             break;
176         case LIBINPUT_EVENT_KEYBOARD_KEY:
177             handle_keyboard_key(event, dev->base.keyboard);
178             break;
179         case LIBINPUT_EVENT_POINTER_MOTION:
180             handle_pointer_motion(event, dev->base.pointer);
181             break;
182         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
183             handle_pointer_motion_abs(event, dev->base.pointer);
184             break;
185         case LIBINPUT_EVENT_POINTER_BUTTON:
186             handle_pointer_button(event, dev->base.pointer);
187             break;
188         case LIBINPUT_EVENT_POINTER_AXIS:
189             handle_pointer_axis(event, dev->base.pointer);
190             break;
191         case LIBINPUT_EVENT_TOUCH_DOWN:
192             handle_touch_down(event, dev->base.touch);
193             break;
194         case LIBINPUT_EVENT_TOUCH_UP:
195             handle_touch_up(event, dev->base.touch);
196             break;
197         case LIBINPUT_EVENT_TOUCH_MOTION:
198             handle_touch_motion(event, dev->base.touch);
199             break;
200         case LIBINPUT_EVENT_TOUCH_CANCEL:
201             handle_touch_cancel(event, dev->base.touch);
202             break;
203         case LIBINPUT_EVENT_TOUCH_FRAME:
204             handle_touch_frame(event, dev->base.touch);
205             break;
206         default:
207             ds_log(DS_DBG, "Unknown libinput event %d", event_type);
208             break;
209     }
210 }