Merge pull request #2596 from akallabeth/wlog_default_out_fix
[platform/upstream/freerdp.git] / client / Wayland / wlf_input.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Wayland Input
4  *
5  * Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdlib.h>
21 #include <linux/input.h>
22
23 #include <freerdp/locale/keyboard.h>
24
25 #include "wlf_input.h"
26
27 static void wl_pointer_enter(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
28 {
29
30 }
31
32 static void wl_pointer_leave(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface)
33 {
34         
35 }
36
37 static void wl_pointer_motion(void* data, struct wl_pointer* pointer, uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
38 {
39         wlfInput* input_w = data;
40         rdpInput* input;
41         UINT16 x;
42         UINT16 y;
43
44         input = input_w->input;
45
46         x = (UINT16) wl_fixed_to_int(sx_w);
47         y = (UINT16) wl_fixed_to_int(sy_w);
48
49         input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
50
51         input_w->last_x = x;
52         input_w->last_y = y;
53 }
54
55 static void wl_pointer_button(void* data, struct wl_pointer* pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
56 {
57         wlfInput* input_w = data;
58         rdpInput* input;
59         UINT16 x;
60         UINT16 y;
61         UINT16 flags;
62
63         input = input_w->input;
64
65         if (state == WL_POINTER_BUTTON_STATE_PRESSED)
66                 flags = PTR_FLAGS_DOWN;
67         else
68                 flags = 0;
69
70         switch (button)
71         {
72                 case BTN_LEFT:
73                         flags |= PTR_FLAGS_BUTTON1;
74                         break;
75                 case BTN_RIGHT:
76                         flags |= PTR_FLAGS_BUTTON2;
77                         break;
78                 case BTN_MIDDLE:
79                         flags |= PTR_FLAGS_BUTTON3;
80                         break;
81                 default:
82                         return;
83         }
84
85         x = input_w->last_x;
86         y = input_w->last_y;
87
88         input->MouseEvent(input, flags, x, y);
89 }
90
91 static void wl_pointer_axis(void* data, struct wl_pointer* pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
92 {
93         wlfInput* input_w = data;
94         rdpInput* input;
95         UINT16 flags;
96         int direction;
97
98         input = input_w->input;
99
100         flags = PTR_FLAGS_WHEEL;
101
102         if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
103         {
104                 direction = wl_fixed_to_int(value);
105                 if (direction < 0)
106                         flags |= 0x0078;
107                 else
108                         flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
109         }
110
111         input->MouseEvent(input, flags, 0, 0);
112 }
113
114 static const struct wl_pointer_listener wl_pointer_listener =
115 {
116         wl_pointer_enter,
117         wl_pointer_leave,
118         wl_pointer_motion,
119         wl_pointer_button,
120         wl_pointer_axis
121 };
122
123 static void wl_keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format, int fd, uint32_t size)
124 {
125
126 }
127
128 static void wl_keyboard_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface, struct wl_array* keys)
129 {
130         wlfInput* input_w = data;
131         rdpInput* input;
132         UINT16 x;
133         UINT16 y;
134
135         input = input_w->input;
136
137         x = input_w->last_x;
138         y = input_w->last_y;
139
140         input->FocusInEvent(input, 0);
141         input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
142 }
143
144 static void wl_keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface)
145 {
146
147 }
148
149 static void wl_keyboard_key(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
150 {
151         wlfInput* input_w = data;
152         rdpInput* input;
153         BOOL key_down;
154         DWORD rdp_scancode;
155
156         input = input_w->input;
157
158         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
159                 key_down = TRUE;
160         else
161                 key_down = FALSE;
162
163         rdp_scancode = (DWORD) key;
164
165         if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
166                 return;
167
168         freerdp_input_send_keyboard_event_ex(input, key_down, rdp_scancode);
169 }
170
171 static void wl_keyboard_modifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t mods_depr, uint32_t mods_latch, uint32_t mods_lock, uint32_t group)
172 {
173
174 }
175
176 static const struct wl_keyboard_listener wl_keyboard_listener =
177 {
178         wl_keyboard_keymap,
179         wl_keyboard_enter,
180         wl_keyboard_leave,
181         wl_keyboard_key,
182         wl_keyboard_modifiers
183 };
184
185 static void wl_seat_handle_capabilities(void* data, struct wl_seat* seat, enum wl_seat_capability capabilities)
186 {
187         wlfInput* input = data;
188         struct wl_pointer* pointer;
189         struct wl_keyboard* keyboard;
190
191         if (capabilities & WL_SEAT_CAPABILITY_POINTER)
192         {
193                 pointer = wl_seat_get_pointer(seat);
194
195                 input->pointer = pointer;
196                 wl_pointer_add_listener(pointer, &wl_pointer_listener, input);
197         }
198
199         if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
200         {
201                 keyboard = wl_seat_get_keyboard(seat);
202
203                 input->keyboard = keyboard;
204                 wl_keyboard_add_listener(keyboard, &wl_keyboard_listener, input);
205         }
206
207 }
208
209 static const struct wl_seat_listener wl_seat_listener = {
210         wl_seat_handle_capabilities
211 };
212
213
214 wlfInput* wlf_CreateInput(wlfContext* wlfc)
215 {
216         wlfInput* input;
217         struct wl_seat* seat;
218
219         if (!wlfc->display)
220                 return NULL;
221         if (!wlfc->display->seat)
222                 return NULL;
223         seat = wlfc->display->seat;
224
225         input = (wlfInput*) calloc(1, sizeof(wlfInput));
226
227         if (input)
228         {
229                 input->input = wlfc->context.input;
230                 input->last_x = 0;
231                 input->last_y = 0;
232
233                 wl_seat_add_listener(seat, &wl_seat_listener, input);
234         }
235
236         return input;
237 }
238
239 void wlf_DestroyInput(wlfContext* wlfc, wlfInput* input)
240 {
241         if (input == NULL)
242                 return;
243
244         if (wlfc->input == input)
245                 wlfc->input = NULL;
246
247         if (input->pointer)
248                 wl_pointer_release(input->pointer);
249         if (input->keyboard)
250                 wl_keyboard_release(input->keyboard);
251
252         free(input);
253 }