Skip to content

Commit

Permalink
Add support for Razer BlackWidow V4 X
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyril Tostivint committed Apr 8, 2024
1 parent fd1e9a7 commit 17699dc
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ The devices below are fully feature supported by OpenRazer, which means all avai
| Razer BlackWidow V4 Pro | 1532:028D |
| Razer DeathStalker V2 Pro (Wireless) | 1532:0290 |
| Razer DeathStalker V2 Pro (Wired) | 1532:0292 |
| Razer BlackWidow V4 X | 1532:0293 |
| Razer Ornata V3 X | 1532:0294 |
| Razer DeathStalker V2 Pro TKL (Wireless) | 1532:0296 |
| Razer DeathStalker V2 Pro TKL (Wired) | 1532:0298 |
Expand Down
21 changes: 21 additions & 0 deletions daemon/openrazer_daemon/hardware/keyboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,27 @@ class RazerBlackWidowV4(_RippleKeyboard):
DEVICE_IMAGE = "https://dl.razerzone.com/src2/13219/13219-1-en-v1.png"


class RazerBlackWidowV4X(_RippleKeyboard):
"""
Class for the Razer BlackWidow V4 X
"""
EVENT_FILE_REGEX = re.compile(r'.*Razer_Razer_BlackWidow_V4_X(-if01)?-event-kbd')

USB_VID = 0x1532
USB_PID = 0x0293
HAS_MATRIX = True
WAVE_DIRS = (1, 2)
MATRIX_DIMS = [8, 23]
METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_wheel_effect', 'set_static_effect', 'set_spectrum_effect',
'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect', 'set_breath_dual_effect',
'set_custom_effect', 'set_key_row', 'get_game_mode', 'set_game_mode', 'get_macro_mode', 'set_macro_mode',
'get_macro_effect', 'set_macro_effect', 'get_macros', 'delete_macro', 'add_macro',
'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
'set_ripple_effect', 'set_ripple_effect_random_colour']

DEVICE_IMAGE = "https://m.media-amazon.com/images/I/71qoXjgRb-L._AC_SL1500_.jpg"


class RazerBlackWidowV4Pro(_RippleKeyboard):
"""
Class for the Razer BlackWidow V4 Pro
Expand Down
24 changes: 24 additions & 0 deletions driver/razerkbd_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ static void razer_get_report_params(struct usb_device *usb_dev, uint *report_ind
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_JP:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
*report_index = 0x02;
*response_index = 0x02;
*wait_min = RAZER_BLACKWIDOW_CHROMA_WAIT_MIN_US;
Expand Down Expand Up @@ -430,6 +431,7 @@ static void razer_set_device_mode(struct razer_kbd_device *device, unsigned char
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED:
case USB_DEVICE_ID_RAZER_ORNATA_V3_X:
Expand Down Expand Up @@ -1157,6 +1159,10 @@ static ssize_t razer_attr_read_device_type(struct device *dev, struct device_att
device_type = "Razer BlackWidow V4\n";
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
device_type = "Razer BlackWidow V4 X\n";
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
device_type = "Razer BlackWidow V4 Pro\n";
break;
Expand Down Expand Up @@ -1579,6 +1585,7 @@ static ssize_t razer_attr_write_matrix_effect_none(struct device *dev, struct de
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_effect_none(VARSTORE, BACKLIGHT_LED);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -1664,6 +1671,7 @@ static ssize_t razer_attr_write_matrix_effect_wave(struct device *dev, struct de
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_effect_wave(VARSTORE, BACKLIGHT_LED, direction);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -1702,6 +1710,7 @@ static ssize_t razer_attr_write_matrix_effect_wheel(struct device *dev, struct d

switch(device->usb_pid) {
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_effect_wheel(VARSTORE, BACKLIGHT_LED, direction);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -1761,6 +1770,7 @@ static ssize_t razer_attr_write_matrix_effect_spectrum(struct device *dev, struc
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLADE_15_BASE_2022:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_effect_spectrum(VARSTORE, BACKLIGHT_LED);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -1835,6 +1845,7 @@ static ssize_t razer_attr_write_matrix_effect_reactive(struct device *dev, struc
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRED:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED:
Expand Down Expand Up @@ -1995,6 +2006,7 @@ static ssize_t razer_attr_write_matrix_effect_static(struct device *dev, struct
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_TK:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRED:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED:
Expand Down Expand Up @@ -2134,6 +2146,7 @@ static ssize_t razer_attr_write_matrix_effect_starlight(struct device *dev, stru
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
if (count == 7) {
request = razer_chroma_extended_matrix_effect_starlight_dual(VARSTORE, BACKLIGHT_LED, buf[0], (struct razer_rgb*)&buf[1], (struct razer_rgb*)&buf[4]);
Expand Down Expand Up @@ -2342,6 +2355,7 @@ static ssize_t razer_attr_write_matrix_effect_breath(struct device *dev, struct
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
if (count == 3) { // Single colour mode
request = razer_chroma_extended_matrix_effect_breathing_single(VARSTORE, BACKLIGHT_LED, (struct razer_rgb*)&buf[0]);
Expand Down Expand Up @@ -2543,6 +2557,7 @@ static ssize_t razer_attr_write_matrix_effect_custom(struct device *dev, struct
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
request = razer_chroma_extended_matrix_effect_custom_frame();
request.transaction_id.id = 0x1F;
break;
Expand Down Expand Up @@ -2685,6 +2700,7 @@ static ssize_t razer_attr_write_matrix_brightness(struct device *dev, struct dev
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_brightness(VARSTORE, BACKLIGHT_LED, brightness);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -2773,6 +2789,7 @@ static ssize_t razer_attr_read_matrix_brightness(struct device *dev, struct devi
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_MINI:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
request = razer_chroma_extended_matrix_get_brightness(VARSTORE, BACKLIGHT_LED);
request.transaction_id.id = 0x1F;
Expand Down Expand Up @@ -2941,6 +2958,7 @@ static ssize_t razer_attr_write_matrix_custom_frame(struct device *dev, struct d
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2_ANALOG:
case USB_DEVICE_ID_RAZER_HUNTSMAN_MINI_ANALOG:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
request = razer_chroma_extended_matrix_set_custom_frame(row_id, start_col, stop_col, (unsigned char*)&buf[offset]);
request.transaction_id.id = 0x1F;
break;
Expand Down Expand Up @@ -3306,6 +3324,7 @@ static int razer_event(struct hid_device *hdev, struct hid_field *field, struct
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
case USB_DEVICE_ID_RAZER_HUNTSMAN_V2:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
Expand Down Expand Up @@ -3623,6 +3642,7 @@ static int razer_raw_event(struct hid_device *hdev, struct hid_report *report, u
switch (device->usb_pid) {
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
case USB_DEVICE_ID_RAZER_ORNATA_V2:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
Expand All @@ -3645,6 +3665,7 @@ static int razer_kbd_input_mapping(struct hid_device *hdev, struct hid_input *hi
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V3_PRO_WIRED:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_ELITE:
case USB_DEVICE_ID_RAZER_DEATHSTALKER_V2:
Expand Down Expand Up @@ -3901,6 +3922,7 @@ static int razer_kbd_probe(struct hid_device *hdev, const struct hid_device_id *
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wheel); // Wheel effect
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_wave); // Wave effect
Expand Down Expand Up @@ -4354,6 +4376,7 @@ static void razer_kbd_disconnect(struct hid_device *hdev)
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X:
case USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO:
device_remove_file(&hdev->dev, &dev_attr_matrix_effect_wheel); // Wheel
device_remove_file(&hdev->dev, &dev_attr_matrix_effect_wave); // Wave effect
Expand Down Expand Up @@ -4687,6 +4710,7 @@ static const struct hid_device_id razer_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRED) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRELESS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V4) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRED) },
{ HID_USB_DEVICE(USB_VENDOR_ID_RAZER,USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRELESS) },
Expand Down
1 change: 1 addition & 0 deletions driver/razerkbd_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_PRO 0x028D
#define USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRELESS 0x0290
#define USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_WIRED 0x0292
#define USB_DEVICE_ID_RAZER_BLACKWIDOW_V4_X 0x0293
#define USB_DEVICE_ID_RAZER_ORNATA_V3_X 0x0294
#define USB_DEVICE_ID_RAZER_DEATHSTALKER_V2 0x0295
#define USB_DEVICE_ID_RAZER_DEATHSTALKER_V2_PRO_TKL_WIRELESS 0x0296
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
<modalias>usb:v1532p028Dd*</modalias>
<modalias>usb:v1532p0290d*</modalias>
<modalias>usb:v1532p0292d*</modalias>
<modalias>usb:v1532p0293d*</modalias>
<modalias>usb:v1532p0294d*</modalias>
<modalias>usb:v1532p0295d*</modalias>
<modalias>usb:v1532p0296d*</modalias>
Expand Down
2 changes: 1 addition & 1 deletion install_files/udev/99-razer.rules
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ATTRS{idProduct}=="0013|0016|0020|0024|0025|0029|002e|002f|0032|0034|0036|0037|0
ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razermouse"

# Keyboards
ATTRS{idProduct}=="010d|010e|010f|0111|0113|0118|011a|011b|011c|0201|0202|0203|0204|0205|0207|0208|0209|020f|0210|0211|0214|0216|0217|021a|021e|021f|0220|0221|0224|0225|0226|0227|0228|022a|022b|022c|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024b|024c|024d|024e|0252|0253|0255|0256|0257|0258|0259|025a|025d|025e|0266|0269|026a|026b|026c|026d|026e|026f|0270|0271|0276|0279|027a|0282|0287|028a|028b|028c|028d|0290|0292|0294|0295|0296|0298|029e|029f|02a0|02a2|0a24", \
ATTRS{idProduct}=="010d|010e|010f|0111|0113|0118|011a|011b|011c|0201|0202|0203|0204|0205|0207|0208|0209|020f|0210|0211|0214|0216|0217|021a|021e|021f|0220|0221|0224|0225|0226|0227|0228|022a|022b|022c|022d|022f|0232|0233|0234|0235|0237|0239|023a|023b|023f|0240|0241|0243|0245|0246|024a|024b|024c|024d|024e|0252|0253|0255|0256|0257|0258|0259|025a|025d|025e|0266|0269|026a|026b|026c|026d|026e|026f|0270|0271|0276|0279|027a|0282|0287|028a|028b|028c|028d|0290|0292|0293|0294|0295|0296|0298|029e|029f|02a0|02a2|0a24", \
ATTRS{idVendor}=="1532", \
ENV{ID_RAZER_CHROMA}="1", ENV{RAZER_DRIVER}="razerkbd"

Expand Down
26 changes: 26 additions & 0 deletions pylib/openrazer/_fake_driver/razerblackwidowv4x.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# DO NOT EDIT THIS FILE!
# You can regenerate all fake driver files with ./scripts/generate_all_fake_drivers.sh -f
[device]
dir_name = 0003:1532:0293.0001
name = Razer BlackWidow V4 X
files = rw,device_mode,0x0000
r,device_serial,XX0000000293
r,device_type,%(name)s
r,firmware_version,v1.0
rw,game_led_state,0
r,kbd_layout,01
rw,macro_led_effect,0
rw,macro_led_state,0
rw,matrix_brightness,0
w,matrix_custom_frame
w,matrix_effect_breath
w,matrix_effect_custom
w,matrix_effect_none
w,matrix_effect_reactive
w,matrix_effect_spectrum
w,matrix_effect_starlight
w,matrix_effect_static
w,matrix_effect_wave
w,matrix_effect_wheel
rw,poll_rate,500
r,version,1.0.0

0 comments on commit 17699dc

Please sign in to comment.