3535static libusb_context * Context ;
3636static LibMK_Handle * DeviceHandle ;
3737
38-
3938typedef enum LibMK_Model LibMK_Model ;
4039typedef enum LibMK_Result LibMK_Result ;
4140typedef enum LibMK_Effect LibMK_Effect ;
4241typedef struct LibMK_Device LibMK_Device ;
4342
44-
4543/** Constants */
4644const unsigned char HEADER_DEFAULT = 0x41 ; // 0100 0001
4745const unsigned char HEADER_EFFECT = 0x50 ; // 0101 0000
@@ -67,38 +65,108 @@ const unsigned char LAYOUT_ISO = 1;
6765 * keyboard. The matrix is in [row][column] format. A value of 0xFF
6866 * indicates an unknown value.
6967*/
70- const unsigned char LIBMK_LAYOUT_ANSI [LIBMK_MAX_ROWS ][LIBMK_MAX_COLS ] =
71- {{0x0b , 0x16 , 0x1e , 0x19 , 0x1b , 0xff , 0x07 , 0x33 , 0x39 , 0x3e , 0xff , 0x56 ,
72- 0x57 , 0x53 , 0x55 , 0x4f , 0x48 , 0x00 , 0x65 , 0x6d , 0x75 , 0x77 , 0xff , 0xff },
73- {0x0e , 0x0f , 0x17 , 0x1f , 0x27 , 0x26 , 0x2e , 0x2f , 0x37 , 0x3f , 0x47 , 0x46 ,
74- 0x36 , 0xff , 0x51 , 0x03 , 0x01 , 0x02 , 0x64 , 0x6c , 0x74 , 0x76 , 0xff , 0xff },
75- {0x09 , 0x08 , 0x10 , 0x18 , 0x20 , 0x21 , 0x29 , 0x28 , 0x30 , 0x38 , 0x40 , 0x41 ,
76- 0x31 , 0xff , 0x52 , 0x5e , 0x5c , 0x58 , 0x60 , 0x68 , 0x70 , 0x6e , 0xff , 0xff },
77- {0x11 , 0x0a , 0x12 , 0x1a , 0x22 , 0x23 , 0x2b , 0x2a , 0x32 , 0x3a , 0x42 , 0x43 ,
78- 0xff , 0xff , 0x54 , 0xff , 0xff , 0xff , 0x61 , 0x69 , 0x71 , 0xff , 0xff , 0xff },
79- {0x49 , 0xff , 0x0c , 0x14 , 0x1c , 0x24 , 0x25 , 0x2d , 0x2c , 0x34 , 0x3c , 0x45 ,
80- 0xff , 0xff , 0x4a , 0xff , 0x50 , 0xff , 0x62 , 0x6a , 0x72 , 0x6f , 0xff , 0xff },
81- {0x06 , 0x5a , 0x4b , 0xff , 0xff , 0xff , 0x5b , 0xff , 0xff , 0xff , 0x4d , 0x4e ,
82- 0x3d , 0xff , 0x04 , 0x5f , 0x5d , 0x05 , 0x6b , 0xff , 0x73 , 0xff , 0xff , 0xff },
83- {0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
84- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff }
85- };
86-
87- const unsigned char LIBMK_LAYOUT_ISO [LIBMK_MAX_ROWS ][LIBMK_MAX_COLS ] =
88- {{0x0B , 0x16 , 0x1E , 0x19 , 0x1B , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
89- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
90- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
91- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
92- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
93- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
94- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
95- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
96- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
97- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
98- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
99- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
100- {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
101- 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }};
68+ const unsigned char LIBMK_LAYOUT [2 ][3 ][LIBMK_MAX_ROWS ][LIBMK_MAX_COLS ] = {
69+ { // ANSI Layouts
70+ // Layout size L
71+ {{0x0b , 0x16 , 0x1e , 0x19 , 0x1b , 0xff , 0x07 , 0x33 , 0x39 , 0x3e , 0xff , 0x56 ,
72+ 0x57 , 0x53 , 0x55 , 0x4f , 0x48 , 0x00 , 0x65 , 0x6d , 0x75 , 0x77 , 0xff , 0xff },
73+ {0x0e , 0x0f , 0x17 , 0x1f , 0x27 , 0x26 , 0x2e , 0x2f , 0x37 , 0x3f , 0x47 , 0x46 ,
74+ 0x36 , 0xff , 0x51 , 0x03 , 0x01 , 0x02 , 0x64 , 0x6c , 0x74 , 0x76 , 0xff , 0xff },
75+ {0x09 , 0x08 , 0x10 , 0x18 , 0x20 , 0x21 , 0x29 , 0x28 , 0x30 , 0x38 , 0x40 , 0x41 ,
76+ 0x31 , 0xff , 0x52 , 0x5e , 0x5c , 0x58 , 0x60 , 0x68 , 0x70 , 0x6e , 0xff , 0xff },
77+ {0x11 , 0x0a , 0x12 , 0x1a , 0x22 , 0x23 , 0x2b , 0x2a , 0x32 , 0x3a , 0x42 , 0x43 ,
78+ 0xff , 0xff , 0x54 , 0xff , 0xff , 0xff , 0x61 , 0x69 , 0x71 , 0xff , 0xff , 0xff },
79+ {0x49 , 0xff , 0x0c , 0x14 , 0x1c , 0x24 , 0x25 , 0x2d , 0x2c , 0x34 , 0x3c , 0x45 ,
80+ 0xff , 0xff , 0x4a , 0xff , 0x50 , 0xff , 0x62 , 0x6a , 0x72 , 0x6f , 0xff , 0xff },
81+ {0x06 , 0x5a , 0x4b , 0xff , 0xff , 0xff , 0x5b , 0xff , 0xff , 0xff , 0x4d , 0x4e ,
82+ 0x3d , 0xff , 0x04 , 0x5f , 0x5d , 0x05 , 0x6b , 0xff , 0x73 , 0xff , 0xff , 0xff },
83+ {0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
84+ 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff }},
85+ // Layout size M
86+ // TODO: Find the key layout matrix of an ANSI M keyboard
87+ {{0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
88+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
89+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
90+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
91+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
92+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
93+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
94+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
95+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
96+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
97+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
98+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
99+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
100+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }},
101+ // Layout size S
102+ {{0x60 , 0x61 , 0x62 , 0x63 , 0x68 , 0xFF , 0x69 , 0x6A , 0x70 , 0x71 , 0xFF , 0x72 ,
103+ 0x43 , 0x44 , 0x45 , 0x66 , 0x67 , 0x6B , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
104+ {0x00 , 0x01 , 0x08 , 0x09 , 0x10 , 0x11 , 0x18 , 0x19 , 0x20 , 0x21 , 0x28 , 0x29 ,
105+ 0x30 , 0xFF , 0x31 , 0x38 , 0x39 , 0x40 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
106+ {0x02 , 0x03 , 0x0A , 0x0B , 0x12 , 0x13 , 0x1A , 0x1B , 0x22 , 0x23 , 0x2A , 0x2B ,
107+ 0x32 , 0xFF , 0x33 , 0x3A , 0x3B , 0x42 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
108+ {0x04 , 0x05 , 0x0C , 0x0D , 0x14 , 0x15 , 0x1C , 0x1D , 0x24 , 0x25 , 0x2C , 0x2D ,
109+ 0xFF , 0xFF , 0x34 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
110+ {0x06 , 0xFF , 0x07 , 0x0E , 0x0F , 0x16 , 0x17 , 0x1E , 0x1F , 0x26 , 0x27 , 0x2E ,
111+ 0x01 , 0xFF , 0x2F , 0xFF , 0x3D , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
112+ {0x5B , 0x5A , 0x5C , 0xFF , 0xFF , 0xFF , 0x5D , 0xFF , 0xFF , 0xFF , 0x5E , 0x3C ,
113+ 0x5F , 0xFF , 0x36 , 0x3F , 0x3E , 0x46 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
114+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
115+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }},
116+ }, { // ISO Layouts
117+ // Layout size L
118+ // This key layout matrix was copied from libcmmk, GNU GPLv3
119+ {{0x0B , 0x16 , 0x1E , 0x19 , 0x1B , 0xFF , 0x07 , 0x33 , 0x39 , 0x3E , 0xFF , 0x56 ,
120+ 0x57 , 0x53 , 0x55 , 0x4F , 0x48 , 0x00 , 0x65 , 0x6D , 0x75 , 0x77 , 0xFF , 0xFF },
121+ {0x0E , 0x0F , 0x17 , 0x1F , 0x27 , 0x26 , 0x2E , 0x2F , 0x37 , 0x3F , 0x47 , 0x46 ,
122+ 0x36 , 0xFF , 0x51 , 0x03 , 0x01 , 0x02 , 0x64 , 0x6C , 0x74 , 0x76 , 0xFF , 0xFF },
123+ {0x09 , 0x08 , 0x10 , 0x18 , 0x20 , 0x21 , 0x29 , 0x28 , 0x30 , 0x38 , 0x40 , 0x41 ,
124+ 0x31 , 0xFF , 0x54 , 0x5E , 0x5C , 0x58 , 0x60 , 0x68 , 0x70 , 0x6E , 0xFF , 0xFF },
125+ {0x11 , 0x0A , 0x12 , 0x1A , 0x22 , 0x23 , 0x2B , 0x2A , 0x32 , 0x3A , 0x42 , 0x43 ,
126+ 0x44 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x61 , 0x69 , 0x71 , 0xFF , 0xFF , 0xFF },
127+ {0x49 , 0x13 , 0x0C , 0x14 , 0x1C , 0x24 , 0x25 , 0x2D , 0x2C , 0x34 , 0x3C , 0x45 ,
128+ 0xFF , 0xFF , 0x4A , 0xFF , 0x50 , 0xFF , 0x62 , 0x6A , 0x72 , 0x6F , 0xFF , 0xFF },
129+ {0x06 , 0x5A , 0x4B , 0xFF , 0xFF , 0xFF , 0x5B , 0xFF , 0xFF , 0xFF , 0x4D , 0x4E ,
130+ 0x3D , 0xFF , 0x04 , 0x5F , 0x5D , 0x05 , 0x6B , 0xFF , 0x73 , 0xFF , 0xFF , 0xFF },
131+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
132+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }},
133+ // Layout size M
134+ // TODO: Find the key layout matrix of an ISO M keyboard
135+ {{0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
136+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
137+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
138+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
139+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
140+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
141+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
142+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
143+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
144+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
145+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
146+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
147+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
148+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }},
149+ // Layout size S
150+ // TODO: Find the key layout matrix of an ISO S keyboard
151+ {{0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
152+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
153+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
154+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
155+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
156+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
157+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
158+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
159+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
160+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
161+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
162+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF },
163+ {0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
164+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF }}
165+ },
166+ // TODO: If required, Japanese layouts may be added at index 2 of this array
167+ // TODO: so that it remains compatible with the LibMK_Layout enum and the
168+ // TODO: firmware defined layout
169+ };
102170
103171
104172bool libmk_init (void ) {
@@ -289,16 +357,34 @@ int libmk_create_handle(LibMK_Handle** handle, LibMK_Device* device) {
289357 * A LibMK_Handle must be created from a LibMK_Device struct, as
290358 * the LibMK_Handle requires special attributes.
291359 */
292- unsigned char layout = libmk_get_layout (device -> bDevice );
293360 * handle = (LibMK_Handle * ) malloc (sizeof (LibMK_Handle ));
361+ if (* handle == NULL )
362+ return LIBMK_ERR_DEV_OPEN_FAILED ;
294363 int r = libusb_open (device -> device , & (* handle )-> handle );
295364 if (r != 0 )
296365 return LIBMK_ERR_DEV_OPEN_FAILED ;
297366 (* handle )-> open = true;
298367 (* handle )-> model = device -> model ;
299- (* handle )-> layout = layout ;
300368 (* handle )-> bDevice = device -> bDevice ;
301369 (* handle )-> bVendor = device -> bVendor ;
370+ LibMK_Model model = device -> model ;
371+ if (model == DEV_RGB_L || model == DEV_WHITE_L )
372+ (* handle )-> size = LIBMK_L ;
373+ else if (model == DEV_RGB_M || model == DEV_WHITE_M )
374+ (* handle )-> size = LIBMK_M ;
375+ else if (model == DEV_RGB_S || model == DEV_WHITE_S )
376+ (* handle )-> size = LIBMK_S ;
377+ else {
378+ libusb_close ((* handle )-> handle );
379+ return LIBMK_ERR_UNKNOWN_LAYOUT ;
380+ }
381+ LibMK_Firmware * fw ;
382+ r = libmk_get_firmware_version (* handle , & fw );
383+ if (r != LIBMK_SUCCESS ) {
384+ libusb_close ((* handle )-> handle );
385+ return r ;
386+ }
387+ (* handle )-> layout = fw -> layout ;
302388 return LIBMK_SUCCESS ;
303389}
304390
@@ -590,7 +676,7 @@ int libmk_send_packet(LibMK_Handle* handle, unsigned char* packet) {
590676 handle -> handle , LIBMK_EP_IN | LIBUSB_ENDPOINT_IN ,
591677 packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
592678 if (r != LIBUSB_SUCCESS ) {
593- result = LIBMK_SUCCESS ;
679+ result = LIBMK_ERR_TRANSFER ;
594680 } else if (t != LIBMK_PACKET_SIZE ) {
595681 result = LIBMK_ERR_TRANSFER ;
596682 } else if (packet [0 ] == HEADER_ERROR ) {
@@ -603,6 +689,30 @@ int libmk_send_packet(LibMK_Handle* handle, unsigned char* packet) {
603689}
604690
605691
692+ int libmk_exch_packet (LibMK_Handle * handle , unsigned char * packet ) {
693+ /** Send a single packet to the keyboard and receive the response
694+ *
695+ * The response is put in the memory allocated for the packet to be
696+ * sent. If the function encounters an error, the memory is freed
697+ * and no response is available (except for a return code).
698+ */
699+ int t ;
700+ int r = libusb_interrupt_transfer (
701+ handle -> handle , LIBMK_EP_OUT | LIBUSB_ENDPOINT_OUT ,
702+ packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
703+ if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE ) {
704+ free (packet );
705+ return LIBMK_ERR_TRANSFER ;
706+ }
707+ r = libusb_interrupt_transfer (
708+ handle -> handle , LIBMK_EP_IN | LIBUSB_ENDPOINT_IN ,
709+ packet , LIBMK_PACKET_SIZE , & t , LIBMK_PACKET_TIMEOUT );
710+ if (r != LIBUSB_SUCCESS || t != LIBMK_PACKET_SIZE )
711+ return LIBMK_ERR_TRANSFER ;
712+ return LIBMK_SUCCESS ;
713+ }
714+
715+
606716unsigned char * libmk_build_packet (unsigned char predef , ...) {
607717 /** Return a pointer to a packet filled with zeros */
608718 unsigned char * packet = (unsigned char * )
@@ -688,26 +798,7 @@ int libmk_set_all_led_color(
688798}
689799
690800
691- unsigned char libmk_get_layout (int bProduct ) {
692- short i = 0 ;
693- while (true) {
694- if (ANSI [i ] == bProduct )
695- return LAYOUT_ANSI ;
696- else if (ANSI [i ] == 0 )
697- break ;
698- i ++ ;
699- }
700- i = 0 ;
701- while (ISO [i ] != 0x0000 ) {
702- if (ISO [i ] == bProduct )
703- return LAYOUT_ISO ;
704- i ++ ;
705- }
706- return LIBMK_ERR_UNKNOWN_LAYOUT ;
707- }
708-
709-
710- void libmk_print_packet (unsigned char * packet ) {
801+ inline void libmk_print_packet (unsigned char * packet ) {
711802 /** Pretty print a keyboard communication packet */
712803#ifdef LIBMK_DEBUG
713804 printf ("Packet:\n" );
@@ -731,12 +822,9 @@ int libmk_get_offset(
731822 * keyboard. This function returns the hexadecimal offset for the
732823 * appropriate layout into the offset pointer.
733824 */
734- if (handle -> layout == LAYOUT_ANSI )
735- * offset = LIBMK_LAYOUT_ANSI [row ][col ];
736- else if (handle -> layout == LAYOUT_ISO )
737- * offset = LIBMK_LAYOUT_ISO [row ][col ];
738- else
825+ if (handle -> layout != LAYOUT_ISO && handle -> layout != LAYOUT_ANSI )
739826 return LIBMK_ERR_UNKNOWN_LAYOUT ;
827+ * offset = LIBMK_LAYOUT [handle -> layout - 1 ][handle -> size ][row ][col ];
740828 return LIBMK_SUCCESS ;
741829}
742830
@@ -795,3 +883,29 @@ int libmk_set_effect_details(
795883 return r ;
796884 return libmk_send_packet (handle , packet );
797885}
886+
887+
888+ int libmk_get_firmware_version (LibMK_Handle * handle , LibMK_Firmware * * fw ) {
889+ /** Return the firmware details
890+ *
891+ * TODO: Determine whether the version number encodes the layout
892+ * TODO: See libcmmk issue #10 for more information
893+ */
894+ if (handle == NULL )
895+ handle = DeviceHandle ;
896+ if (handle == NULL )
897+ return LIBMK_ERR_DEV_NOT_SET ;
898+ unsigned char * p = libmk_build_packet (2 , 0x01 , 0x02 );
899+ int r = libmk_exch_packet (handle , p );
900+ if (r != LIBMK_SUCCESS )
901+ return r ;
902+ (* fw ) = (LibMK_Firmware * ) malloc (sizeof (LibMK_Firmware ));
903+ for (unsigned char i = 0 ; i < 5 ; i ++ )
904+ (* fw )-> string [i ] = p [0x04 + i ];
905+ (* fw )-> string [5 ] = (char ) NULL ;
906+ (* fw )-> major = p [0x04 ] & 0x0F ;
907+ (* fw )-> minor = p [0x06 ] & 0x0F ;
908+ (* fw )-> patch = p [0x08 ] & 0x0F ;
909+ (* fw )-> layout = p [0x04 ] & 0x0F ;
910+ return LIBMK_SUCCESS ;
911+ }
0 commit comments