@@ -209,13 +209,14 @@ static BOOL hid_device_add_hatswitch_count(struct unix_device *iface, BYTE count
209
209
ERR ("hatswitches should be added before buttons!\n" );
210
210
else if ((iface -> hid_device_state .bit_size % 8 ))
211
211
ERR ("hatswitches should be byte aligned, missing padding!\n" );
212
- else if (iface -> hid_device_state .bit_size + 8 * count > 0x80000 )
212
+ else if (iface -> hid_device_state .bit_size + 4 * ( count + 1 ) > 0x80000 )
213
213
ERR ("report size overflow, too many elements!\n" );
214
214
else
215
215
{
216
216
if (!iface -> hid_device_state .hatswitch_count ) iface -> hid_device_state .hatswitch_start = offset ;
217
217
iface -> hid_device_state .hatswitch_count += count ;
218
- iface -> hid_device_state .bit_size += 8 * count ;
218
+ iface -> hid_device_state .bit_size += 4 * count ;
219
+ if (count % 2 ) iface -> hid_device_state .bit_size += 4 ;
219
220
return TRUE;
220
221
}
221
222
@@ -231,16 +232,28 @@ BOOL hid_device_add_hatswitch(struct unix_device *iface, INT count)
231
232
USAGE (1 , HID_USAGE_GENERIC_HATSWITCH ),
232
233
LOGICAL_MINIMUM (1 , 1 ),
233
234
LOGICAL_MAXIMUM (1 , 8 ),
234
- REPORT_SIZE (1 , 8 ),
235
+ REPORT_SIZE (1 , 4 ),
235
236
REPORT_COUNT (4 , count ),
236
237
UNIT (1 , 0x0 ), /* None */
237
238
INPUT (1 , Data |Var |Abs |Null ),
238
239
};
240
+ const BYTE template_pad [] =
241
+ {
242
+ REPORT_COUNT (1 , 4 ),
243
+ REPORT_SIZE (1 , 1 ),
244
+ INPUT (1 , Cnst |Ary |Abs ),
245
+ };
239
246
240
247
if (!hid_device_add_hatswitch_count (iface , count ))
241
248
return FALSE;
242
249
243
- return hid_report_descriptor_append (desc , template , sizeof (template ));
250
+ if (!hid_report_descriptor_append (desc , template , sizeof (template )))
251
+ return FALSE;
252
+
253
+ if ((count % 2 ) && !hid_report_descriptor_append (desc , template_pad , sizeof (template_pad )))
254
+ return FALSE;
255
+
256
+ return TRUE;
244
257
}
245
258
246
259
static BOOL hid_device_add_axis_count (struct unix_device * iface , BOOL rel , BYTE count ,
@@ -1409,58 +1422,71 @@ BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set)
1409
1422
* +1 | 6 5 4
1410
1423
* v
1411
1424
*/
1412
- static void hatswitch_decompose (BYTE value , LONG * x , LONG * y )
1425
+ static void hatswitch_decompose (BYTE value , ULONG index , LONG * x , LONG * y )
1413
1426
{
1427
+ value = (index % 2 ) ? (value >> 4 ) : (value & 0x0f );
1414
1428
* x = * y = 0 ;
1415
1429
if (value == 8 || value == 1 || value == 2 ) * y = -1 ;
1416
1430
if (value == 6 || value == 5 || value == 4 ) * y = +1 ;
1417
1431
if (value == 8 || value == 7 || value == 6 ) * x = -1 ;
1418
1432
if (value == 2 || value == 3 || value == 4 ) * x = +1 ;
1419
1433
}
1420
1434
1421
- static void hatswitch_compose (LONG x , LONG y , BYTE * value )
1435
+ static void hatswitch_compose (LONG x , LONG y , BYTE * value , ULONG index )
1422
1436
{
1423
- if (x == 0 && y == 0 ) * value = 0 ;
1424
- else if (x == 0 && y < 0 ) * value = 1 ;
1425
- else if (x > 0 && y < 0 ) * value = 2 ;
1426
- else if (x > 0 && y == 0 ) * value = 3 ;
1427
- else if (x > 0 && y > 0 ) * value = 4 ;
1428
- else if (x == 0 && y > 0 ) * value = 5 ;
1429
- else if (x < 0 && y > 0 ) * value = 6 ;
1430
- else if (x < 0 && y == 0 ) * value = 7 ;
1431
- else if (x < 0 && y < 0 ) * value = 8 ;
1437
+ BYTE new_value = 0 ;
1438
+ if (x == 0 && y == 0 ) new_value = 0 ;
1439
+ else if (x == 0 && y < 0 ) new_value = 1 ;
1440
+ else if (x > 0 && y < 0 ) new_value = 2 ;
1441
+ else if (x > 0 && y == 0 ) new_value = 3 ;
1442
+ else if (x > 0 && y > 0 ) new_value = 4 ;
1443
+ else if (x == 0 && y > 0 ) new_value = 5 ;
1444
+ else if (x < 0 && y > 0 ) new_value = 6 ;
1445
+ else if (x < 0 && y == 0 ) new_value = 7 ;
1446
+ else if (x < 0 && y < 0 ) new_value = 8 ;
1447
+
1448
+ if (index % 2 )
1449
+ {
1450
+ * value &= 0xf ;
1451
+ * value |= new_value << 4 ;
1452
+ }
1453
+ else
1454
+ {
1455
+ * value &= 0xf0 ;
1456
+ * value |= new_value ;
1457
+ }
1432
1458
}
1433
1459
1434
1460
BOOL hid_device_set_hatswitch_x (struct unix_device * iface , ULONG index , LONG new_x )
1435
1461
{
1436
1462
struct hid_device_state * state = & iface -> hid_device_state ;
1437
- ULONG offset = state -> hatswitch_start + index ;
1463
+ ULONG offset = state -> hatswitch_start + index / 2 ;
1438
1464
LONG x , y ;
1439
1465
if (index > state -> hatswitch_count ) return FALSE;
1440
- hatswitch_decompose (state -> report_buf [offset ], & x , & y );
1441
- hatswitch_compose (new_x , y , & state -> report_buf [offset ]);
1466
+ hatswitch_decompose (state -> report_buf [offset ], index , & x , & y );
1467
+ hatswitch_compose (new_x , y , & state -> report_buf [offset ], index );
1442
1468
return TRUE;
1443
1469
}
1444
1470
1445
1471
BOOL hid_device_set_hatswitch_y (struct unix_device * iface , ULONG index , LONG new_y )
1446
1472
{
1447
1473
struct hid_device_state * state = & iface -> hid_device_state ;
1448
- ULONG offset = state -> hatswitch_start + index ;
1474
+ ULONG offset = state -> hatswitch_start + index / 2 ;
1449
1475
LONG x , y ;
1450
1476
if (index > state -> hatswitch_count ) return FALSE;
1451
- hatswitch_decompose (state -> report_buf [offset ], & x , & y );
1452
- hatswitch_compose (x , new_y , & state -> report_buf [offset ]);
1477
+ hatswitch_decompose (state -> report_buf [offset ], index , & x , & y );
1478
+ hatswitch_compose (x , new_y , & state -> report_buf [offset ], index );
1453
1479
return TRUE;
1454
1480
}
1455
1481
1456
1482
BOOL hid_device_move_hatswitch (struct unix_device * iface , ULONG index , LONG x , LONG y )
1457
1483
{
1458
1484
struct hid_device_state * state = & iface -> hid_device_state ;
1459
- ULONG offset = state -> hatswitch_start + index ;
1485
+ ULONG offset = state -> hatswitch_start + index / 2 ;
1460
1486
LONG old_x , old_y ;
1461
1487
if (index > state -> hatswitch_count ) return FALSE;
1462
- hatswitch_decompose (state -> report_buf [offset ], & old_x , & old_y );
1463
- hatswitch_compose (old_x + x , old_y + y , & state -> report_buf [offset ]);
1488
+ hatswitch_decompose (state -> report_buf [offset ], index , & old_x , & old_y );
1489
+ hatswitch_compose (old_x + x , old_y + y , & state -> report_buf [offset ], index );
1464
1490
return TRUE;
1465
1491
}
1466
1492
0 commit comments