added heatmap
This commit is contained in:
		
							parent
							
								
									413eb916e4
								
							
						
					
					
						commit
						b6faa0bd2d
					
				
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							@ -4,14 +4,17 @@ LDFLAGS=-lm -lusb-1.0
 | 
				
			|||||||
TEX=xelatex
 | 
					TEX=xelatex
 | 
				
			||||||
TEXFLAGS=-file-line-error -interaction nonstopmode
 | 
					TEXFLAGS=-file-line-error -interaction nonstopmode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: doc build/sniffer build/skillerctl
 | 
					all: build/sniffer build/skillerctl build/heatmap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-include $(wildcard build/*.d)
 | 
					-include $(wildcard build/*.d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build/sniffer: build/sniffer.o build/utils.o build/usb.o build/skiller.o
 | 
					build/sniffer: build/sniffer.o build/utils.o build/usb.o build/skiller.o
 | 
				
			||||||
	$(CC) $^ -o $@ $(LDFLAGS)
 | 
						$(CC) $^ -o $@ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build/skillerctl: build/skillerctl.o build/utils.o build/usb.o build/skiller.o
 | 
					build/skillerctl: build/skillerctl.o build/utils.o build/usb.o build/skiller.o build/keys.o
 | 
				
			||||||
 | 
						$(CC) $^ -o $@ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					build/heatmap: build/heatmap.o build/utils.o build/usb.o build/skiller.o build/keys.o
 | 
				
			||||||
	$(CC) $^ -o $@ $(LDFLAGS)
 | 
						$(CC) $^ -o $@ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
doc: doc/skiller-sgk3.pdf
 | 
					doc: doc/skiller-sgk3.pdf
 | 
				
			||||||
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							@ -32,94 +32,85 @@
 | 
				
			|||||||
\node[key] at (12,\row) {00\\63};
 | 
					\node[key] at (12,\row) {00\\63};
 | 
				
			||||||
\node[key, text width=14.5mm] at (13,\row) {00\\66};
 | 
					\node[key, text width=14.5mm] at (13,\row) {00\\66};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\node[key] at (15.25,\row) {F12};
 | 
					\node[key] at (15.25,\row) {00\\69};
 | 
				
			||||||
\node[key] at (16.25,\row) {F12};
 | 
					\node[key] at (16.25,\row) {00\\6c};
 | 
				
			||||||
\node[key] at (17.25,\row) {F12};
 | 
					\node[key] at (17.25,\row) {00\\6f};
 | 
				
			||||||
 | 
					\node[key] at (18.5,\row)  {00\\72};
 | 
				
			||||||
\node[key] at (18.5,\row) {F12};
 | 
					\node[key] at (19.5,\row)  {00\\75};
 | 
				
			||||||
\node[key] at (19.5,\row) {F12};
 | 
					\node[key] at (20.5,\row)  {00\\78};
 | 
				
			||||||
\node[key] at (20.5,\row) {F12};
 | 
					\node[key] at (21.5,\row)  {00\\7A};
 | 
				
			||||||
\node[key] at (21.5,\row) {F12};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
\def\row{2.5}
 | 
					\def\row{2.5}
 | 
				
			||||||
\node[key, text width=10.75mm] at (0,\row) {0000};
 | 
					\node[key, text width=10.75mm] at (0,\row)       {00\\7E};
 | 
				
			||||||
\node[key] at (1.5,\row) {0000};
 | 
					\node[key] at (1.5,\row)                         {00\\81};
 | 
				
			||||||
\node[key] at (2.5,\row) {0003};
 | 
					\node[key] at (2.5,\row)                         {00\\84};
 | 
				
			||||||
\node[key] at (3.5,\row) {0006};
 | 
					\node[key] at (3.5,\row)                         {00\\87};
 | 
				
			||||||
\node[key] at (4.5,\row) {0009};
 | 
					\node[key] at (4.5,\row)                         {00\\8A};
 | 
				
			||||||
\node[key] at (5.5,\row) {000C};
 | 
					\node[key] at (5.5,\row)                         {00\\8D};
 | 
				
			||||||
\node[key] at (6.5,\row) {000F};
 | 
					\node[key] at (6.5,\row)                         {00\\90};
 | 
				
			||||||
\node[key] at (7.5,\row) {F6};
 | 
					\node[key] at (7.5,\row)                         {00\\93};
 | 
				
			||||||
\node[key] at (8.5,\row) {F7};
 | 
					\node[key] at (8.5,\row)                         {00\\96};
 | 
				
			||||||
\node[key] at (9.5,\row) {F8};
 | 
					\node[key] at (9.5,\row)                         {00\\99};
 | 
				
			||||||
\node[key] at (10.5,\row) {F9};
 | 
					\node[key] at (10.5,\row)                        {00\\9C};
 | 
				
			||||||
\node[key] at (11.5,\row) {F10};
 | 
					\node[key] at (11.5,\row)                        {00\\9F};
 | 
				
			||||||
\node[key] at (12.5,\row) {F11};
 | 
					\node[key] at (12.5,\row)                        {00\\A2};
 | 
				
			||||||
\node[key, text width=10.75mm] at (13.5,\row) {F12};
 | 
					\node[key, text width=10.75mm] at (13.5,\row)    {00\\A5};
 | 
				
			||||||
 | 
					\node[key] at (15.25,\row)                       {00\\A8};
 | 
				
			||||||
\node[key] at (15.25,\row) {F12};
 | 
					\node[key] at (16.25,\row)                       {00\\AB};
 | 
				
			||||||
\node[key] at (16.25,\row) {F12};
 | 
					\node[key] at (17.25,\row)                       {00\\AE};
 | 
				
			||||||
\node[key] at (17.25,\row) {F12};
 | 
					\node[key] at (18.5,\row)                        {00\\B1};
 | 
				
			||||||
 | 
					\node[key] at (19.5,\row)                        {00\\B4};
 | 
				
			||||||
\node[key] at (18.5,\row) {F12};
 | 
					\node[key] at (20.5,\row)                        {00\\B7};
 | 
				
			||||||
\node[key] at (19.5,\row) {F12};
 | 
					\node[key, minimum height=12.5mm] at (21.5,\row) {00\\BA};
 | 
				
			||||||
\node[key] at (20.5,\row) {F12};
 | 
					 | 
				
			||||||
\node[key, minimum height=12.5mm] at (21.5,\row) {F12};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
\def\row{3.5}
 | 
					\def\row{3.5}
 | 
				
			||||||
\node[key, text width=13.0mm] at (0,\row) {0000};
 | 
					\node[key, text width=13.0mm] at (0,\row)  {00\\BD};
 | 
				
			||||||
\node[key] at (1.8,\row) {0000};
 | 
					\node[key] at (1.8,\row)                   {00\\C0};
 | 
				
			||||||
\node[key] at (2.8,\row) {0003};
 | 
					\node[key] at (2.8,\row)                   {00\\C3};
 | 
				
			||||||
\node[key] at (3.8,\row) {0006};
 | 
					\node[key] at (3.8,\row)                   {00\\C6};
 | 
				
			||||||
\node[key] at (4.8,\row) {0009};
 | 
					\node[key] at (4.8,\row)                   {00\\C9};
 | 
				
			||||||
\node[key] at (5.8,\row) {000C};
 | 
					\node[key] at (5.8,\row)                   {00\\CC};
 | 
				
			||||||
\node[key] at (6.8,\row) {000F};
 | 
					\node[key] at (6.8,\row)                   {00\\CF};
 | 
				
			||||||
\node[key] at (7.8,\row) {F6};
 | 
					\node[key] at (7.8,\row)                   {00\\D2};
 | 
				
			||||||
\node[key] at (8.8,\row) {F7};
 | 
					\node[key] at (8.8,\row)                   {00\\D5};
 | 
				
			||||||
\node[key] at (9.8,\row) {F8};
 | 
					\node[key] at (9.8,\row)                   {00\\D8};
 | 
				
			||||||
\node[key] at (10.8,\row) {F9};
 | 
					\node[key] at (10.8,\row)                  {00\\DB};
 | 
				
			||||||
\node[key] at (11.8,\row) {F10};
 | 
					\node[key] at (11.8,\row)                  {00\\DE};
 | 
				
			||||||
\node[key, text width=16mm] at (12.8,\row) {F12};
 | 
					\node[key, text width=16mm] at (12.8,\row) {00\\E4};
 | 
				
			||||||
 | 
					\node[key] at (18.5,\row)                  {00\\F0};
 | 
				
			||||||
\node[key] at (18.5,\row) {F12};
 | 
					\node[key] at (19.5,\row)                  {00\\F3};
 | 
				
			||||||
\node[key] at (19.5,\row) {F12};
 | 
					\node[key] at (20.5,\row)                  {00\\F6};
 | 
				
			||||||
\node[key] at (20.5,\row) {F12};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
\def\row{4.5}
 | 
					\def\row{4.5}
 | 
				
			||||||
\node[key, text width=16.75mm] at (0,\row) {0000};
 | 
					\node[key, text width=16.75mm] at (0,\row)       {00\\FC};
 | 
				
			||||||
\node[key] at (2.3,\row) {0000};
 | 
					\node[key] at (2.3,\row)                         {01\\02};
 | 
				
			||||||
\node[key] at (3.3,\row) {0003};
 | 
					\node[key] at (3.3,\row)                         {01\\05};
 | 
				
			||||||
\node[key] at (4.3,\row) {0006};
 | 
					\node[key] at (4.3,\row)                         {01\\08};
 | 
				
			||||||
\node[key] at (5.3,\row) {0009};
 | 
					\node[key] at (5.3,\row)                         {01\\0b};
 | 
				
			||||||
\node[key] at (6.3,\row) {000C};
 | 
					\node[key] at (6.3,\row)                         {01\\0e};
 | 
				
			||||||
\node[key] at (7.3,\row) {000F};
 | 
					\node[key] at (7.3,\row)                         {01\\11};
 | 
				
			||||||
\node[key] at (8.3,\row) {F6};
 | 
					\node[key] at (8.3,\row)                         {01\\14};
 | 
				
			||||||
\node[key] at (9.3,\row) {F7};
 | 
					\node[key] at (9.3,\row)                         {01\\17};
 | 
				
			||||||
\node[key] at (10.3,\row) {F8};
 | 
					\node[key] at (10.3,\row)                        {01\\1a};
 | 
				
			||||||
\node[key] at (11.3,\row) {F9};
 | 
					\node[key] at (11.3,\row)                        {01\\1d};
 | 
				
			||||||
\node[key, text width=19.75mm] at (12.3,\row) {F12};
 | 
					\node[key, text width=19.75mm] at (12.3,\row)    {01\\23};
 | 
				
			||||||
 | 
					\node[key] at (16.25,\row)                       {01\\29};
 | 
				
			||||||
\node[key] at (16.25,\row) {F12};
 | 
					\node[key] at (18.5,\row)                        {01\\2f};
 | 
				
			||||||
 | 
					\node[key] at (19.5,\row)                        {01\\32};
 | 
				
			||||||
\node[key] at (18.5,\row) {F12};
 | 
					\node[key] at (20.5,\row)                        {01\\35};
 | 
				
			||||||
\node[key] at (19.5,\row) {F12};
 | 
					\node[key, minimum height=12.5mm] at (21.5,\row) {01\\38};
 | 
				
			||||||
\node[key] at (20.5,\row) {F12};
 | 
					 | 
				
			||||||
\node[key, minimum height=12.5mm] at (21.5,\row) {F12};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
\def\row{5.5}
 | 
					\def\row{5.5}
 | 
				
			||||||
\node[key, text width=8.875mm] at (0,\row) {0000};
 | 
					\node[key, text width=8.875mm] at (0,\row)     {01\\3b};
 | 
				
			||||||
\node[key, text width=8.875mm] at (1.25,\row) {0000};
 | 
					\node[key, text width=8.875mm] at (1.25,\row)  {01\\3e};
 | 
				
			||||||
\node[key, text width=8.875mm] at (2.5,\row) {0003};
 | 
					\node[key, text width=8.875mm] at (2.5,\row)   {01\\41};
 | 
				
			||||||
\node[key, text width=46.375mm] at (3.75,\row) {0006};
 | 
					\node[key, text width=46.375mm] at (3.75,\row) {01\\44};
 | 
				
			||||||
\node[key, text width=8.875mm] at (10,\row) {F12};
 | 
					\node[key, text width=8.875mm] at (10,\row)    {01\\47};
 | 
				
			||||||
\node[key, text width=8.875mm] at (11.25,\row) {F12};
 | 
					\node[key, text width=8.875mm] at (11.25,\row) {01\\4a};
 | 
				
			||||||
\node[key, text width=8.875mm] at (12.5,\row) {F12};
 | 
					\node[key, text width=8.875mm] at (12.5,\row)  {01\\4d};
 | 
				
			||||||
\node[key, text width=8.875mm] at (13.75,\row) {F12};
 | 
					\node[key, text width=8.875mm] at (13.75,\row) {01\\53};
 | 
				
			||||||
 | 
					\node[key] at (15.25,\row)                     {01\\65};
 | 
				
			||||||
\node[key] at (15.25,\row) {F12};
 | 
					\node[key] at (16.25,\row)                     {01\\68};
 | 
				
			||||||
\node[key] at (16.25,\row) {F12};
 | 
					\node[key] at (17.25,\row)                     {01\\6b};
 | 
				
			||||||
\node[key] at (17.25,\row) {F12};
 | 
					\node[key, text width=14.5mm] at (18.5,\row)   {01\\71};
 | 
				
			||||||
 | 
					\node[key] at (20.5,\row)                      {01\\74};
 | 
				
			||||||
\node[key] at (18.5,\row) {F12};
 | 
					 | 
				
			||||||
\node[key] at (19.5,\row) {F12};
 | 
					 | 
				
			||||||
\node[key] at (20.5,\row) {F12};
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -11,9 +11,11 @@
 | 
				
			|||||||
\usepackage{verbatim}
 | 
					\usepackage{verbatim}
 | 
				
			||||||
\usepackage{amstext}
 | 
					\usepackage{amstext}
 | 
				
			||||||
\usepackage{tikz}
 | 
					\usepackage{tikz}
 | 
				
			||||||
 | 
					\usepackage{siunitx}
 | 
				
			||||||
\usepackage{pgfplots}
 | 
					\usepackage{pgfplots}
 | 
				
			||||||
\usepackage{bytefield}
 | 
					\usepackage{bytefield}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					\sisetup{group-separator={,}}
 | 
				
			||||||
\usetikzlibrary{intersections,calc,positioning,arrows}
 | 
					\usetikzlibrary{intersections,calc,positioning,arrows}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%opening
 | 
					%opening
 | 
				
			||||||
@ -50,7 +52,7 @@
 | 
				
			|||||||
        \begin{bytefield}[bitwidth=4em]{8}
 | 
					        \begin{bytefield}[bitwidth=4em]{8}
 | 
				
			||||||
            \bitheader{0-7} \\
 | 
					            \bitheader{0-7} \\
 | 
				
			||||||
            \bitbox{1}{04h} & \bitbox{2}{checksum} & \bitbox{1}{cmd} & \bitbox{1}{len} & \bitbox{2}{addr} & \bitbox{1}{00h} \\
 | 
					            \bitbox{1}{04h} & \bitbox{2}{checksum} & \bitbox{1}{cmd} & \bitbox{1}{len} & \bitbox{2}{addr} & \bitbox{1}{00h} \\
 | 
				
			||||||
            \wordbox{3}{payload \\ up to len bytes}
 | 
					            \wordbox{3}{payload \\ up to 56 bytes}
 | 
				
			||||||
        \end{bytefield}
 | 
					        \end{bytefield}
 | 
				
			||||||
    \end{figure}
 | 
					    \end{figure}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,7 +80,7 @@
 | 
				
			|||||||
            \texttt{SK\_CMD\_ENABLE\_LED}  & \texttt{02h} & Enables key backlight, takes some time. \\
 | 
					            \texttt{SK\_CMD\_ENABLE\_LED}  & \texttt{02h} & Enables key backlight, takes some time. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_READ\_???}    & \texttt{03h} & Reads some state. \\
 | 
					            \texttt{SK\_CMD\_READ\_???}    & \texttt{03h} & Reads some state. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_READ\_???}    & \texttt{05h} & Reads some state. \\
 | 
					            \texttt{SK\_CMD\_READ\_???}    & \texttt{05h} & Reads some state. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_SET\_MODE}    & \texttt{06h} & Changes keyboard mode or mode settings. \\
 | 
					            \texttt{SK\_CMD\_SET\_PROP}    & \texttt{06h} & Changes keyboard mode or mode settings. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_MAP\_KEYS}    & \texttt{08h} & Writes key mapping to controller. \\
 | 
					            \texttt{SK\_CMD\_MAP\_KEYS}    & \texttt{08h} & Writes key mapping to controller. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_WRITE\_MACRO} & \texttt{0Ah} & Saves macros in controller memory. \\
 | 
					            \texttt{SK\_CMD\_WRITE\_MACRO} & \texttt{0Ah} & Saves macros in controller memory. \\
 | 
				
			||||||
            \texttt{SK\_CMD\_SET\_COLOR}   & \texttt{11h} & Changes LED RGB values in key given keys, or key range. \\
 | 
					            \texttt{SK\_CMD\_SET\_COLOR}   & \texttt{11h} & Changes LED RGB values in key given keys, or key range. \\
 | 
				
			||||||
@ -102,9 +104,87 @@
 | 
				
			|||||||
    This command re-enables all LEDs on keyboard. It's useful when we need to change few values and don't want to 
 | 
					    This command re-enables all LEDs on keyboard. It's useful when we need to change few values and don't want to 
 | 
				
			||||||
    constantly blink diodes. Both operations are quite long to execute, they can took about 1s.
 | 
					    constantly blink diodes. Both operations are quite long to execute, they can took about 1s.
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    \subsection{\texttt{SK\_CMD\_SET\_PROP} (\texttt{06h})}
 | 
				
			||||||
 | 
					    This command is used to change color mode and other settings like brighteness, pulsation direction, polling rate
 | 
				
			||||||
 | 
					    etc. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \subsubsection{Addressing}
 | 
				
			||||||
 | 
					    Changed property is referenced via \texttt{addr}.
 | 
				
			||||||
 | 
					    \begin{table}[H]
 | 
				
			||||||
 | 
					        \begin{tabular}{l|r|l}
 | 
				
			||||||
 | 
					            \textbf{Property} & \textbf{Address} & \textbf{Description} \\ \hline
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_MODE} & \texttt{00h} & Changes backlight program (pulsing, permamant, custom, etc.) \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_BRIGHTNESS} & \texttt{01h} & Sets brihgtness level \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_SPEED} & \texttt{02h} & Sets animation speed \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_DIRECTION} & \texttt{03h} & Sets animation direction \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_RGB} & \texttt{04h} & LGBT promotion \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_COLOR} & \texttt{05h} & Base color \\
 | 
				
			||||||
 | 
					            \texttt{SK\_PROP\_POLLING} & \texttt{0Fh} & Polling rate \\
 | 
				
			||||||
 | 
					        \end{tabular}
 | 
				
			||||||
 | 
					    \end{table}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \subsubsection{Payload}
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_MODE} (\texttt{00h})}
 | 
				
			||||||
 | 
					    Payload is 1-byte long mode identifier, possible modes are listed in table below.
 | 
				
			||||||
 | 
					    \begin{table}[H]
 | 
				
			||||||
 | 
					        \centering
 | 
				
			||||||
 | 
					        \begin{tabular}{l|r|l}
 | 
				
			||||||
 | 
					            \textbf{Identifier}     & \textbf{Value} & \textbf{Name} \\ \hline
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_WAVE} & \texttt{01h} & Wave \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_DRIFT} & \texttt{02h} & Drift \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_SWIRL} & \texttt{03h} & Swirl \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_CHANGE} & \texttt{04h} & color change \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_PULSATING} & \texttt{05h} & pulsating \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_PERMAMENT} & \texttt{06h} & permament \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_EXPLOSION} & \texttt{07h} & Explosion \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_TRIGGER} & \texttt{08h} & Trigger \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_BURST} & \texttt{09h} & Gamma Ray Burst \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_CHAOS} & \texttt{0Ah} & Chaos \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_COSMIC} & \texttt{0Bh} & Cosmic \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_GRADIENT} & \texttt{0Ch} & Gradient \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_TIDE} & \texttt{0Dh} & Tide \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_LIGHTING} & \texttt{0Eh} & Ball Lighting \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_MATRIX} & \texttt{0Fh} & Matrix \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_RICOCHET} & \texttt{10h} & Ricochet \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_RIPPLE} & \texttt{12h} & Ripple \\
 | 
				
			||||||
 | 
					            \texttt{SK\_MODE\_CUSTOM} & \texttt{14h} & Custom
 | 
				
			||||||
 | 
					        \end{tabular}
 | 
				
			||||||
 | 
					    \end{table}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_BRIGHTNESS} (\texttt{01h})}
 | 
				
			||||||
 | 
					    Payload is 1-byte from range \texttt{00h-05h}, where \texttt{00h} means no light at all and \texttt{05h} is the
 | 
				
			||||||
 | 
					    brightest value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_SPEED} (\texttt{02h})}
 | 
				
			||||||
 | 
					    Payload is 1-byte from range \texttt{00h-05h}, where \texttt{00h} is the slowest setting and \texttt{05h} is the 
 | 
				
			||||||
 | 
					    fastest one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_DIRECTION} (\texttt{03h})}
 | 
				
			||||||
 | 
					    Payload 1-byte value desciring direction, \texttt{00} for left to right/top to bottom and \texttt{ffh} for reverse.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_RGB} (\texttt{04h})}
 | 
				
			||||||
 | 
					    Payload is 1-byte long flag, which defines if we should see rainbow (\texttt{01h}) or not (\texttt{00h})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_COLOR} (\texttt{05h})}
 | 
				
			||||||
 | 
					    Payload is 3-byte RGB value describing color used by mode, detailed structure is exactly the same as in
 | 
				
			||||||
 | 
					    \ref{cmd:color:payload}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    \paragraph{\texttt{SK\_PROP\_POLLING} (\texttt{0Fh})}
 | 
				
			||||||
 | 
					    Payload is 1-byte long value identifing used polling rate.
 | 
				
			||||||
 | 
					    \begin{table}[H]
 | 
				
			||||||
 | 
					        \centering
 | 
				
			||||||
 | 
					        \begin{tabular}{l|r|l}
 | 
				
			||||||
 | 
					            \textbf{Identifier}       & \textbf{Value} & \textbf{Polling rate} \\ \hline
 | 
				
			||||||
 | 
					            \texttt{SK\_POLL\_125HZ}  & \texttt{00h}   & \SI{125}{\hertz} \\
 | 
				
			||||||
 | 
					            \texttt{SK\_POLL\_250HZ}  & \texttt{01h}   & \SI{250}{\hertz} \\
 | 
				
			||||||
 | 
					            \texttt{SK\_POLL\_500HZ}  & \texttt{02h}   & \SI{500}{\hertz} \\
 | 
				
			||||||
 | 
					            \texttt{SK\_POLL\_1000HZ} & \texttt{03h}   & \SI{1000}{\hertz} \\
 | 
				
			||||||
 | 
					        \end{tabular}
 | 
				
			||||||
 | 
					    \end{table}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    \subsection{\texttt{SK\_CMD\_SET\_COLOR} (\texttt{11h})}
 | 
					    \subsection{\texttt{SK\_CMD\_SET\_COLOR} (\texttt{11h})}
 | 
				
			||||||
    This command can be used to change color of 1 or few LEDs at once. This operation takes less than 100ms, and
 | 
					    This command can be used to change color of 1 or few LEDs at once. This operation takes less than 100ms, and
 | 
				
			||||||
    refreshes all diodes (in simpler words - they blink). 
 | 
					    refreshes all diodes (in simpler words - they blink). This command only makes sens weh in \texttt{SK\_MODE\_CUSTOM}.
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    \subsubsection{Addressing}
 | 
					    \subsubsection{Addressing}
 | 
				
			||||||
    The \texttt{addr} header value identifies starting address of specific LED in keyboard. Rule of thumb is that keys
 | 
					    The \texttt{addr} header value identifies starting address of specific LED in keyboard. Rule of thumb is that keys
 | 
				
			||||||
@ -129,7 +209,7 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    \end{figure}
 | 
					    \end{figure}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    \subsubsection{Payload}
 | 
					    \subsubsection{Payload} \label{cmd:color:payload}
 | 
				
			||||||
    Payload of this command consist of consecutive RGB values, 1-byte per channel, we could describe this struct like that:
 | 
					    Payload of this command consist of consecutive RGB values, 1-byte per channel, we could describe this struct like that:
 | 
				
			||||||
    \begin{verbatim}
 | 
					    \begin{verbatim}
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										246
									
								
								src/heatmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								src/heatmap.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,246 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					#include "skiller.h"
 | 
				
			||||||
 | 
					#include "usb.h"
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PACKETS_MAX 255
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skillerctl_packet_t packets[255] = {};
 | 
				
			||||||
 | 
					size_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct color_stop {
 | 
				
			||||||
 | 
					    double   value;
 | 
				
			||||||
 | 
					    int16_t r;
 | 
				
			||||||
 | 
					    int16_t g;
 | 
				
			||||||
 | 
					    int16_t b;
 | 
				
			||||||
 | 
					} stops[] = {
 | 
				
			||||||
 | 
					    -INFINITY, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
					    0/6., 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
					    1/6., 0x00, 0x00, 0xFF,
 | 
				
			||||||
 | 
					    2/6., 0x00, 0xFF, 0xFF,
 | 
				
			||||||
 | 
					    3/6., 0x00, 0xFF, 0x00,
 | 
				
			||||||
 | 
					    4/6., 0xFF, 0xFF, 0x00,
 | 
				
			||||||
 | 
					    5/6., 0xFF, 0x00, 0x00,
 | 
				
			||||||
 | 
					    6/6., 0xFF, 0xFF, 0xFF,
 | 
				
			||||||
 | 
					    INFINITY, 0xFF, 0xFF, 0xFF
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int clamp(int min, int value, int max) {
 | 
				
			||||||
 | 
					    return value > max ? max : (value < min ? min : value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t interpolate(double color) {
 | 
				
			||||||
 | 
					    struct color_stop *top = stops;
 | 
				
			||||||
 | 
					    struct color_stop *bottom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (top->value < color) top++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bottom = top - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double d = (color - bottom->value) / (top->value - bottom->value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (clamp(0x00, bottom->r + (top->r - bottom->r)  * d, 0xFF) & 0xFF)
 | 
				
			||||||
 | 
					         + ((clamp(0x00, bottom->g + (top->g - bottom->g) * d, 0xFF) & 0xFF) << 8)
 | 
				
			||||||
 | 
					         + ((clamp(0x00, bottom->b + (top->b - bottom->b) * d, 0xFF) & 0xFF) << 16)
 | 
				
			||||||
 | 
					         ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t mapping[] = {
 | 
				
			||||||
 | 
					    ['`']   = SK_KEY_TILDE,
 | 
				
			||||||
 | 
					    ['~']   = SK_KEY_TILDE,
 | 
				
			||||||
 | 
					    ['1']   = SK_KEY_1,
 | 
				
			||||||
 | 
					    ['!']   = SK_KEY_1,
 | 
				
			||||||
 | 
					    ['2']   = SK_KEY_2,
 | 
				
			||||||
 | 
					    ['@']   = SK_KEY_2,
 | 
				
			||||||
 | 
					    ['3']   = SK_KEY_3,
 | 
				
			||||||
 | 
					    ['#']   = SK_KEY_3,
 | 
				
			||||||
 | 
					    ['4']   = SK_KEY_4,
 | 
				
			||||||
 | 
					    ['$']   = SK_KEY_4,
 | 
				
			||||||
 | 
					    ['5']   = SK_KEY_5,
 | 
				
			||||||
 | 
					    ['%']   = SK_KEY_5,
 | 
				
			||||||
 | 
					    ['6']   = SK_KEY_6,
 | 
				
			||||||
 | 
					    ['^']   = SK_KEY_6,
 | 
				
			||||||
 | 
					    ['7']   = SK_KEY_7,
 | 
				
			||||||
 | 
					    ['&']   = SK_KEY_7,
 | 
				
			||||||
 | 
					    ['8']   = SK_KEY_8,
 | 
				
			||||||
 | 
					    ['*']   = SK_KEY_8,
 | 
				
			||||||
 | 
					    ['9']   = SK_KEY_9,
 | 
				
			||||||
 | 
					    ['(']   = SK_KEY_9,
 | 
				
			||||||
 | 
					    ['0']   = SK_KEY_0,
 | 
				
			||||||
 | 
					    [')']   = SK_KEY_0,
 | 
				
			||||||
 | 
					    ['-']   = SK_KEY_MINUS,
 | 
				
			||||||
 | 
					    ['_']   = SK_KEY_MINUS,
 | 
				
			||||||
 | 
					    ['=']   = SK_KEY_EQUALS,
 | 
				
			||||||
 | 
					    ['+']   = SK_KEY_EQUALS,
 | 
				
			||||||
 | 
					    ['q']   = SK_KEY_Q,
 | 
				
			||||||
 | 
					    ['Q']   = SK_KEY_Q,
 | 
				
			||||||
 | 
					    ['w']   = SK_KEY_W,
 | 
				
			||||||
 | 
					    ['W']   = SK_KEY_W,
 | 
				
			||||||
 | 
					    ['e']   = SK_KEY_E,
 | 
				
			||||||
 | 
					    ['E']   = SK_KEY_E,
 | 
				
			||||||
 | 
					    ['r']   = SK_KEY_R,
 | 
				
			||||||
 | 
					    ['R']   = SK_KEY_R,
 | 
				
			||||||
 | 
					    ['t']   = SK_KEY_T,
 | 
				
			||||||
 | 
					    ['T']   = SK_KEY_T,
 | 
				
			||||||
 | 
					    ['y']   = SK_KEY_Y,
 | 
				
			||||||
 | 
					    ['Y']   = SK_KEY_Y,
 | 
				
			||||||
 | 
					    ['u']   = SK_KEY_U,
 | 
				
			||||||
 | 
					    ['U']   = SK_KEY_U,
 | 
				
			||||||
 | 
					    ['i']   = SK_KEY_I,
 | 
				
			||||||
 | 
					    ['I']   = SK_KEY_I,
 | 
				
			||||||
 | 
					    ['o']   = SK_KEY_O,
 | 
				
			||||||
 | 
					    ['O']   = SK_KEY_O,
 | 
				
			||||||
 | 
					    ['p']   = SK_KEY_P,
 | 
				
			||||||
 | 
					    ['P']   = SK_KEY_P,
 | 
				
			||||||
 | 
					    ['[']   = SK_KEY_OPEN_BRACKET,
 | 
				
			||||||
 | 
					    ['{']   = SK_KEY_OPEN_BRACKET,
 | 
				
			||||||
 | 
					    [']']   = SK_KEY_CLOSE_BRACKET,
 | 
				
			||||||
 | 
					    ['}']   = SK_KEY_CLOSE_BRACKET,
 | 
				
			||||||
 | 
					    ['\\']  = SK_KEY_BACKSLASH,
 | 
				
			||||||
 | 
					    ['|']   = SK_KEY_BACKSLASH,
 | 
				
			||||||
 | 
					    ['a']   = SK_KEY_A,
 | 
				
			||||||
 | 
					    ['A']   = SK_KEY_A,
 | 
				
			||||||
 | 
					    ['s']   = SK_KEY_S,
 | 
				
			||||||
 | 
					    ['S']   = SK_KEY_S,
 | 
				
			||||||
 | 
					    ['d']   = SK_KEY_D,
 | 
				
			||||||
 | 
					    ['D']   = SK_KEY_D,
 | 
				
			||||||
 | 
					    ['f']   = SK_KEY_F,
 | 
				
			||||||
 | 
					    ['F']   = SK_KEY_F,
 | 
				
			||||||
 | 
					    ['g']   = SK_KEY_G,
 | 
				
			||||||
 | 
					    ['G']   = SK_KEY_G,
 | 
				
			||||||
 | 
					    ['h']   = SK_KEY_H,
 | 
				
			||||||
 | 
					    ['H']   = SK_KEY_H,
 | 
				
			||||||
 | 
					    ['j']   = SK_KEY_J,
 | 
				
			||||||
 | 
					    ['J']   = SK_KEY_J,
 | 
				
			||||||
 | 
					    ['k']   = SK_KEY_K,
 | 
				
			||||||
 | 
					    ['K']   = SK_KEY_K,
 | 
				
			||||||
 | 
					    ['l']   = SK_KEY_L,
 | 
				
			||||||
 | 
					    ['L']   = SK_KEY_L,
 | 
				
			||||||
 | 
					    [';']   = SK_KEY_COLON,
 | 
				
			||||||
 | 
					    [':']   = SK_KEY_COLON,
 | 
				
			||||||
 | 
					    ['\'']  = SK_KEY_QUOTE,
 | 
				
			||||||
 | 
					    ['"']   = SK_KEY_QUOTE,
 | 
				
			||||||
 | 
					    ['\n']  = SK_KEY_ENTER,
 | 
				
			||||||
 | 
					    [' ']   = SK_KEY_SPACE,
 | 
				
			||||||
 | 
					    ['z']   = SK_KEY_Z,
 | 
				
			||||||
 | 
					    ['Z']   = SK_KEY_Z,
 | 
				
			||||||
 | 
					    ['x']   = SK_KEY_X,
 | 
				
			||||||
 | 
					    ['X']   = SK_KEY_X,
 | 
				
			||||||
 | 
					    ['c']   = SK_KEY_C,
 | 
				
			||||||
 | 
					    ['C']   = SK_KEY_C,
 | 
				
			||||||
 | 
					    ['v']   = SK_KEY_V,
 | 
				
			||||||
 | 
					    ['V']   = SK_KEY_V,
 | 
				
			||||||
 | 
					    ['b']   = SK_KEY_B,
 | 
				
			||||||
 | 
					    ['B']   = SK_KEY_B,
 | 
				
			||||||
 | 
					    ['n']   = SK_KEY_N,
 | 
				
			||||||
 | 
					    ['N']   = SK_KEY_N,
 | 
				
			||||||
 | 
					    ['m']   = SK_KEY_M,
 | 
				
			||||||
 | 
					    ['M']   = SK_KEY_M,
 | 
				
			||||||
 | 
					    [',']   = SK_KEY_COMMA,
 | 
				
			||||||
 | 
					    ['<']   = SK_KEY_COMMA,
 | 
				
			||||||
 | 
					    ['.']   = SK_KEY_DOT,
 | 
				
			||||||
 | 
					    ['>']   = SK_KEY_DOT,
 | 
				
			||||||
 | 
					    ['/']   = SK_KEY_SLASH,
 | 
				
			||||||
 | 
					    ['?']   = SK_KEY_SLASH,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					double heatmap[SK_LIMIT_KEY] = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void normalize_heatmap()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    double max = 1.0, min = 0.0;
 | 
				
			||||||
 | 
					    for (int i = 0; i < SK_LIMIT_KEY; i += 3) {
 | 
				
			||||||
 | 
					        max = max > heatmap[i] ? max : heatmap[i];
 | 
				
			||||||
 | 
					        min = min >= 1.0 && min < heatmap[i] ? min : heatmap[i]; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < SK_LIMIT_KEY; i += 3) {
 | 
				
			||||||
 | 
					        heatmap[i] /= (max - min);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void make_row(skillerctl_keyaddr_t low, skillerctl_keyaddr_t high) {
 | 
				
			||||||
 | 
					    uint32_t colors[18] = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned j = 0;
 | 
				
			||||||
 | 
					    for (skillerctl_keyaddr_t i = low; i <= high; i += 3, j++) {
 | 
				
			||||||
 | 
					        printf("Key: %s heat: %lf color: #%06x\n", skillerctl_keystr(i), heatmap[i], interpolate(heatmap[i]));
 | 
				
			||||||
 | 
					        colors[j] = interpolate(heatmap[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    skillerctl_color_batch_command(packets + count++, low, colors, (high - low) / 3 + 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void make_packets()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    count = 0;
 | 
				
			||||||
 | 
					    skillerctl_disable_led_command(packets + count++);
 | 
				
			||||||
 | 
					    make_row(SK_KEY_TILDE, SK_KEY_EQUALS);
 | 
				
			||||||
 | 
					    make_row(SK_KEY_Q, SK_KEY_BACKSLASH);
 | 
				
			||||||
 | 
					    make_row(SK_KEY_A, SK_KEY_ENTER);
 | 
				
			||||||
 | 
					    make_row(SK_KEY_Z, SK_KEY_SLASH);
 | 
				
			||||||
 | 
					    skillerctl_color_command(packets + count++, SK_KEY_SPACE, interpolate(heatmap[SK_KEY_SPACE]));
 | 
				
			||||||
 | 
					    skillerctl_enable_led_command(packets + count++);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handle_input(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char c = getc(stdin);
 | 
				
			||||||
 | 
					    skillerctl_keyaddr_t key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (c != EOF) {
 | 
				
			||||||
 | 
					        if ((key = mapping[c])) {
 | 
				
			||||||
 | 
					            heatmap[key] += 1.;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        c = getc(stdin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    normalize_heatmap();
 | 
				
			||||||
 | 
					    make_packets();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handle_logic(libusb_device *skiller)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    libusb_device_handle *handle;
 | 
				
			||||||
 | 
					    skillerctl_packet_t packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (skiller == NULL) {
 | 
				
			||||||
 | 
					        printf("Cannot found compatibile keyboard, is it connected?\n");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (libusb_open(skiller, &handle) != LIBUSB_SUCCESS) {
 | 
				
			||||||
 | 
					        printf("Cannot open device, try with sudo.\n");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    libusb_detach_kernel_driver(handle, 1);
 | 
				
			||||||
 | 
					    libusb_claim_interface(handle, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					        skillerctl_send_command(handle, packets + i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    libusb_release_interface(handle, 1);
 | 
				
			||||||
 | 
					    libusb_attach_kernel_driver(handle, 1);
 | 
				
			||||||
 | 
					    libusb_close(handle);
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    libusb_device **list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    libusb_init(NULL);
 | 
				
			||||||
 | 
					    size_t count = libusb_get_device_list(NULL, &list);
 | 
				
			||||||
 | 
					    libusb_device *skiller = skillerctl_find_device(list, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    handle_input(argc, argv);
 | 
				
			||||||
 | 
					    handle_logic(skiller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    libusb_free_device_list(list, 1);
 | 
				
			||||||
 | 
					    libusb_exit(NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										247
									
								
								src/keys.c
									
									
									
									
									
								
							
							
						
						
									
										247
									
								
								src/keys.c
									
									
									
									
									
								
							@ -1,30 +1,241 @@
 | 
				
			|||||||
#include "keys.h"
 | 
					#include "keys.h"
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					skillerctl_name_value_pair_t keycodeLUT[] = {
 | 
				
			||||||
    skillerctl_keyaddr_t addr;
 | 
					 | 
				
			||||||
    char*                name;
 | 
					 | 
				
			||||||
} keyaddr_name_pair; 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
keyaddr_name_pair keycodeLUT[] = {
 | 
					 | 
				
			||||||
    SK_KEY_ESC,            "esc",
 | 
					    SK_KEY_ESC,            "esc",
 | 
				
			||||||
    SK_KEY_F1,             "f1",
 | 
					    SK_KEY_F1,             "f1",
 | 
				
			||||||
    SK_KEY_F2,             "f2",
 | 
					    SK_KEY_F2,             "f2",
 | 
				
			||||||
 | 
					    SK_KEY_F3,             "f3",
 | 
				
			||||||
 | 
					    SK_KEY_F4,             "f4",
 | 
				
			||||||
 | 
					    SK_KEY_F5,             "f5",
 | 
				
			||||||
 | 
					    SK_KEY_F6,             "f6",
 | 
				
			||||||
 | 
					    SK_KEY_F7,             "f7",
 | 
				
			||||||
 | 
					    SK_KEY_F8,             "f8",
 | 
				
			||||||
 | 
					    SK_KEY_F9,             "f9",
 | 
				
			||||||
 | 
					    SK_KEY_F10,            "f10",
 | 
				
			||||||
 | 
					    SK_KEY_F11,            "f11",
 | 
				
			||||||
 | 
					    SK_KEY_F12,            "f12",
 | 
				
			||||||
 | 
					    SK_KEY_PRTSC,          "prtsc",
 | 
				
			||||||
 | 
					    SK_KEY_PRTSC,          "printscreen",
 | 
				
			||||||
 | 
					    SK_KEY_PRTSC,          "prtscr",
 | 
				
			||||||
 | 
					    SK_KEY_SCROLL_LOCK,    "scrollock",
 | 
				
			||||||
 | 
					    SK_KEY_BREAK,          "pause",
 | 
				
			||||||
 | 
					    SK_KEY_BREAK,          "break",
 | 
				
			||||||
 | 
					    SK_KEY_TILDE,          "~",
 | 
				
			||||||
 | 
					    SK_KEY_TILDE,          "tilde",
 | 
				
			||||||
 | 
					    SK_KEY_1,              "1",
 | 
				
			||||||
 | 
					    SK_KEY_2,              "2",
 | 
				
			||||||
 | 
					    SK_KEY_3,              "3",
 | 
				
			||||||
 | 
					    SK_KEY_4,              "4",
 | 
				
			||||||
 | 
					    SK_KEY_5,              "5",
 | 
				
			||||||
 | 
					    SK_KEY_6,              "6",
 | 
				
			||||||
 | 
					    SK_KEY_7,              "7",
 | 
				
			||||||
 | 
					    SK_KEY_8,              "8",
 | 
				
			||||||
 | 
					    SK_KEY_9,              "9",
 | 
				
			||||||
 | 
					    SK_KEY_0,              "0",
 | 
				
			||||||
 | 
					    SK_KEY_MINUS,          "-",
 | 
				
			||||||
 | 
					    SK_KEY_EQUALS,         "=",
 | 
				
			||||||
 | 
					    SK_KEY_BACKSPACE,      "backspace",
 | 
				
			||||||
 | 
					    SK_KEY_INSERT,         "insert",
 | 
				
			||||||
 | 
					    SK_KEY_HOME,           "home",
 | 
				
			||||||
 | 
					    SK_KEY_PGUP,           "pgup",
 | 
				
			||||||
 | 
					    SK_KEY_NUMLOCK,        "numlock",
 | 
				
			||||||
 | 
					    SK_KEY_NUMDIV,         "numdiv",
 | 
				
			||||||
 | 
					    SK_KEY_NUMASTERISK,    "numasterisk",
 | 
				
			||||||
 | 
					    SK_KEY_NUMMINUS,       "numminus",
 | 
				
			||||||
 | 
					    SK_KEY_TAB,            "tab",
 | 
				
			||||||
 | 
					    SK_KEY_Q,              "q",
 | 
				
			||||||
 | 
					    SK_KEY_W,              "w",
 | 
				
			||||||
 | 
					    SK_KEY_E,              "e",
 | 
				
			||||||
 | 
					    SK_KEY_R,              "r",
 | 
				
			||||||
 | 
					    SK_KEY_T,              "t",
 | 
				
			||||||
 | 
					    SK_KEY_Y,              "y",
 | 
				
			||||||
 | 
					    SK_KEY_U,              "u",
 | 
				
			||||||
 | 
					    SK_KEY_I,              "i",
 | 
				
			||||||
 | 
					    SK_KEY_O,              "o",
 | 
				
			||||||
 | 
					    SK_KEY_P,              "p",
 | 
				
			||||||
 | 
					    SK_KEY_OPEN_BRACKET,   "[",
 | 
				
			||||||
 | 
					    SK_KEY_CLOSE_BRACKET,  "]",
 | 
				
			||||||
 | 
					    SK_KEY_BACKSLASH,      "]",
 | 
				
			||||||
 | 
					    SK_KEY_DELETE,         "delete",
 | 
				
			||||||
 | 
					    SK_KEY_DELETE,         "del",
 | 
				
			||||||
 | 
					    SK_KEY_END,            "end",
 | 
				
			||||||
 | 
					    SK_KEY_PGDOWN,         "pgdown",
 | 
				
			||||||
 | 
					    SK_KEY_NUM7,           "num7",
 | 
				
			||||||
 | 
					    SK_KEY_NUM8,           "num8",
 | 
				
			||||||
 | 
					    SK_KEY_NUM9,           "num9",
 | 
				
			||||||
 | 
					    SK_KEY_NUMPLUS,        "numplus",
 | 
				
			||||||
 | 
					    SK_KEY_CAPSLOCK,       "caps",
 | 
				
			||||||
 | 
					    SK_KEY_CAPSLOCK,       "capslock",
 | 
				
			||||||
 | 
					    SK_KEY_A,              "a",
 | 
				
			||||||
 | 
					    SK_KEY_S,              "s",
 | 
				
			||||||
 | 
					    SK_KEY_D,              "d",
 | 
				
			||||||
 | 
					    SK_KEY_F,              "f",
 | 
				
			||||||
 | 
					    SK_KEY_G,              "g",
 | 
				
			||||||
 | 
					    SK_KEY_H,              "h",
 | 
				
			||||||
 | 
					    SK_KEY_J,              "j",
 | 
				
			||||||
 | 
					    SK_KEY_K,              "k",
 | 
				
			||||||
 | 
					    SK_KEY_L,              "l",
 | 
				
			||||||
 | 
					    SK_KEY_COLON,          ";",
 | 
				
			||||||
 | 
					    SK_KEY_QUOTE,          "'",
 | 
				
			||||||
 | 
					    SK_KEY_ENTER,          "enter",
 | 
				
			||||||
 | 
					    SK_KEY_NUM4,           "num4",
 | 
				
			||||||
 | 
					    SK_KEY_NUM5,           "num5",
 | 
				
			||||||
 | 
					    SK_KEY_NUM6,           "num6",
 | 
				
			||||||
 | 
					    SK_KEY_LSHIFT,         "lshift",
 | 
				
			||||||
 | 
					    SK_KEY_Z,              "z",
 | 
				
			||||||
 | 
					    SK_KEY_X,              "x",
 | 
				
			||||||
 | 
					    SK_KEY_C,              "c",
 | 
				
			||||||
 | 
					    SK_KEY_V,              "v",
 | 
				
			||||||
 | 
					    SK_KEY_B,              "b",
 | 
				
			||||||
 | 
					    SK_KEY_N,              "n",
 | 
				
			||||||
 | 
					    SK_KEY_M,              "m",
 | 
				
			||||||
 | 
					    SK_KEY_COMMA,          ",",
 | 
				
			||||||
 | 
					    SK_KEY_DOT,            ".",
 | 
				
			||||||
 | 
					    SK_KEY_SLASH,          "/",
 | 
				
			||||||
 | 
					    SK_KEY_RSHIFT,         "rshift",
 | 
				
			||||||
 | 
					    SK_KEY_UP,             "up",
 | 
				
			||||||
 | 
					    SK_KEY_NUM1,           "num1",
 | 
				
			||||||
 | 
					    SK_KEY_NUM2,           "num2",
 | 
				
			||||||
 | 
					    SK_KEY_NUM3,           "num3",
 | 
				
			||||||
 | 
					    SK_KEY_NUMENTER,       "numenter",
 | 
				
			||||||
 | 
					    SK_KEY_LCTRL,          "lctrl",
 | 
				
			||||||
 | 
					    SK_KEY_LWIN,           "win",
 | 
				
			||||||
 | 
					    SK_KEY_LWIN,           "super",
 | 
				
			||||||
 | 
					    SK_KEY_LALT,           "lalt",
 | 
				
			||||||
 | 
					    SK_KEY_SPACE,          "space",
 | 
				
			||||||
 | 
					    SK_KEY_ALTGR,          "altgr",
 | 
				
			||||||
 | 
					    SK_KEY_ALTGR,          "ralt",
 | 
				
			||||||
 | 
					    SK_KEY_SHARKOON,       "sharkoon",
 | 
				
			||||||
 | 
					    SK_KEY_MENU,           "menu",
 | 
				
			||||||
 | 
					    SK_KEY_RCTRL,          "rctrl",
 | 
				
			||||||
 | 
					    SK_KEY_LEFT,           "left",
 | 
				
			||||||
 | 
					    SK_KEY_DOWN,           "down",
 | 
				
			||||||
 | 
					    SK_KEY_RIGHT,          "right",
 | 
				
			||||||
 | 
					    SK_KEY_NUM0,           "num0",
 | 
				
			||||||
 | 
					    SK_KEY_LWIN,           "lwin",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skillerctl_keyaddr_t skillerctl_keyaddr(const char* name)
 | 
					skillerctl_keyaddr_t skillerctl_keyaddr(const char* name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    size_t n = sizeof(keycodeLUT) / sizeof(keyaddr_name_pair); 
 | 
					    return skillerctl_lut_search(
 | 
				
			||||||
    keyaddr_name_pair *current;
 | 
					            keycodeLUT,
 | 
				
			||||||
        
 | 
					            sizeof(keycodeLUT) / sizeof(skillerctl_name_value_pair_t), 
 | 
				
			||||||
    for (int i = 0; i < n; i++) {
 | 
					            name
 | 
				
			||||||
        current = keycodeLUT + i;
 | 
					   );
 | 
				
			||||||
          
 | 
					}
 | 
				
			||||||
        if (strcmp(current->name, name) == 0) {
 | 
					
 | 
				
			||||||
            return current->addr;
 | 
					char* skillerctl_keystr(skillerctl_keyaddr_t key)
 | 
				
			||||||
        }
 | 
					{
 | 
				
			||||||
    }
 | 
					    switch (key) {
 | 
				
			||||||
 | 
					        case SK_KEY_BAD: return "SK_KEY_BAD";
 | 
				
			||||||
    return SK_KEY_BAD;
 | 
					        case SK_KEY_ESC: return "SK_KEY_ESC";
 | 
				
			||||||
 | 
					        case SK_KEY_F1: return "SK_KEY_F1";
 | 
				
			||||||
 | 
					        case SK_KEY_F2: return "SK_KEY_F2";
 | 
				
			||||||
 | 
					        case SK_KEY_F3: return "SK_KEY_F3";
 | 
				
			||||||
 | 
					        case SK_KEY_F4: return "SK_KEY_F4";
 | 
				
			||||||
 | 
					        case SK_KEY_F5: return "SK_KEY_F5";
 | 
				
			||||||
 | 
					        case SK_KEY_F6: return "SK_KEY_F6";
 | 
				
			||||||
 | 
					        case SK_KEY_F7: return "SK_KEY_F7";
 | 
				
			||||||
 | 
					        case SK_KEY_F8: return "SK_KEY_F8";
 | 
				
			||||||
 | 
					        case SK_KEY_F9: return "SK_KEY_F9";
 | 
				
			||||||
 | 
					        case SK_KEY_F10: return "SK_KEY_F10";
 | 
				
			||||||
 | 
					        case SK_KEY_F11: return "SK_KEY_F11";
 | 
				
			||||||
 | 
					        case SK_KEY_F12: return "SK_KEY_F12";
 | 
				
			||||||
 | 
					        case SK_KEY_PRTSC: return "SK_KEY_PRTSC";
 | 
				
			||||||
 | 
					        case SK_KEY_SCROLL_LOCK: return "SK_KEY_SCROLL_LOCK";
 | 
				
			||||||
 | 
					        case SK_KEY_BREAK: return "SK_KEY_BREAK";
 | 
				
			||||||
 | 
					        case SK_KEY_TILDE: return "SK_KEY_TILDE";
 | 
				
			||||||
 | 
					        case SK_KEY_1: return "SK_KEY_1";
 | 
				
			||||||
 | 
					        case SK_KEY_2: return "SK_KEY_2";
 | 
				
			||||||
 | 
					        case SK_KEY_3: return "SK_KEY_3";
 | 
				
			||||||
 | 
					        case SK_KEY_4: return "SK_KEY_4";
 | 
				
			||||||
 | 
					        case SK_KEY_5: return "SK_KEY_5";
 | 
				
			||||||
 | 
					        case SK_KEY_6: return "SK_KEY_6";
 | 
				
			||||||
 | 
					        case SK_KEY_7: return "SK_KEY_7";
 | 
				
			||||||
 | 
					        case SK_KEY_8: return "SK_KEY_8";
 | 
				
			||||||
 | 
					        case SK_KEY_9: return "SK_KEY_9";
 | 
				
			||||||
 | 
					        case SK_KEY_0: return "SK_KEY_0";
 | 
				
			||||||
 | 
					        case SK_KEY_MINUS: return "SK_KEY_MINUS";
 | 
				
			||||||
 | 
					        case SK_KEY_EQUALS: return "SK_KEY_EQUALS";
 | 
				
			||||||
 | 
					        case SK_KEY_BACKSPACE: return "SK_KEY_BACKSPACE";
 | 
				
			||||||
 | 
					        case SK_KEY_INSERT: return "SK_KEY_INSERT";
 | 
				
			||||||
 | 
					        case SK_KEY_HOME: return "SK_KEY_HOME";
 | 
				
			||||||
 | 
					        case SK_KEY_PGUP: return "SK_KEY_PGUP";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMLOCK: return "SK_KEY_NUMLOCK";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMDIV: return "SK_KEY_NUMDIV";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMASTERISK: return "SK_KEY_NUMASTERISK";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMMINUS: return "SK_KEY_NUMMINUS";
 | 
				
			||||||
 | 
					        case SK_KEY_TAB: return "SK_KEY_TAB";
 | 
				
			||||||
 | 
					        case SK_KEY_Q: return "SK_KEY_Q";
 | 
				
			||||||
 | 
					        case SK_KEY_W: return "SK_KEY_W";
 | 
				
			||||||
 | 
					        case SK_KEY_E: return "SK_KEY_E";
 | 
				
			||||||
 | 
					        case SK_KEY_R: return "SK_KEY_R";
 | 
				
			||||||
 | 
					        case SK_KEY_T: return "SK_KEY_T";
 | 
				
			||||||
 | 
					        case SK_KEY_Y: return "SK_KEY_Y";
 | 
				
			||||||
 | 
					        case SK_KEY_U: return "SK_KEY_U";
 | 
				
			||||||
 | 
					        case SK_KEY_I: return "SK_KEY_I";
 | 
				
			||||||
 | 
					        case SK_KEY_O: return "SK_KEY_O";
 | 
				
			||||||
 | 
					        case SK_KEY_P: return "SK_KEY_P";
 | 
				
			||||||
 | 
					        case SK_KEY_OPEN_BRACKET: return "SK_KEY_OPEN_BRACKET";
 | 
				
			||||||
 | 
					        case SK_KEY_CLOSE_BRACKET: return "SK_KEY_CLOSE_BRACKET";
 | 
				
			||||||
 | 
					        case SK_KEY_BACKSLASH: return "SK_KEY_BACKSLASH";
 | 
				
			||||||
 | 
					        case SK_KEY_DELETE: return "SK_KEY_DELETE";
 | 
				
			||||||
 | 
					        case SK_KEY_END: return "SK_KEY_END";
 | 
				
			||||||
 | 
					        case SK_KEY_PGDOWN: return "SK_KEY_PGDOWN";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM7: return "SK_KEY_NUM7";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM8: return "SK_KEY_NUM8";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM9: return "SK_KEY_NUM9";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMPLUS: return "SK_KEY_NUMPLUS";
 | 
				
			||||||
 | 
					        case SK_KEY_CAPSLOCK: return "SK_KEY_CAPSLOCK";
 | 
				
			||||||
 | 
					        case SK_KEY_A: return "SK_KEY_A";
 | 
				
			||||||
 | 
					        case SK_KEY_S: return "SK_KEY_S";
 | 
				
			||||||
 | 
					        case SK_KEY_D: return "SK_KEY_D";
 | 
				
			||||||
 | 
					        case SK_KEY_F: return "SK_KEY_F";
 | 
				
			||||||
 | 
					        case SK_KEY_G: return "SK_KEY_G";
 | 
				
			||||||
 | 
					        case SK_KEY_H: return "SK_KEY_H";
 | 
				
			||||||
 | 
					        case SK_KEY_J: return "SK_KEY_J";
 | 
				
			||||||
 | 
					        case SK_KEY_K: return "SK_KEY_K";
 | 
				
			||||||
 | 
					        case SK_KEY_L: return "SK_KEY_L";
 | 
				
			||||||
 | 
					        case SK_KEY_COLON: return "SK_KEY_COLON";
 | 
				
			||||||
 | 
					        case SK_KEY_QUOTE: return "SK_KEY_QUOTE";
 | 
				
			||||||
 | 
					        case SK_KEY_ENTER: return "SK_KEY_ENTER";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM4: return "SK_KEY_NUM4";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM5: return "SK_KEY_NUM5";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM6: return "SK_KEY_NUM6";
 | 
				
			||||||
 | 
					        case SK_KEY_LSHIFT: return "SK_KEY_LSHIFT";
 | 
				
			||||||
 | 
					        case SK_KEY_Z: return "SK_KEY_Z";
 | 
				
			||||||
 | 
					        case SK_KEY_X: return "SK_KEY_X";
 | 
				
			||||||
 | 
					        case SK_KEY_C: return "SK_KEY_C";
 | 
				
			||||||
 | 
					        case SK_KEY_V: return "SK_KEY_V";
 | 
				
			||||||
 | 
					        case SK_KEY_B: return "SK_KEY_B";
 | 
				
			||||||
 | 
					        case SK_KEY_N: return "SK_KEY_N";
 | 
				
			||||||
 | 
					        case SK_KEY_M: return "SK_KEY_M";
 | 
				
			||||||
 | 
					        case SK_KEY_COMMA: return "SK_KEY_COMMA";
 | 
				
			||||||
 | 
					        case SK_KEY_DOT: return "SK_KEY_DOT";
 | 
				
			||||||
 | 
					        case SK_KEY_SLASH: return "SK_KEY_SLASH";
 | 
				
			||||||
 | 
					        case SK_KEY_RSHIFT: return "SK_KEY_RSHIFT";
 | 
				
			||||||
 | 
					        case SK_KEY_UP: return "SK_KEY_UP";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM1: return "SK_KEY_NUM1";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM2: return "SK_KEY_NUM2";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM3: return "SK_KEY_NUM3";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMENTER: return "SK_KEY_NUMENTER";
 | 
				
			||||||
 | 
					        case SK_KEY_LCTRL: return "SK_KEY_LCTRL";
 | 
				
			||||||
 | 
					        case SK_KEY_LWIN: return "SK_KEY_LWIN";
 | 
				
			||||||
 | 
					        case SK_KEY_LALT: return "SK_KEY_LALT";
 | 
				
			||||||
 | 
					        case SK_KEY_SPACE: return "SK_KEY_SPACE";
 | 
				
			||||||
 | 
					        case SK_KEY_ALTGR: return "SK_KEY_ALTGR";
 | 
				
			||||||
 | 
					        case SK_KEY_SHARKOON: return "SK_KEY_SHARKOON";
 | 
				
			||||||
 | 
					        case SK_KEY_MENU: return "SK_KEY_MENU";
 | 
				
			||||||
 | 
					        case SK_KEY_RCTRL: return "SK_KEY_RCTRL";
 | 
				
			||||||
 | 
					        case SK_KEY_LEFT: return "SK_KEY_LEFT";
 | 
				
			||||||
 | 
					        case SK_KEY_DOWN: return "SK_KEY_DOWN";
 | 
				
			||||||
 | 
					        case SK_KEY_RIGHT: return "SK_KEY_RIGHT";
 | 
				
			||||||
 | 
					        case SK_KEY_NUM0: return "SK_KEY_NUM0";
 | 
				
			||||||
 | 
					        case SK_KEY_NUMDEL: return "SK_KEY_NUMDEL";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "SK_KEY_BAD";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@
 | 
				
			|||||||
#define SK_KEY_PGUP          0x006f
 | 
					#define SK_KEY_PGUP          0x006f
 | 
				
			||||||
#define SK_KEY_NUMLOCK       0x0072
 | 
					#define SK_KEY_NUMLOCK       0x0072
 | 
				
			||||||
#define SK_KEY_NUMDIV        0x0075
 | 
					#define SK_KEY_NUMDIV        0x0075
 | 
				
			||||||
#define SK_KEY_NUMASTERIX    0x0078
 | 
					#define SK_KEY_NUMASTERISK   0x0078
 | 
				
			||||||
#define SK_KEY_NUMMINUS      0x007A
 | 
					#define SK_KEY_NUMMINUS      0x007A
 | 
				
			||||||
#define SK_KEY_TAB           0x007E
 | 
					#define SK_KEY_TAB           0x007E
 | 
				
			||||||
#define SK_KEY_Q             0x0081
 | 
					#define SK_KEY_Q             0x0081
 | 
				
			||||||
@ -109,10 +109,11 @@
 | 
				
			|||||||
#define SK_KEY_NUM0          0x0171
 | 
					#define SK_KEY_NUM0          0x0171
 | 
				
			||||||
#define SK_KEY_NUMDEL        0x0174
 | 
					#define SK_KEY_NUMDEL        0x0174
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SK_LIMIT_KEY         0x0177      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef uint16_t skillerctl_keyaddr_t;
 | 
					typedef uint16_t skillerctl_keyaddr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skillerctl_keyaddr_t skillerctl_keyaddr(const char* name);
 | 
					skillerctl_keyaddr_t skillerctl_keyaddr(const char* name);
 | 
				
			||||||
 | 
					 | 
				
			||||||
char*                skillerctl_keystr(skillerctl_keyaddr_t key);
 | 
					char*                skillerctl_keystr(skillerctl_keyaddr_t key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* KEYS_H */
 | 
					#endif /* KEYS_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										117
									
								
								src/skiller.c
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								src/skiller.c
									
									
									
									
									
								
							@ -1,6 +1,28 @@
 | 
				
			|||||||
#include "skiller.h"
 | 
					#include "skiller.h"
 | 
				
			||||||
 | 
					#include "utils.h"
 | 
				
			||||||
#include <memory.h>
 | 
					#include <memory.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skillerctl_name_value_pair_t modesLUT[] = {
 | 
				
			||||||
 | 
					    SK_MODE_WAVE     , "wave", 
 | 
				
			||||||
 | 
					    SK_MODE_DRIFT    , "drift",
 | 
				
			||||||
 | 
					    SK_MODE_SWIRL    , "swirl",
 | 
				
			||||||
 | 
					    SK_MODE_CHANGE   , "change",
 | 
				
			||||||
 | 
					    SK_MODE_PULSATING, "pulsating",
 | 
				
			||||||
 | 
					    SK_MODE_PERMAMENT, "permament",
 | 
				
			||||||
 | 
					    SK_MODE_TRIGGER  , "trigger",
 | 
				
			||||||
 | 
					    SK_MODE_EXPLOSION, "explosion",
 | 
				
			||||||
 | 
					    SK_MODE_BURST    , "burst",
 | 
				
			||||||
 | 
					    SK_MODE_CHAOS    , "chaos",
 | 
				
			||||||
 | 
					    SK_MODE_COSMIC   , "cosmic",
 | 
				
			||||||
 | 
					    SK_MODE_GRADIENT , "gradient",
 | 
				
			||||||
 | 
					    SK_MODE_TIDE     , "tide",
 | 
				
			||||||
 | 
					    SK_MODE_LIGHTING , "lighting",
 | 
				
			||||||
 | 
					    SK_MODE_MATRIX   , "matrix",
 | 
				
			||||||
 | 
					    SK_MODE_RICOCHET , "ricochet",
 | 
				
			||||||
 | 
					    SK_MODE_RIPPLE   , "ripple",
 | 
				
			||||||
 | 
					    SK_MODE_CUSTOM   , "custom",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length) {
 | 
					skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length) {
 | 
				
			||||||
    if (*(unsigned char*)data != 0x04 || length < 1) {
 | 
					    if (*(unsigned char*)data != 0x04 || length < 1) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
@ -68,17 +90,102 @@ void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t
 | 
				
			|||||||
    payload.color[0].g = (color >> 8)  & 0xFF;
 | 
					    payload.color[0].g = (color >> 8)  & 0xFF;
 | 
				
			||||||
    payload.color[0].b = color         & 0xFF;
 | 
					    payload.color[0].b = color         & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    skillerctl_make_packet(packet, SK_CMD_COLOR, address, &payload, 3);
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_COLOR, address, &payload, 3);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void skillerctl_enable_command(skillerctl_packet_t *packet)
 | 
					void skillerctl_color_batch_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t *color, size_t n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    skillerctl_payload_color_t payload;
 | 
					    skillerctl_payload_color_t payload;
 | 
				
			||||||
    skillerctl_make_packet(packet, SK_CMD_ENABLE, 0x0000, NULL, 0);
 | 
					    
 | 
				
			||||||
 | 
					    for (int i = 0; i < n; i++) {
 | 
				
			||||||
 | 
					        payload.color[i].r = (color[i] >> 16) & 0xFF;
 | 
				
			||||||
 | 
					        payload.color[i].g = (color[i] >> 8)  & 0xFF;
 | 
				
			||||||
 | 
					        payload.color[i].b = color[i]         & 0xFF;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_COLOR, address, &payload, 3*n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void skillerctl_disable_command(skillerctl_packet_t *packet)
 | 
					void skillerctl_enable_led_command(skillerctl_packet_t *packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    skillerctl_payload_color_t payload;
 | 
					    skillerctl_payload_color_t payload;
 | 
				
			||||||
    skillerctl_make_packet(packet, SK_CMD_DISABLE, 0x0000, NULL, 0);
 | 
					    skillerctl_make_packet(packet, SK_CMD_ENABLE_LED, 0x0000, NULL, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_disable_led_command(skillerctl_packet_t *packet)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_payload_color_t payload;
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_DISABLE_LED, 0x0000, NULL, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_mode_command(skillerctl_packet_t *packet, uint8_t mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_MODE, &mode, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_brightness_command(skillerctl_packet_t *packet, uint8_t brightness)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_BRIGHTNESS, &brightness, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_direction_command(skillerctl_packet_t *packet, uint8_t direction)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_DIRECTION, &direction, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_rgb_command(skillerctl_packet_t *packet, uint8_t rgb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_RGB, &rgb, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_speed_command(skillerctl_packet_t *packet, uint8_t speed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_SPEED, &speed, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_polling_command(skillerctl_packet_t *packet, uint8_t rate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_POLLING, &rate, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_base_color_command(skillerctl_packet_t *packet, uint32_t color)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    skillerctl_payload_color_t payload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    payload.color[0].r = (color >> 16) & 0xFF;
 | 
				
			||||||
 | 
					    payload.color[0].g = (color >> 8)  & 0xFF;
 | 
				
			||||||
 | 
					    payload.color[0].b = color         & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    skillerctl_make_packet(packet, SK_CMD_SET_PROP, SK_PROP_COLOR, &payload, 3);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* skillerctl_modestr(skillerctl_mode_t mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (mode) {
 | 
				
			||||||
 | 
					    case SK_MODE_WAVE: return "SK_MODE_WAVE";
 | 
				
			||||||
 | 
					    case SK_MODE_DRIFT: return "SK_MODE_DRIFT";
 | 
				
			||||||
 | 
					    case SK_MODE_SWIRL: return "SK_MODE_SWIRL";
 | 
				
			||||||
 | 
					    case SK_MODE_CHANGE: return "SK_MODE_CHANGE";
 | 
				
			||||||
 | 
					    case SK_MODE_PULSATING: return "SK_MODE_PULSATING";
 | 
				
			||||||
 | 
					    case SK_MODE_PERMAMENT: return "SK_MODE_PERMAMENT";
 | 
				
			||||||
 | 
					    case SK_MODE_TRIGGER: return "SK_MODE_TRIGGER";
 | 
				
			||||||
 | 
					    case SK_MODE_EXPLOSION: return "SK_MODE_EXPLOSION";
 | 
				
			||||||
 | 
					    case SK_MODE_BURST: return "SK_MODE_BURST";
 | 
				
			||||||
 | 
					    case SK_MODE_CHAOS: return "SK_MODE_CHAOS";
 | 
				
			||||||
 | 
					    case SK_MODE_COSMIC: return "SK_MODE_COSMIC";
 | 
				
			||||||
 | 
					    case SK_MODE_GRADIENT: return "SK_MODE_GRADIENT";
 | 
				
			||||||
 | 
					    case SK_MODE_TIDE: return "SK_MODE_TIDE";
 | 
				
			||||||
 | 
					    case SK_MODE_LIGHTING: return "SK_MODE_LIGHTING";
 | 
				
			||||||
 | 
					    case SK_MODE_MATRIX: return "SK_MODE_MATRIX";
 | 
				
			||||||
 | 
					    case SK_MODE_RICOCHET: return "SK_MODE_RICOCHET";
 | 
				
			||||||
 | 
					    case SK_MODE_RIPPLE: return "SK_MODE_RIPPLE";
 | 
				
			||||||
 | 
					    case SK_MODE_CUSTOM: return "SK_MODE_CUSTOM";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "SK_MODE_UNKNOWN";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skillerctl_mode_t skillerctl_strmode(const char *mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return skillerctl_lut_search(modesLUT, sizeof(modesLUT) / sizeof(skillerctl_name_value_pair_t), mode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,9 +10,42 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define SK_MAGIC            0x04
 | 
					#define SK_MAGIC            0x04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SK_CMD_COLOR   0x11
 | 
					#define SK_CMD_DISABLE_LED  0x01 // Disables key backlight, takes some time 
 | 
				
			||||||
#define SK_CMD_ENABLE  0x01
 | 
					#define SK_CMD_ENABLE_LED   0x02 // Enables key backlight, takes some time
 | 
				
			||||||
#define SK_CMD_DISABLE 0x02
 | 
					#define SK_CMD_SET_PROP     0x06 // Changes keyboard mode or mode settings
 | 
				
			||||||
 | 
					#define SK_CMD_MAP_KEYS     0x08 // Writes key mapping to controller 
 | 
				
			||||||
 | 
					#define SK_CMD_WRITE_MACRO  0x0A // Saves macros in controller memory
 | 
				
			||||||
 | 
					#define SK_CMD_SET_COLOR    0x11 // Changes LED RGB values in key given keys, or key range.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SK_PROP_MODE        0x00 // Changes backlight program (pulsing, permamant, custom, etc.) 
 | 
				
			||||||
 | 
					#define SK_PROP_BRIGHTNESS  0x01 // Sets brihgtness level 
 | 
				
			||||||
 | 
					#define SK_PROP_SPEED       0x02 // Sets animation speed 
 | 
				
			||||||
 | 
					#define SK_PROP_DIRECTION   0x03 // Sets animation direction 
 | 
				
			||||||
 | 
					#define SK_PROP_RGB         0x04 // LGBT promotion 
 | 
				
			||||||
 | 
					#define SK_PROP_COLOR       0x05 // Base color 
 | 
				
			||||||
 | 
					#define SK_PROP_POLLING     0x0F // Polling rate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SK_MODE_WAVE        0x01 // Wave 
 | 
				
			||||||
 | 
					#define SK_MODE_DRIFT       0x02 // Drift 
 | 
				
			||||||
 | 
					#define SK_MODE_SWIRL       0x03 // Swirl 
 | 
				
			||||||
 | 
					#define SK_MODE_CHANGE      0x04 // color change 
 | 
				
			||||||
 | 
					#define SK_MODE_PULSATING   0x05 // pulsating 
 | 
				
			||||||
 | 
					#define SK_MODE_PERMAMENT   0x06 // permament 
 | 
				
			||||||
 | 
					#define SK_MODE_TRIGGER     0x07 // Trigger 
 | 
				
			||||||
 | 
					#define SK_MODE_EXPLOSION   0x08 // Explosion 
 | 
				
			||||||
 | 
					#define SK_MODE_BURST       0x09 // Gamma Ray Burst 
 | 
				
			||||||
 | 
					#define SK_MODE_CHAOS       0x0A // Chaos 
 | 
				
			||||||
 | 
					#define SK_MODE_COSMIC      0x0B // Cosmic 
 | 
				
			||||||
 | 
					#define SK_MODE_GRADIENT    0x0C // Gradient 
 | 
				
			||||||
 | 
					#define SK_MODE_TIDE        0x0D // Tide 
 | 
				
			||||||
 | 
					#define SK_MODE_LIGHTING    0x0E // Ball Lighting 
 | 
				
			||||||
 | 
					#define SK_MODE_MATRIX      0x0F // Matrix 
 | 
				
			||||||
 | 
					#define SK_MODE_RICOCHET    0x10 // Ricochet 
 | 
				
			||||||
 | 
					#define SK_MODE_RIPPLE      0x12 // Ripple 
 | 
				
			||||||
 | 
					#define SK_MODE_CUSTOM      0x14 // Custom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef uint16_t skillerctl_property_t;
 | 
				
			||||||
 | 
					typedef uint8_t  skillerctl_mode_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    uint8_t  magic;
 | 
					    uint8_t  magic;
 | 
				
			||||||
@ -24,23 +57,38 @@ typedef struct {
 | 
				
			|||||||
} skillerctl_packet_t;
 | 
					} skillerctl_packet_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    struct { 
 | 
					 | 
				
			||||||
    uint8_t r;
 | 
					    uint8_t r;
 | 
				
			||||||
    uint8_t g;
 | 
					    uint8_t g;
 | 
				
			||||||
    uint8_t b;
 | 
					    uint8_t b;
 | 
				
			||||||
    } color[SK_MAX_PAYLOAD / 3];
 | 
					} skillerctl_color_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    skillerctl_color_t color[SK_MAX_PAYLOAD / 3];
 | 
				
			||||||
} skillerctl_payload_color_t;
 | 
					} skillerctl_payload_color_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void skillerctl_make_packet(skillerctl_packet_t *packet, uint8_t command, uint16_t address, void* payload, uint8_t size);
 | 
					void skillerctl_make_packet(skillerctl_packet_t *packet, uint8_t command, uint16_t address, void* payload, uint8_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t color);
 | 
					void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t color);
 | 
				
			||||||
void skillerctl_enable_command(skillerctl_packet_t *packet);
 | 
					void skillerctl_color_batch_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t start, uint32_t *colors, size_t n);
 | 
				
			||||||
void skillerctl_disable_command(skillerctl_packet_t *packet);
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_enable_led_command(skillerctl_packet_t *packet);
 | 
				
			||||||
 | 
					void skillerctl_disable_led_command(skillerctl_packet_t *packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void skillerctl_set_mode_command(skillerctl_packet_t *packet, skillerctl_mode_t mode);
 | 
				
			||||||
 | 
					void skillerctl_set_brightness_command(skillerctl_packet_t *packet, uint8_t brightness);
 | 
				
			||||||
 | 
					void skillerctl_set_direction_command(skillerctl_packet_t *packet, uint8_t direction);
 | 
				
			||||||
 | 
					void skillerctl_set_rgb_command(skillerctl_packet_t *packet, uint8_t rgb);
 | 
				
			||||||
 | 
					void skillerctl_set_base_color_command(skillerctl_packet_t *packet, uint32_t color);
 | 
				
			||||||
 | 
					void skillerctl_set_speed_command(skillerctl_packet_t *packet, uint8_t speed);
 | 
				
			||||||
 | 
					void skillerctl_set_polling_command(skillerctl_packet_t *packet, uint8_t rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length);
 | 
					skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length);
 | 
				
			||||||
void*                skillerctl_pack(skillerctl_packet_t *packet, uint8_t *data);
 | 
					void*                skillerctl_pack(skillerctl_packet_t *packet, uint8_t *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t skillectl_packet_checksum(skillerctl_packet_t *packet);
 | 
					uint16_t skillectl_packet_checksum(skillerctl_packet_t *packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char*             skillerctl_modestr(skillerctl_mode_t mode);
 | 
				
			||||||
 | 
					skillerctl_mode_t skillerctl_strmode(const char *mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SKILLER_H */
 | 
					#endif /* SKILLER_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										114
									
								
								src/skillerctl.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								src/skillerctl.c
									
									
									
									
									
								
							@ -1,49 +1,122 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Ten program jest napisany bardziej w postaci PoC niż faktycznej aplikacji użytkowej - stąd brak jakiejkolwiek walidacji inputu użytkownika.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include "skiller.h"
 | 
					#include "skiller.h"
 | 
				
			||||||
#include "usb.h"
 | 
					#include "usb.h"
 | 
				
			||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stuff(libusb_device *skiller)
 | 
					#define PACKETS_MAX 255
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skillerctl_packet_t packets[255] = {};
 | 
				
			||||||
 | 
					size_t count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *input_pop_arg(int *i, int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (++*i >= argc) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return argv[*i];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t handle_input(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *arg;
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ((arg = input_pop_arg(&i, argc, argv))) {
 | 
				
			||||||
 | 
					        skillerctl_packet_t *current = packets + count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (strcmp(arg, "-d") == 0) {
 | 
				
			||||||
 | 
					            printf("Disable leds.\n");
 | 
				
			||||||
 | 
					            skillerctl_disable_led_command(current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            count++;
 | 
				
			||||||
 | 
					        } else if (strcmp(arg, "-e") == 0) {
 | 
				
			||||||
 | 
					            printf("Enable leds.\n");
 | 
				
			||||||
 | 
					            skillerctl_enable_led_command(current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            count++;
 | 
				
			||||||
 | 
					        } else if (strcmp(arg, "-c") == 0) {
 | 
				
			||||||
 | 
					            char     *keys = input_pop_arg(&i, argc, argv);
 | 
				
			||||||
 | 
					            uint32_t color = strtol(input_pop_arg(&i, argc, argv), NULL, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            keys = strtok(keys, ",");
 | 
				
			||||||
 | 
					            do {
 | 
				
			||||||
 | 
					                skillerctl_keyaddr_t addr = skillerctl_keyaddr(keys);
 | 
				
			||||||
 | 
					                printf("Set key %s [%04xh] color to #%06x.\n", skillerctl_keystr(addr), addr, color);
 | 
				
			||||||
 | 
					                skillerctl_color_command(packets + count++, addr, color);
 | 
				
			||||||
 | 
					            } while ((keys = strtok(NULL, ",")));
 | 
				
			||||||
 | 
					        } else if (strcmp(arg, "-C") == 0) {
 | 
				
			||||||
 | 
					            uint32_t color = strtol(input_pop_arg(&i, argc, argv), NULL, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            printf("Clear to #%06x.\n", color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            uint32_t colors[18] = {};
 | 
				
			||||||
 | 
					            for (int i = 0; i < 18; i++) colors[i] = color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i = 0; i <= SK_LIMIT_KEY / 54; i++) {
 | 
				
			||||||
 | 
					                skillerctl_color_batch_command(packets + count++, 54*i, colors, 18);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else if (strcmp(arg, "-b") == 0) {
 | 
				
			||||||
 | 
					            uint8_t brightness = strtol(input_pop_arg(&i, argc, argv), NULL, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            printf("Set brightness to %d.\n", brightness);
 | 
				
			||||||
 | 
					            skillerctl_set_brightness_command(current, brightness);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            count++;
 | 
				
			||||||
 | 
					        }  else if (strcmp(arg, "-m") == 0) {
 | 
				
			||||||
 | 
					            skillerctl_mode_t mode = skillerctl_strmode(input_pop_arg(&i, argc, argv));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (mode == 0xFF) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            printf("Set mode to to %s [%02xh].\n", skillerctl_modestr(mode), mode);
 | 
				
			||||||
 | 
					            skillerctl_set_mode_command(current, mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            count++;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            printf("Unknown command %s, omiting.\n", arg);
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return count;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void handle_logic(libusb_device *skiller)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    libusb_device_handle *handle;
 | 
					    libusb_device_handle *handle;
 | 
				
			||||||
    skillerctl_packet_t packet;
 | 
					    skillerctl_packet_t packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (skiller == NULL) {
 | 
					    if (skiller == NULL) {
 | 
				
			||||||
        printf("Device not found kurwa.\n");
 | 
					        printf("Cannot found compatibile keyboard, is it connected?\n");
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (libusb_open(skiller, &handle) != LIBUSB_SUCCESS) {
 | 
					    if (libusb_open(skiller, &handle) != LIBUSB_SUCCESS) {
 | 
				
			||||||
        printf("Nie udało się nawiązać połączenia kurwa..\n");
 | 
					        printf("Cannot open device, try with sudo.\n");
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("Hura kurwa.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    libusb_detach_kernel_driver(handle, 1);
 | 
					    libusb_detach_kernel_driver(handle, 1);
 | 
				
			||||||
    libusb_claim_interface(handle, 1);
 | 
					    libusb_claim_interface(handle, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*     skillerctl_enable_command(&packet); */
 | 
					    for (int i = 0; i < count; i++) {
 | 
				
			||||||
/*     skillerctl_send_command(handle, &packet); */
 | 
					        skillerctl_send_command(handle, packets + i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    skillerctl_color_command(&packet, SK_KEY_ESC, 0xFF0000);
 | 
					 | 
				
			||||||
    skillerctl_send_command(handle, &packet);
 | 
					 | 
				
			||||||
    skillerctl_color_command(&packet, SK_KEY_F1,  0x00FF00);
 | 
					 | 
				
			||||||
    skillerctl_send_command(handle, &packet);
 | 
					 | 
				
			||||||
    skillerctl_color_command(&packet, SK_KEY_F2,  0x0000FF);
 | 
					 | 
				
			||||||
    skillerctl_send_command(handle, &packet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* skillerctl_disable_command(&packet); */
 | 
					 | 
				
			||||||
    /* skillerctl_send_command(handle, &packet); */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    libusb_release_interface(handle, 1);
 | 
					    libusb_release_interface(handle, 1);
 | 
				
			||||||
    libusb_attach_kernel_driver(handle, 1);
 | 
					    libusb_attach_kernel_driver(handle, 1);
 | 
				
			||||||
    libusb_close(handle);
 | 
					    libusb_close(handle);
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() 
 | 
					int main(int argc, char **argv) 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    libusb_device **list;
 | 
					    libusb_device **list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,7 +124,8 @@ int main()
 | 
				
			|||||||
    size_t count = libusb_get_device_list(NULL, &list);
 | 
					    size_t count = libusb_get_device_list(NULL, &list);
 | 
				
			||||||
    libusb_device *skiller = skillerctl_find_device(list, count);
 | 
					    libusb_device *skiller = skillerctl_find_device(list, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stuff(skiller);
 | 
					    handle_input(argc, argv);
 | 
				
			||||||
 | 
					    handle_logic(skiller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    libusb_free_device_list(list, 1);
 | 
					    libusb_free_device_list(list, 1);
 | 
				
			||||||
    libusb_exit(NULL);
 | 
					    libusb_exit(NULL);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/utils.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/utils.c
									
									
									
									
									
								
							@ -1,5 +1,6 @@
 | 
				
			|||||||
#include "utils.h"
 | 
					#include "utils.h"
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hexdump(void* data, size_t length)
 | 
					void hexdump(void* data, size_t length)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -15,3 +16,13 @@ void hexdump(void* data, size_t length)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t skillerctl_lut_search(skillerctl_name_value_pair_t *lut, size_t n, const char* name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (int i = 0; i < n; i++) {
 | 
				
			||||||
 | 
					        if (strcmp(lut[i].name, name) == 0) {
 | 
				
			||||||
 | 
					            return lut[i].value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,8 +17,14 @@
 | 
				
			|||||||
} while (0)
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    uint16_t value;
 | 
				
			||||||
 | 
					    char*    name;
 | 
				
			||||||
 | 
					} skillerctl_name_value_pair_t; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hexdump(void* bytes, size_t length);
 | 
					void hexdump(void* bytes, size_t length);
 | 
				
			||||||
 | 
					uint16_t skillerctl_lut_search(skillerctl_name_value_pair_t *lut, size_t n, const char* name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user