3434)
3535CLAW_SYNC_ROM = bytes ([0x0F , 0x00 , 0x00 , 0x3C , 0x22 ])
3636
37+ CLAW_SET_XINPUT = bytes ([0x0F , 0x00 , 0x00 , 0x3C , 0x24 , 0x01 , 0x00 ])
3738CLAW_SET_DINPUT = bytes ([0x0F , 0x00 , 0x00 , 0x3C , 0x24 , 0x02 , 0x00 ])
3839CLAW_SET_MSI = bytes ([0x0F , 0x00 , 0x00 , 0x3C , 0x24 , 0x03 , 0x00 ])
3940CLAW_SET_DESKTOP = bytes ([0x0F , 0x00 , 0x00 , 0x3C , 0x24 , 0x04 , 0x00 ])
4344MSI_CLAW_DINPUT_PID = 0x1902
4445MSI_CLAW_TEST_PID = 0x1903
4546
47+ MSI_VENDOR_APPLICATIONS = [
48+ 0xFFF00040 ,
49+ 0x00010005 ,
50+ 0xFF000000 ,
51+ 0xFFA00001 ,
52+ ]
53+
4654KBD_VID = 0x0001
4755KBD_PID = 0x0001
4856
@@ -174,12 +182,13 @@ def consume(self, events: Sequence[Event]) -> None:
174182 )
175183 self .write (cmd )
176184
177- def set_dinput_mode (self , init : bool = False ) -> None :
185+ def set_controller_mode (self , dinput : bool = False , init : bool = False ) -> None :
178186 if not self .dev :
179187 return
180188
181- # Make sure M1/M2 are recognizable
182- if init :
189+ # Make sure M1/M2 are recognizable in dinput mode
190+ # Otherwise dont remap them. So users can modify them in Windows
191+ if init and dinput :
183192 time .sleep (0.3 )
184193 self .write (CLAW_SET_M1M2 (self .addr or ADDR_DEFAULT , "m1" ))
185194 time .sleep (0.5 )
@@ -190,8 +199,11 @@ def set_dinput_mode(self, init: bool = False) -> None:
190199 self .write (CLAW_SET_MSI )
191200 time .sleep (2 )
192201
193- # Set the device to dinput mode
194- self .write (CLAW_SET_DINPUT )
202+ if dinput :
203+ # Set the device to dinput mode
204+ self .write (CLAW_SET_DINPUT )
205+ else :
206+ self .write (CLAW_SET_XINPUT )
195207
196208
197209DINPUT_BUTTON_MAP : dict [int , GamepadButton ] = to_map (
@@ -259,34 +271,34 @@ def plugin_run(
259271 else :
260272 first_disabled = True
261273
274+ use_dinput = conf .get ("dinput_mode" , False )
262275 try :
263276 is_xinput = bool (enumerate_evs (vid = MSI_CLAW_VID , pid = MSI_CLAW_XINPUT_PID ))
264- found_device = bool (
265- enumerate_evs (vid = MSI_CLAW_VID , pid = MSI_CLAW_DINPUT_PID )
266- )
277+ is_dinput = bool (enumerate_evs (vid = MSI_CLAW_VID , pid = MSI_CLAW_DINPUT_PID ))
278+ found_device = is_xinput or is_dinput
267279 test_mode = bool (enumerate_evs (vid = MSI_CLAW_VID , pid = MSI_CLAW_TEST_PID ))
268280 except Exception :
269281 logger .warning ("Failed finding device, skipping check." )
270282 time .sleep (LONGER_ERROR_DELAY )
271283 found_device = True
272284 is_xinput = False
285+ is_dinput = False
273286
274- if is_xinput or (found_device and not test_mode and not initialized ):
287+ if (
288+ (is_xinput and use_dinput )
289+ or (is_dinput and not use_dinput )
290+ or (found_device and not test_mode and not initialized )
291+ ):
275292 d_vend = ClawDInputHidraw (
276293 vid = [MSI_CLAW_VID ],
277294 pid = [MSI_CLAW_XINPUT_PID , MSI_CLAW_DINPUT_PID ],
278- application = [
279- 0xFFF00040 ,
280- 0x00010005 ,
281- 0xFF000000 ,
282- 0xFFA00001 ,
283- ],
295+ application = MSI_VENDOR_APPLICATIONS ,
284296 required = True ,
285297 )
286298 initialized = True
287299 try :
288300 d_vend .open ()
289- d_vend .set_dinput_mode ( init = True )
301+ d_vend .set_controller_mode ( conf . get ( "dinput_mode" , False ), init = True )
290302 d_vend .close (True )
291303 time .sleep (2 )
292304 except Exception as e :
@@ -312,6 +324,7 @@ def plugin_run(
312324 emit ,
313325 woke_up ,
314326 test_mode = test_mode ,
327+ use_dinput = use_dinput ,
315328 )
316329 repeated_fail = False
317330 except Exception as e :
@@ -359,6 +372,7 @@ def controller_loop(
359372 emit : Emitter ,
360373 woke_up : TEvent ,
361374 test_mode : bool = False ,
375+ use_dinput : bool = False ,
362376):
363377 debug = DEBUG_MODE
364378
@@ -369,20 +383,23 @@ def controller_loop(
369383 None ,
370384 emit = emit ,
371385 rgb_modes = {"disabled" : [], "solid" : ["color" ]},
372- extra_buttons = dconf .get ("extra_buttons" , "dual" ),
386+ extra_buttons = dconf .get ("extra_buttons" , "dual" ) if use_dinput else "none" ,
373387 )
374388
375389 # Inputs
390+ extra_args = {
391+ "btn_map" : DINPUT_BUTTON_MAP ,
392+ "axis_map" : DINPUT_AXIS_MAP ,
393+ "postprocess" : DINPUT_AXIS_POSTPROCESS ,
394+ }
376395 d_xinput = GenericGamepadEvdev (
377396 vid = [MSI_CLAW_VID ],
378- pid = [MSI_CLAW_DINPUT_PID , MSI_CLAW_TEST_PID ],
397+ pid = [MSI_CLAW_XINPUT_PID , MSI_CLAW_DINPUT_PID , MSI_CLAW_TEST_PID ],
379398 # name=["Generic X-Box pad"],
380399 capabilities = {EC ("EV_KEY" ): [EC ("BTN_A" )]},
381400 required = True ,
382401 hide = True ,
383- btn_map = DINPUT_BUTTON_MAP ,
384- axis_map = DINPUT_AXIS_MAP ,
385- postprocess = DINPUT_AXIS_POSTPROCESS ,
402+ ** (extra_args if use_dinput else {}),
386403 )
387404
388405 d_kbd_1 = GenericGamepadEvdev (
@@ -396,14 +413,14 @@ def controller_loop(
396413 # Mute these so after suspend we do not get stray keypresses
397414 d_kbd_2 = DesktopDetectorEvdev (
398415 vid = [MSI_CLAW_VID ],
399- pid = [MSI_CLAW_DINPUT_PID ],
416+ pid = [MSI_CLAW_XINPUT_PID , MSI_CLAW_DINPUT_PID ],
400417 required = False ,
401418 grab = True ,
402419 capabilities = {EC ("EV_KEY" ): [EC ("KEY_ESC" )]},
403420 )
404421 d_mouse = DesktopDetectorEvdev (
405422 vid = [MSI_CLAW_VID ],
406- pid = [MSI_CLAW_DINPUT_PID ],
423+ pid = [MSI_CLAW_XINPUT_PID , MSI_CLAW_DINPUT_PID ],
407424 required = False ,
408425 grab = True ,
409426 capabilities = {EC ("EV_KEY" ): [EC ("BTN_MOUSE" )]},
@@ -442,23 +459,15 @@ def controller_loop(
442459 d_vend = ClawDInputHidraw (
443460 vid = [MSI_CLAW_VID ],
444461 pid = [MSI_CLAW_TEST_PID ],
445- application = [
446- 0xFFF00040 ,
447- 0x00010005 ,
448- 0xFF000000 ,
449- ],
462+ application = MSI_VENDOR_APPLICATIONS ,
450463 required = True ,
451464 test_mode = True ,
452465 )
453466 else :
454467 d_vend = ClawDInputHidraw (
455468 vid = [MSI_CLAW_VID ],
456- pid = [MSI_CLAW_DINPUT_PID ],
457- application = [
458- 0xFFF00040 ,
459- 0x00010005 ,
460- 0xFF000000 ,
461- ],
469+ pid = [MSI_CLAW_DINPUT_PID , MSI_CLAW_XINPUT_PID ],
470+ application = MSI_VENDOR_APPLICATIONS ,
462471 required = True ,
463472 )
464473
@@ -511,8 +520,10 @@ def prepare(m):
511520 d_kbd_2 .desktop = False
512521
513522 if desktop_mode or (switch_to_dinput and start > switch_to_dinput ):
514- logger .info ("Setting controller to dinput mode." )
515- d_vend .set_dinput_mode ()
523+ logger .info (
524+ f"Setting controller to { 'dinput' if use_dinput else 'xinput' } mode."
525+ )
526+ d_vend .set_controller_mode (dinput = use_dinput )
516527 switch_to_dinput = None
517528 # elif woke_up.is_set():
518529 # woke_up.clear()
0 commit comments