Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F368964
datatypes.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Subscribers
None
datatypes.py
View Options
from
enum
import
IntEnum
from
dataclasses
import
dataclass
from
typing
import
Optional
,
List
from
math
import
floor
class
FusionLightEffect
(
IntEnum
):
Static
=
1
Breathing
=
2
Wave
=
3
Fadeonkeypress
=
4
Marquee
=
5
Ripple
=
6
Flashonkeypress
=
7
Neon
=
8
Rainbowmarquee
=
9
Raindrop
=
10
Circlemarquee
=
11
Hedge
=
12
Rotate
=
13
Custom1
=
51
Custom2
=
52
Custom3
=
53
Custom4
=
54
Custom5
=
55
class
FusionLightColor
(
IntEnum
):
Black
=
0
Red
=
1
Green
=
2
Yellow
=
3
Blue
=
4
Orange
=
5
Purple
=
6
White
=
7
Random
=
8
class
IoneDirection
(
IntEnum
):
Left2Right
=
0
Right2Left
=
1
Up2Down
=
2
Down2Up
=
3
Clockwise
=
4
AntiClockwise
=
5
@dataclass
class
FusionLightData
:
fusion_effect
:
FusionLightEffect
#seems like speed actually means duration here since shorter = faster
fusion_speed
:
int
fusion_brightness
:
int
fusion_color
:
FusionLightColor
fusion_direction
:
int
@dataclass
class
RawInputDevice
:
usUsagePage
:
int
usUsage
:
int
dwFlags
:
int
hwndTarget
:
Optional
[
int
]
=
None
@dataclass
class
RGB
:
red
:
int
green
:
int
blue
:
int
@dataclass
class
PictureMatrix
:
pixels
:
List
[
RGB
]
def
to_bytes
(
self
)
->
bytes
:
if
len
(
self
.
pixels
)
not
in
range
(
106
):
raise
TypeError
(
'Too many pixels!'
)
arr
=
bytearray
(
512
)
for
i
,
pixel
in
enumerate
(
self
.
pixels
):
idx
=
KEY_MATRIX_INDEX_VALUES
[
i
]
*
4
arr
[
idx
:
idx
+
4
]
=
[
0
,
pixel
.
red
,
pixel
.
green
,
pixel
.
blue
]
return
arr
@classmethod
def
from_bytes
(
cls
,
data
:
bytes
)
->
'PictureMatrix'
:
if
len
(
data
)
!=
512
:
raise
TypeError
(
'Invalid payload size!'
)
#the nones should be gone after the loop since KEY_MATRIX_INDEX_VALUES should have all the positions for 105 keys regardless of color
pixels
=
[
None
]
*
105
for
chunk
,
idx
in
enumerate
(
range
(
0
,
len
(
data
),
4
)):
if
chunk
in
[
92
,
7
]:
breakpoint
()
if
chunk
in
KEY_MATRIX_INDEX_VALUES
:
#apparently there are duplicates in the mapping so we need to loop through it
start
=
0
try
:
while
True
:
key_idx
=
KEY_MATRIX_INDEX_VALUES
.
index
(
chunk
,
start
)
start
=
key_idx
+
1
pixels
[
key_idx
]
=
RGB
(
*
data
[
idx
+
1
:
idx
+
4
])
except
ValueError
:
continue
return
PictureMatrix
(
pixels
)
@classmethod
def
pixel_matrix_to_keys
(
cls
,
list
:
List
[
RGB
])
->
'PictureMatrix'
:
"""Turns a proper 19x6 matrix of RGB values into the keyboard matrix by averaging the color over larger keys"""
if
len
(
list
)
!=
19
*
6
:
raise
TypeError
(
'Has to be a 19x6 matrix!'
)
mat
=
[
list
[
i
:
i
+
19
]
for
i
in
range
(
0
,
19
*
6
,
19
)]
def
avg
(
ints
:
List
[
int
]):
return
sum
(
ints
)
//
len
(
ints
)
def
merge
(
pos
:
int
,
length
:
int
,
pixels
:
List
[
RGB
])
->
RGB
:
curr_length
=
1
-
(
pos
-
floor
(
pos
))
#how much of the key is actually in the first pixel location
mat_pos
=
floor
(
pos
)
#first pixel location
length
-=
curr_length
r
,
g
,
b
=
[],
[],
[]
while
(
curr_length
+
length
)
>
0
:
#print(mat_pos, length, curr_length)
#apply weight
r
.
append
(
pixels
[
mat_pos
]
.
red
*
curr_length
)
g
.
append
(
pixels
[
mat_pos
]
.
green
*
curr_length
)
b
.
append
(
pixels
[
mat_pos
]
.
blue
*
curr_length
)
#either it takes a full pixel, or a portion of the pixel if nothing else is left
curr_length
=
min
(
1
,
length
)
length
-=
curr_length
mat_pos
+=
1
return
RGB
(
round
(
avg
(
r
)),
round
(
avg
(
g
)),
round
(
avg
(
b
)))
key_pixels
=
[]
for
pixels
,
weights
in
zip
(
mat
,
KEY_WEIGHT
):
pos
=
0
for
weight
in
weights
:
key_pixels
.
append
(
merge
(
pos
,
weight
,
pixels
))
pos
+=
weight
#account for the 2 vertical keys
def
merge_vertical
(
*
pos
:
int
):
p1
,
p2
=
key_pixels
[
pos
[
0
]],
key_pixels
[
pos
[
1
]],
key_pixels
[
pos
[
1
]]
=
RGB
(
avg
([
p1
.
red
,
p2
.
red
]),
avg
([
p1
.
green
,
p2
.
green
]),
avg
([
p1
.
blue
,
p2
.
blue
]))
#first position is the one to be removed according to KEY_TITLES mapping
key_pixels
.
pop
(
pos
[
0
])
#note the order - it has to be from top of list to bottom of list to avoid repositioning
merge_vertical
(
88
,
102
)
#numpad enter
merge_vertical
(
54
,
71
)
#numpad plus
return
PictureMatrix
(
key_pixels
)
KEY_MATRIX_INDEX_VALUES
=
[
11
,
17
,
23
,
29
,
35
,
41
,
47
,
53
,
59
,
65
,
71
,
77
,
83
,
89
,
95
,
101
,
107
,
113
,
119
,
10
,
16
,
22
,
28
,
34
,
40
,
46
,
52
,
58
,
64
,
70
,
76
,
82
,
94
,
100
,
106
,
112
,
118
,
9
,
15
,
21
,
27
,
33
,
39
,
45
,
51
,
57
,
63
,
69
,
75
,
81
,
87
,
99
,
105
,
111
,
8
,
14
,
20
,
26
,
32
,
38
,
44
,
50
,
56
,
62
,
68
,
74
,
92
,
98
,
104
,
110
,
116
,
7
,
19
,
25
,
31
,
37
,
43
,
49
,
55
,
61
,
67
,
73
,
85
,
91
,
97
,
103
,
109
,
6
,
12
,
18
,
24
,
42
,
60
,
66
,
72
,
84
,
90
,
96
,
102
,
108
,
114
,
86
,
92
,
7
,
13
]
KEY_TITLES
=
[
"btnEsc"
,
"btnF1"
,
"btnF2"
,
"btnF3"
,
"btnF4"
,
"btnF5"
,
"btnF6"
,
"btnF7"
,
"btnF8"
,
"btnF9"
,
"btnF10"
,
"btnF11"
,
"btnF12"
,
"btnPause"
,
"btnDel"
,
"btnHome"
,
"btnPgUp"
,
"btnPgDn"
,
"btnEnd"
,
"btnGrave"
,
"btn1"
,
"btn2"
,
"btn3"
,
"btn4"
,
"btn5"
,
"btn6"
,
"btn7"
,
"btn8"
,
"btn9"
,
"btn0"
,
"btnHyphen"
,
"btnEqual"
,
"btnBackspace"
,
"btnNumLk"
,
"btnSlash2"
,
"btnAsterisk"
,
"btnMinus"
,
"btnTab"
,
"btnQ"
,
"btnW"
,
"btnE"
,
"btnR"
,
"btnT"
,
"btnY"
,
"btnU"
,
"btnI"
,
"btnO"
,
"btnP"
,
"btnLsquarebracket"
,
"btnRsquarebracket"
,
"btnBackslash"
,
"btn_7"
,
"btn_8"
,
"btn_9"
,
"btnCapsLock"
,
"btnA"
,
"btnS"
,
"btnD"
,
"btnF"
,
"btnG"
,
"btnH"
,
"btnJ"
,
"btnK"
,
"btnL"
,
"btnSemicolon"
,
"btnApostrophe"
,
"btnEnter"
,
"btn_4"
,
"btn_5"
,
"btn_6"
,
"btnPlus"
,
"btnLshift"
,
"btnZ"
,
"btnX"
,
"btnC"
,
"btnV"
,
"btnB"
,
"btnN"
,
"btnM"
,
"btnComma"
,
"btnFullstop"
,
"btn_Slash"
,
"btnRshift"
,
"btnUp"
,
"btn_1"
,
"btn_2"
,
"btn_3"
,
"btnLctrl"
,
"btnFn"
,
"btnWin"
,
"btnLalt"
,
"btnSpace"
,
"btnRalt"
,
"btnApp"
,
"btnRctrl"
,
"btnLeft"
,
"btnDown"
,
"btnRight"
,
"btn_0"
,
"btn_Del"
,
"btnEnter2"
,
"btnSharpUk"
,
"btnEnterUk"
,
"btnLshiftUk"
,
"btnSlashUk"
]
KEY_WEIGHT
=
[
[
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
],
[
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
2
,
1
,
1
,
1
,
1
],
[
1.5
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1.5
,
1
,
1
,
1
,
1
],
[
1.8
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
2.2
,
1
,
1
,
1
,
1
],
[
2.3
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1.7
,
1
,
1
,
1
,
1
,
1
],
[
1.2
,
1
,
1
,
1
,
5.2
,
1
,
1
,
1.6
,
1
,
1
,
1
,
1
,
1
,
1
],
]
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Sun, Jul 6, 3:22 AM (21 h, 30 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
79/ea/ea374f4cb376899c74e53fa49b81
Attached To
rAERO GIGABYTE Aero Fusion controller lib
Event Timeline
Log In to Comment