Created
May 29, 2016 16:29
-
-
Save anonymous/0eaa66d0e0f94817232f778591de3717 to your computer and use it in GitHub Desktop.
Invert fn keys for Logitech K81x series (Linux)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2012 Mario Scholz <[email protected]> | |
* | |
* based on pairing_tool.c from Benjamin Tissoires <[email protected]> | |
* see also https://lkml.org/lkml/2011/9/22/367 | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#include <linux/input.h> | |
#include <linux/hidraw.h> | |
#include <sys/ioctl.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include <errno.h> | |
#define HID_VENDOR_ID_LOGITECH (__u32)0x046d | |
#define HID_DEVICE_ID_K810 (__s16)0xb319 | |
#define HID_DEVICE_ID_K811 (__s16)0xb317 | |
const char k810_seq_fkeys_on[] = {0x10, 0xff, 0x06, 0x15, 0x00, 0x00, 0x00}; | |
const char k810_seq_fkeys_off[] = {0x10, 0xff, 0x06, 0x15, 0x01, 0x00, 0x00}; | |
const char opt_on[] = "on"; | |
const char opt_off[] = "off"; | |
void send(const int fd, const char * buf, const int len) | |
{ | |
int res; | |
/* Send sequence to the Device */ | |
res = write(fd, buf, len); | |
if (res < 0) | |
{ | |
printf("Error: %d\n", errno); | |
perror("write"); | |
} | |
else if (res == len) | |
{ | |
// printf("Configuration sent.\n"); | |
} | |
else | |
{ | |
errno = ENOMEM; | |
printf("write: %d were written instead of %ld.\n", res, len); | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
int fd; | |
int res; | |
struct hidraw_devinfo info; | |
const char * seq; | |
char *dev = NULL; | |
int flag_fkeys = 1; | |
int c; | |
if (argc < 5) | |
{ | |
printf("Logitech K810 Keyboard Configurator (by trial-n-error)\n\n"); | |
printf("Usage: %s -d /dev/hidraw{0,1,...} -f {on|off}:\n\n", argv[0]); | |
printf("-d /dev/hidrawX\n" | |
" Path to hidraw device. Determine by e.g.:\n" | |
" ls /sys/class/hidraw/hidraw*/device/uevent\n" | |
" and/or\n" | |
" cat /sys/class/hidraw/hidraw*/device/uevent\n"); | |
printf("-f <on|off>\n" | |
" To enable direct access to F-keys.\n"); | |
printf("\n"); | |
} | |
while ((c = getopt (argc, argv, "d:f:")) != -1) | |
{ | |
switch (c) | |
{ | |
case 'd': | |
dev = optarg; | |
break; | |
case 'f': | |
if (strcmp(opt_on, optarg) == 0) | |
{ | |
flag_fkeys = 1; | |
} | |
else if (strcmp(opt_off, optarg) == 0) | |
{ | |
flag_fkeys = 0; | |
} | |
else | |
{ | |
fprintf (stderr, "Option -%c requires argument '%s' or '%s'.\n", optopt, opt_on, opt_off); | |
return 1; | |
} | |
break; | |
case '?': | |
if (optopt == 'f') | |
{ | |
fprintf (stderr, "Option -%c requires an argument.\n", optopt); | |
} | |
else if (isprint (optopt)) | |
{ | |
fprintf (stderr, "Unknown option `-%c'.\n", optopt); | |
} | |
else | |
{ | |
fprintf (stderr, | |
"Unknown option character `\\x%x'.\n", | |
optopt); | |
} | |
return 1; | |
default: | |
abort (); | |
} | |
} | |
/* Open the Device with non-blocking reads. */ | |
fd = open(dev, O_RDWR|O_NONBLOCK); | |
if (fd < 0) | |
{ | |
perror("Unable to open device"); | |
return 1; | |
} | |
/* Get Raw Info */ | |
res = ioctl(fd, HIDIOCGRAWINFO, &info); | |
if (res < 0) | |
{ | |
perror("error while getting info from device"); | |
fprintf(stderr,"%d", res); | |
return 1; | |
} | |
if ((info.bustype == BUS_BLUETOOTH && | |
info.vendor == HID_VENDOR_ID_LOGITECH) && | |
(info.product == HID_DEVICE_ID_K811 || | |
info.product == HID_DEVICE_ID_K810)) | |
{ | |
if (flag_fkeys) | |
{ | |
send(fd, k810_seq_fkeys_on, sizeof(k810_seq_fkeys_on)); | |
} | |
else | |
{ | |
send(fd, k810_seq_fkeys_off, sizeof(k810_seq_fkeys_off)); | |
} | |
} | |
else | |
{ | |
errno = EPERM; | |
perror("The given device is not a supported " | |
"Logitech keyboard"); | |
close(fd); | |
return 1; | |
} | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment