@@ -37,6 +37,7 @@ struct lenovo_drvdata_tpkbd {
37
37
};
38
38
39
39
struct lenovo_drvdata_cptkbd {
40
+ u8 middlebutton_state ; /* 0:Up, 1:Down (undecided), 2:Scrolling */
40
41
bool fn_lock ;
41
42
int sensitivity ;
42
43
};
@@ -316,6 +317,53 @@ static int lenovo_raw_event(struct hid_device *hdev,
316
317
return 0 ;
317
318
}
318
319
320
+ static int lenovo_event_cptkbd (struct hid_device * hdev ,
321
+ struct hid_field * field , struct hid_usage * usage , __s32 value )
322
+ {
323
+ struct lenovo_drvdata_cptkbd * cptkbd_data = hid_get_drvdata (hdev );
324
+
325
+ /* "wheel" scroll events */
326
+ if (usage -> type == EV_REL && (usage -> code == REL_WHEEL ||
327
+ usage -> code == REL_HWHEEL )) {
328
+ /* Scroll events disable middle-click event */
329
+ cptkbd_data -> middlebutton_state = 2 ;
330
+ return 0 ;
331
+ }
332
+
333
+ /* Middle click events */
334
+ if (usage -> type == EV_KEY && usage -> code == BTN_MIDDLE ) {
335
+ if (value == 1 ) {
336
+ cptkbd_data -> middlebutton_state = 1 ;
337
+ } else if (value == 0 ) {
338
+ if (cptkbd_data -> middlebutton_state == 1 ) {
339
+ /* No scrolling inbetween, send middle-click */
340
+ input_event (field -> hidinput -> input ,
341
+ EV_KEY , BTN_MIDDLE , 1 );
342
+ input_sync (field -> hidinput -> input );
343
+ input_event (field -> hidinput -> input ,
344
+ EV_KEY , BTN_MIDDLE , 0 );
345
+ input_sync (field -> hidinput -> input );
346
+ }
347
+ cptkbd_data -> middlebutton_state = 0 ;
348
+ }
349
+ return 1 ;
350
+ }
351
+
352
+ return 0 ;
353
+ }
354
+
355
+ static int lenovo_event (struct hid_device * hdev , struct hid_field * field ,
356
+ struct hid_usage * usage , __s32 value )
357
+ {
358
+ switch (hdev -> product ) {
359
+ case USB_DEVICE_ID_LENOVO_CUSBKBD :
360
+ case USB_DEVICE_ID_LENOVO_CBTKBD :
361
+ return lenovo_event_cptkbd (hdev , field , usage , value );
362
+ default :
363
+ return 0 ;
364
+ }
365
+ }
366
+
319
367
static int lenovo_features_set_tpkbd (struct hid_device * hdev )
320
368
{
321
369
struct hid_report * report ;
@@ -708,6 +756,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
708
756
hid_warn (hdev , "Failed to switch middle button: %d\n" , ret );
709
757
710
758
/* Set keyboard settings to known state */
759
+ cptkbd_data -> middlebutton_state = 0 ;
711
760
cptkbd_data -> fn_lock = true;
712
761
cptkbd_data -> sensitivity = 0x05 ;
713
762
lenovo_features_set_cptkbd (hdev );
@@ -835,6 +884,7 @@ static struct hid_driver lenovo_driver = {
835
884
.probe = lenovo_probe ,
836
885
.remove = lenovo_remove ,
837
886
.raw_event = lenovo_raw_event ,
887
+ .event = lenovo_event ,
838
888
.report_fixup = lenovo_report_fixup ,
839
889
};
840
890
module_hid_driver (lenovo_driver );
0 commit comments