Python vs. PHP
Show all projects!

Logitech G400 Maus DPI setzen unter Linux (deprecated)

Dieser Artikel ist veraltet und dient nur dazu bei entsprechenden Suchbegriffen und Bookmarks auf den neuen Artikel hin zu weisen.

Seit einiger Zeit gibt es einiges was man unter Linux spielen kann. Möchte man hier eine hohe Präzision beim Spielen erreichen ist es notwendig, das die Maus immer mit der selben DPI Zahl eingestellt ist. Da es unter Linux aber keinen Treiber für die Logitech Mäuse gibt muss man von Hand, über die beim Mausrad platzierten Taster, dafür sorgen das diese eingestellt wird.

Dadurch wird leider verhindert das man diese Tasten mit eigenen Funktionen belegt, zudem kann man es auch einfach manchmal vergessen, und merkt es erst beim Spielen. Um nun sicherzustellen das diese aber immer gleich ist, ohne das man diese von Hand einstellt, muss ein kleines Tool kompiliert und beim starten ausgeführt werden.

Ich habe zwei Möglichkeiten gefunden dies zu tun. Die erste Variante ist ein kleines zu kompilierendes C-Programm, die zweite Variante ein Pyton Skript was die selbe Arbeit leistet. Beide basieren darauf via USB die Werte 0x8e und die DPI Rate (0x011 - 0x111) als Binärcode zu senden.

Ob diese Tools mit der angeschlossen Maus funktionieren kann, wird ermittelt indem man 'lsusb' aufruft.

thomas@quad:~/devel/mouse_g400$ lsusb 
Bus 002 Device 002: ID 8087:8001 Intel Corp. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8009 Intel Corp. 
Bus 003 Device 003: ID 046d:c245 Logitech, Inc. G400 Optical Mouse
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Die Vendor:Product ID "046d:c245" ist die im Tool eingestellte kombination, über welche das USB-Gerät (in diesem Fall die Maus) angesprochen wird.

Perl-Skript

sudo apt-get install libhidapi-libusb0 

Eine Datei mit dem Namen /etc/udev/rules.d/10-logitech-g400-config.rules mit folgendem Inhalt anlegen:
SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c245", MODE:="660", GROUP="plugdev"

sudo udevadm control --reload-rules
sudo usermod -a -G plugdev $USER

Danach einmal neu am System anmelden, so das die Gruppenzugehörigkeit greift und die Maus einmal aus-/einstecken.

thomas@quad:~/source/logitech-g400-config$ ./logitech-g400-config.py
sampling_rate: 500
dpi_level: 800

C Tool Source

Für die zweite Variante kommt ein kleines C-Programm zum Einsatz. Den Quellcode habe ich auf der Suche nach einer Lösung auf Pastebin gefunden und angepasst(siehe Quellen). Das Tool ermöglicht die Maus auf die der Logitech G400 Mouse möglichen DPI Werte einzustellen (400 800 1800 3600). Ob das Tool mit der Angeschlossen Maus funktionieren kann, wird ermittelt, indem man 'lsusb' aufruft.

//
// Simple hack to change dpi on Logitech G400s
// G400s only support: 400, 800, 1600, 2000 and 4000 dpi, all other are interpolate by software
//
// Based on g400_hack from Przemek Aksamit
// https://bitbucket.org/extaliones/g400_hack/src
//
// gcc -lusb-1.0 -o g400s_hack g400s_hack.c
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>

#define G400S_VENDOR_ID 0x046d
#define G400S_PRODUCT_ID 0xc24c

#define EXIT_SUCCESS 0
#define EXIT_ERROR_ARGS 1
#define EXIT_ERROR_DEVICE 2
#define EXIT_ERROR_KERNEL 3
#define EXIT_ERROR_CLAIM 4
#define EXIT_ERROR_WRITE 5


libusb_context *ctx = NULL;
libusb_device_handle *handle = NULL;

int detached = 0;
int claimed = 0;


void usage()
{
 printf("Usage: ./g400s_hack ( -400 | -800 | -1600 | -2000 | -4000 | -d | -n)\n");
 printf("Highly experimental, use with caution.\n");
}

void cleanup()
{
 if (claimed)
 libusb_release_interface(handle, 1);

 if (detached)
 libusb_attach_kernel_driver(handle, 1);

 libusb_close(handle);
 libusb_exit(ctx);
}

int main(int argc, char **argv)
{
 if (argc != 2 || argv[1][0] != '-') {
 usage();
 return EXIT_ERROR_ARGS;
 }

 //131 => 400dpi, 132 => 800dpi, 133 => 1600dpi, 134 => 2000dpi, 135 => 4000dpi
 uint16_t dpi_idx = 131;
 if (strcmp(&argv[1][1], "400" ) == 0)
 dpi_idx += 0;
 else if (strcmp(&argv[1][1], "800" ) == 0)
 dpi_idx += 1;
 else if (strcmp(&argv[1][1], "1600") == 0)
 dpi_idx += 2;
 else if (strcmp(&argv[1][1], "2000") == 0)
 dpi_idx += 3;
 else if (strcmp(&argv[1][1], "4000") == 0)
 dpi_idx += 4;
 else if (strcmp(&argv[1][1], "d") == 0)
 dpi_idx = 0;
 else if (strcmp(&argv[1][1], "n") == 0)
 dpi_idx = 4;
 else {
 usage();
 return EXIT_ERROR_ARGS;
 }

 if (dpi_idx >= 131) {
 printf("Set new DPI: %s (index %i)\n", &argv[1][1], dpi_idx);
 }
 else {
 printf("Set Driver/Native mode: %s (index %i)\n", &argv[1][1], dpi_idx);
 }

 libusb_init(&ctx);

 handle = libusb_open_device_with_vid_pid(ctx, G400S_VENDOR_ID, G400S_PRODUCT_ID);
 libusb_set_debug(ctx, 3);

 if (!handle) {
 fprintf(stderr, "Logitech G400s not found! (Do you have usb rights? Try with sudo?)\n");
 cleanup();
 return EXIT_ERROR_DEVICE;
 }

 if (libusb_kernel_driver_active(handle, 1) == 1) {
 if (libusb_detach_kernel_driver(handle, 1) != 0) {
 fprintf(stderr, "Can't detach kernel driver.\n");
 cleanup();
 return EXIT_ERROR_KERNEL;
 }

 detached = 1;
 }

 if (libusb_claim_interface(handle, 1) != 0) {
 fprintf(stderr, "Failed to claim interface.\n");
 cleanup();
 return EXIT_ERROR_CLAIM;
 }

 claimed = 1;
 
 if (dpi_idx == 0) {
 // Set driver mode, then DPI to 400
 char data[2];
 data[0] = 0x20; data[1] = 0x01;
 int result = libusb_control_transfer (handle, 0x21, 9, 0x0320, 1, data, 2, 1000);
 if (result != 2) {
 fprintf(stderr, "Error writing to USB device (%d).\n", result);
 cleanup();
 return EXIT_ERROR_WRITE;
 }
 dpi_idx = 131;
 }

 if (libusb_control_transfer (handle, 0x40, 2, 0x008e, dpi_idx, NULL, 0, 1000) != 0) {
 fprintf(stderr, "Error writing to USB device.\n");
 cleanup();
 return EXIT_ERROR_WRITE;
 }

 cleanup();
 printf("Finished.\n");
 return EXIT_SUCCESS;
}

Tool kompilieren

Den Quellcode des Tools herunterladen und mittels 'gcc -o g400_hack h400_hack.c -lusb-1.0' kompilieren. Dazu muss man das 'libusb-1.0-0-dev' Paket installiert haben.

sudo apt-get install libusb-1.0-0-dev
mkdir g400
cd g400
wget "http://notdefine.de/g400_hack.c"
gcc -o g400_hack h400_hack.c -lusb-1.0

DPI beim starten setzen

Um zum Beispiel die Maus auf 800 DPI zu setzen wird das Tool wie folgt aufgerufen:

sudo ./g400_hack -800

Diese wollen wir nun direkt beim Bootvorgang erledigen, dazu tragen wir das Tool in die '/etc/rc.local' ein. Somit wird der Befehl beim starten als Root aufgerufen. Hier ein Beispiel wie diese Datei bei mir aussieht, der Pfad zum Tool ist anzupassen

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
# 
# By default this script does nothing. 
 
# maus auf 800dpi 
/home/thomas/devel/mouse_g400/g400_hack -800 
 
exit 0 

Quellen

Article relase date: / Last update: