1 module razer.chroma; 2 3 import std.algorithm; 4 import std.array; 5 import std.range; 6 import std.conv; 7 import std.file; 8 import std.path; 9 import std.string; 10 import std.exception; 11 12 import razer.hardware; 13 14 /// A structure representing the size of a chroma device 15 struct Dimension { 16 /// 17 int width; 18 19 /// 20 int height; 21 } 22 23 /// A structure representing a chroma color 24 struct Color { 25 /// 26 ubyte red; 27 28 /// 29 ubyte green; 30 31 /// 32 ubyte blue; 33 34 /// Convert the color to a byte array 35 ubyte[] toArray() { 36 return [red, green, blue]; 37 } 38 } 39 40 /// Return the razer chroma devices that are connected to your computer 41 RazerChromaDevice[] chromaDevices() { 42 return dirEntries("/sys/bus/hid/drivers/razerkbd/", SpanMode.shallow) 43 .filter!(a => buildPath(a, "device_type").exists) 44 .map!(a => new RazerChromaDevice(a)) 45 .array; 46 } 47 48 /// Represents a chroma device and it offers methods for customising 49 /// the led colors 50 class RazerChromaDevice { 51 private { 52 immutable string basePath; 53 } 54 55 RazerDevice device; 56 57 alias device this; 58 59 this(const string basePath) { 60 this.basePath = basePath; 61 this.device = getRazerDevice(basePath.baseName); 62 } 63 64 /// 65 string country() { 66 return readText(buildPath(basePath, "country")).strip; 67 } 68 69 /// 70 string type() { 71 return readText(buildPath(basePath, "device_type")).strip; 72 } 73 74 /// 75 string serial() { 76 return readText(buildPath(basePath, "device_serial")).strip; 77 } 78 79 /// 80 string mode() { 81 return readText(buildPath(basePath, "device_mode")).strip; 82 } 83 84 /// 85 string firmwareVersion() { 86 return readText(buildPath(basePath, "firmware_version")).strip; 87 } 88 89 /// check if the razer logo is illuminated 90 bool logoLedState() { 91 return readText(buildPath(basePath, "logo_led_state")).strip == "1"; 92 } 93 94 /// 95 string driverVersion() { 96 return readText(buildPath(basePath, "version")).strip; 97 } 98 99 /// set a row of colors 100 void setKeyRow(ubyte row, Color[] colors) { 101 enforce(device.hasMatrix, "The device does not support custom effects."); 102 enforce(device.height >= row, "The row is too large."); 103 enforce(device.width >= colors.length, "The color list is too large."); 104 105 ubyte[] colorList = colors.map!"a.toArray".join; 106 ubyte[] list = [ row, 0, colors.length - 1 ].to!(ubyte[]).chain(colorList).array; 107 108 std.file.write(buildPath(basePath, "matrix_custom_frame"), list); 109 } 110 111 /// apply the custom effect 112 void flush() { 113 enforce(device.hasMatrix, "The device does not support custom effects."); 114 std.file.write(buildPath(basePath, "matrix_effect_custom"), "1"); 115 } 116 }