d2d1: Scale stroke width for D2D1_STROKE_TRANSFORM_TYPE_FIXED in DrawGeometry::ID2D1D...
[wine.git] / dlls / winebus.sys / unixlib.c
blob74b4992f07bbf323f17511f4b02cdc29d480536f
1 /*
2 * Copyright 2021 RĂ©mi Bernon for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #if 0
20 #pragma makedep unix
21 #endif
23 #include "config.h"
25 #include <stdarg.h>
26 #include <stdlib.h>
28 #include "ntstatus.h"
29 #define WIN32_NO_STATUS
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winternl.h"
33 #include "ddk/hidtypes.h"
35 #include "wine/debug.h"
36 #include "wine/list.h"
37 #include "wine/unixlib.h"
39 #include "unix_private.h"
41 BOOL is_xbox_gamepad(WORD vid, WORD pid)
43 if (vid != 0x045e) return FALSE;
44 if (pid == 0x0202) return TRUE; /* Xbox Controller */
45 if (pid == 0x0285) return TRUE; /* Xbox Controller S */
46 if (pid == 0x0289) return TRUE; /* Xbox Controller S */
47 if (pid == 0x028e) return TRUE; /* Xbox360 Controller */
48 if (pid == 0x028f) return TRUE; /* Xbox360 Wireless Controller */
49 if (pid == 0x02d1) return TRUE; /* Xbox One Controller */
50 if (pid == 0x02dd) return TRUE; /* Xbox One Controller (Covert Forces/Firmware 2015) */
51 if (pid == 0x02e0) return TRUE; /* Xbox One X Controller */
52 if (pid == 0x02e3) return TRUE; /* Xbox One Elite Controller */
53 if (pid == 0x02e6) return TRUE; /* Wireless XBox Controller Dongle */
54 if (pid == 0x02ea) return TRUE; /* Xbox One S Controller */
55 if (pid == 0x02fd) return TRUE; /* Xbox One S Controller (Firmware 2017) */
56 if (pid == 0x0b00) return TRUE; /* Xbox Elite 2 */
57 if (pid == 0x0b05) return TRUE; /* Xbox Elite 2 Wireless */
58 if (pid == 0x0b12) return TRUE; /* Xbox Series */
59 if (pid == 0x0b13) return TRUE; /* Xbox Series Wireless */
60 if (pid == 0x0719) return TRUE; /* Xbox 360 Wireless Adapter */
61 return FALSE;
64 BOOL is_dualshock4_gamepad(WORD vid, WORD pid)
66 if (vid != 0x054c) return FALSE;
67 if (pid == 0x05c4) return TRUE; /* DualShock 4 [CUH-ZCT1x] */
68 if (pid == 0x09cc) return TRUE; /* DualShock 4 [CUH-ZCT2x] */
69 if (pid == 0x0ba0) return TRUE; /* Dualshock 4 Wireless Adaptor */
70 return FALSE;
73 BOOL is_dualsense_gamepad(WORD vid, WORD pid)
75 if (vid == 0x054c && pid == 0x0ce6) return TRUE;
76 return FALSE;
79 struct mouse_device
81 struct unix_device unix_device;
84 static void mouse_destroy(struct unix_device *iface)
88 static NTSTATUS mouse_start(struct unix_device *iface)
90 const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_MOUSE};
91 if (!hid_device_begin_report_descriptor(iface, &device_usage))
92 return STATUS_NO_MEMORY;
93 if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_BUTTON, 1, 3))
94 return STATUS_NO_MEMORY;
95 if (!hid_device_end_report_descriptor(iface))
96 return STATUS_NO_MEMORY;
98 return STATUS_SUCCESS;
101 static void mouse_stop(struct unix_device *iface)
105 static NTSTATUS mouse_haptics_start(struct unix_device *iface, UINT duration,
106 USHORT rumble_intensity, USHORT buzz_intensity,
107 USHORT left_intensity, USHORT right_intensity)
109 return STATUS_NOT_SUPPORTED;
112 static NTSTATUS mouse_haptics_stop(struct unix_device *iface)
114 return STATUS_NOT_SUPPORTED;
117 static NTSTATUS mouse_physical_device_control(struct unix_device *iface, USAGE control)
119 return STATUS_NOT_SUPPORTED;
122 static NTSTATUS mouse_physical_device_set_gain(struct unix_device *iface, BYTE percent)
124 return STATUS_NOT_SUPPORTED;
127 static NTSTATUS mouse_physical_effect_control(struct unix_device *iface, BYTE index,
128 USAGE control, BYTE iterations)
130 return STATUS_NOT_SUPPORTED;
133 static NTSTATUS mouse_physical_effect_update(struct unix_device *iface, BYTE index,
134 struct effect_params *params)
136 return STATUS_NOT_SUPPORTED;
139 static const struct hid_device_vtbl mouse_vtbl =
141 mouse_destroy,
142 mouse_start,
143 mouse_stop,
144 mouse_haptics_start,
145 mouse_haptics_stop,
146 mouse_physical_device_control,
147 mouse_physical_device_set_gain,
148 mouse_physical_effect_control,
149 mouse_physical_effect_update,
152 static const struct device_desc mouse_device_desc =
154 .vid = 0x845e,
155 .pid = 0x0001,
156 .input = -1,
157 .manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
158 .product = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0},
159 .serialnumber = {'0','0','0','0',0},
162 static NTSTATUS mouse_device_create(void *args)
164 struct device_create_params *params = args;
165 params->desc = mouse_device_desc;
166 params->device = (UINT_PTR)hid_device_create(&mouse_vtbl, sizeof(struct mouse_device));
167 return STATUS_SUCCESS;
170 struct keyboard_device
172 struct unix_device unix_device;
175 static void keyboard_destroy(struct unix_device *iface)
179 static NTSTATUS keyboard_start(struct unix_device *iface)
181 const USAGE_AND_PAGE device_usage = {.UsagePage = HID_USAGE_PAGE_GENERIC, .Usage = HID_USAGE_GENERIC_KEYBOARD};
182 if (!hid_device_begin_report_descriptor(iface, &device_usage))
183 return STATUS_NO_MEMORY;
184 if (!hid_device_add_buttons(iface, HID_USAGE_PAGE_KEYBOARD, 0, 101))
185 return STATUS_NO_MEMORY;
186 if (!hid_device_end_report_descriptor(iface))
187 return STATUS_NO_MEMORY;
189 return STATUS_SUCCESS;
192 static void keyboard_stop(struct unix_device *iface)
196 static NTSTATUS keyboard_haptics_start(struct unix_device *iface, UINT duration,
197 USHORT rumble_intensity, USHORT buzz_intensity,
198 USHORT left_intensity, USHORT right_intensity)
200 return STATUS_NOT_SUPPORTED;
203 static NTSTATUS keyboard_haptics_stop(struct unix_device *iface)
205 return STATUS_NOT_SUPPORTED;
208 static NTSTATUS keyboard_physical_device_control(struct unix_device *iface, USAGE control)
210 return STATUS_NOT_SUPPORTED;
213 static NTSTATUS keyboard_physical_device_set_gain(struct unix_device *iface, BYTE percent)
215 return STATUS_NOT_SUPPORTED;
218 static NTSTATUS keyboard_physical_effect_control(struct unix_device *iface, BYTE index,
219 USAGE control, BYTE iterations)
221 return STATUS_NOT_SUPPORTED;
224 static NTSTATUS keyboard_physical_effect_update(struct unix_device *iface, BYTE index,
225 struct effect_params *params)
227 return STATUS_NOT_SUPPORTED;
230 static const struct hid_device_vtbl keyboard_vtbl =
232 keyboard_destroy,
233 keyboard_start,
234 keyboard_stop,
235 keyboard_haptics_start,
236 keyboard_haptics_stop,
237 keyboard_physical_device_control,
238 keyboard_physical_device_set_gain,
239 keyboard_physical_effect_control,
240 keyboard_physical_effect_update,
243 static const struct device_desc keyboard_device_desc =
245 .vid = 0x845e,
246 .pid = 0x0002,
247 .input = -1,
248 .manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
249 .product = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0},
250 .serialnumber = {'0','0','0','0',0},
253 static NTSTATUS keyboard_device_create(void *args)
255 struct device_create_params *params = args;
256 params->desc = keyboard_device_desc;
257 params->device = (UINT_PTR)hid_device_create(&keyboard_vtbl, sizeof(struct keyboard_device));
258 return STATUS_SUCCESS;
261 void *raw_device_create(const struct raw_device_vtbl *vtbl, SIZE_T size)
263 struct unix_device *iface;
265 if (!(iface = calloc(1, size))) return NULL;
266 iface->vtbl = vtbl;
267 iface->ref = 1;
269 return iface;
272 static void unix_device_decref(struct unix_device *iface)
274 if (!InterlockedDecrement(&iface->ref))
276 iface->vtbl->destroy(iface);
277 free(iface);
281 static ULONG unix_device_incref(struct unix_device *iface)
283 return InterlockedIncrement(&iface->ref);
286 static NTSTATUS unix_device_remove(void *args)
288 struct device_remove_params *params = args;
289 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
290 iface->vtbl->stop(iface);
291 unix_device_decref(iface);
292 return STATUS_SUCCESS;
295 static NTSTATUS unix_device_start(void *args)
297 struct device_start_params *params = args;
298 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
299 return iface->vtbl->start(iface);
302 static NTSTATUS unix_device_get_report_descriptor(void *args)
304 struct device_descriptor_params *params = args;
305 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
306 return iface->vtbl->get_report_descriptor(iface, params->buffer, params->length, params->out_length);
309 static NTSTATUS unix_device_set_output_report(void *args)
311 struct device_report_params *params = args;
312 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
313 iface->vtbl->set_output_report(iface, params->packet, params->io);
314 return STATUS_SUCCESS;
317 static NTSTATUS unix_device_get_feature_report(void *args)
319 struct device_report_params *params = args;
320 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
321 iface->vtbl->get_feature_report(iface, params->packet, params->io);
322 return STATUS_SUCCESS;
325 static NTSTATUS unix_device_set_feature_report(void *args)
327 struct device_report_params *params = args;
328 struct unix_device *iface = (struct unix_device *)(UINT_PTR)params->device;
329 iface->vtbl->set_feature_report(iface, params->packet, params->io);
330 return STATUS_SUCCESS;
333 const unixlib_entry_t __wine_unix_call_funcs[] =
335 sdl_bus_init,
336 sdl_bus_wait,
337 sdl_bus_stop,
338 udev_bus_init,
339 udev_bus_wait,
340 udev_bus_stop,
341 iohid_bus_init,
342 iohid_bus_wait,
343 iohid_bus_stop,
344 mouse_device_create,
345 keyboard_device_create,
346 unix_device_remove,
347 unix_device_start,
348 unix_device_get_report_descriptor,
349 unix_device_set_output_report,
350 unix_device_get_feature_report,
351 unix_device_set_feature_report,
354 C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count);
356 void bus_event_cleanup(struct bus_event *event)
358 struct unix_device *iface = (struct unix_device *)(UINT_PTR)event->device;
359 if (event->type == BUS_EVENT_TYPE_NONE) return;
360 unix_device_decref(iface);
363 struct bus_event_entry
365 struct list entry;
366 struct bus_event event;
369 void bus_event_queue_destroy(struct list *queue)
371 struct bus_event_entry *entry, *next;
373 LIST_FOR_EACH_ENTRY_SAFE(entry, next, queue, struct bus_event_entry, entry)
375 bus_event_cleanup(&entry->event);
376 list_remove(&entry->entry);
377 free(entry);
381 BOOL bus_event_queue_device_removed(struct list *queue, struct unix_device *device)
383 ULONG size = sizeof(struct bus_event_entry);
384 struct bus_event_entry *entry = malloc(size);
385 if (!entry) return FALSE;
387 if (unix_device_incref(device) == 1) /* being destroyed */
389 free(entry);
390 return FALSE;
393 entry->event.type = BUS_EVENT_TYPE_DEVICE_REMOVED;
394 entry->event.device = (UINT_PTR)device;
395 list_add_tail(queue, &entry->entry);
397 return TRUE;
400 BOOL bus_event_queue_device_created(struct list *queue, struct unix_device *device, struct device_desc *desc)
402 ULONG size = sizeof(struct bus_event_entry);
403 struct bus_event_entry *entry = malloc(size);
404 if (!entry) return FALSE;
406 if (unix_device_incref(device) == 1) /* being destroyed */
408 free(entry);
409 return FALSE;
412 entry->event.type = BUS_EVENT_TYPE_DEVICE_CREATED;
413 entry->event.device = (UINT_PTR)device;
414 entry->event.device_created.desc = *desc;
415 list_add_tail(queue, &entry->entry);
417 return TRUE;
420 BOOL bus_event_queue_input_report(struct list *queue, struct unix_device *device, BYTE *report, USHORT length)
422 ULONG size = offsetof(struct bus_event_entry, event.input_report.buffer[length]);
423 struct bus_event_entry *entry = malloc(size);
424 if (!entry) return FALSE;
426 if (unix_device_incref(device) == 1) /* being destroyed */
428 free(entry);
429 return FALSE;
432 entry->event.type = BUS_EVENT_TYPE_INPUT_REPORT;
433 entry->event.device = (UINT_PTR)device;
434 entry->event.input_report.length = length;
435 memcpy(entry->event.input_report.buffer, report, length);
436 list_add_tail(queue, &entry->entry);
438 return TRUE;
441 BOOL bus_event_queue_pop(struct list *queue, struct bus_event *event)
443 struct list *head = list_head(queue);
444 struct bus_event_entry *entry;
445 ULONG size;
447 if (!head) return FALSE;
449 entry = LIST_ENTRY(head, struct bus_event_entry, entry);
450 list_remove(&entry->entry);
452 if (entry->event.type != BUS_EVENT_TYPE_INPUT_REPORT) size = sizeof(entry->event);
453 else size = offsetof(struct bus_event, input_report.buffer[entry->event.input_report.length]);
455 memcpy(event, &entry->event, size);
456 free(entry);
458 return TRUE;