Guest User

g400s_hack

a guest
Sep 13th, 2013
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.73 KB | None | 0 0
  1. //
  2. // Simple hack to change dpi on Logitech G400s
  3. // G400s only support: 400, 800, 1600, 2000 and 4000 dpi, all other are interpolate by software
  4. //
  5. // Based on g400_hack from Przemek Aksamit
  6. // https://bitbucket.org/extaliones/g400_hack/src
  7. //
  8. // gcc -lusb-1.0 -o g400s_hack g400s_hack.c
  9. //
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <libusb-1.0/libusb.h>
  15.  
  16. #define G400S_VENDOR_ID   0x046d
  17. #define G400S_PRODUCT_ID  0xc24c
  18.  
  19. #define EXIT_SUCCESS       0
  20. #define EXIT_ERROR_ARGS    1
  21. #define EXIT_ERROR_DEVICE  2
  22. #define EXIT_ERROR_KERNEL  3
  23. #define EXIT_ERROR_CLAIM   4
  24. #define EXIT_ERROR_WRITE   5
  25.  
  26.  
  27. libusb_context *ctx = NULL;
  28. libusb_device_handle *handle = NULL;
  29.  
  30. int detached = 0;
  31. int claimed  = 0;
  32.  
  33.  
  34. void usage()
  35. {
  36.   printf("Usage: ./g400s_hack ( -400 | -800 | -1600 | -2000 | -4000 )\n");
  37.   printf("Highly experimental, use with caution.\n");
  38. }
  39.  
  40. void cleanup()
  41. {
  42.   if (claimed)
  43.     libusb_release_interface(handle, 1);
  44.  
  45.   if (detached)
  46.     libusb_attach_kernel_driver(handle, 1);
  47.  
  48.   libusb_close(handle);
  49.   libusb_exit(ctx);
  50. }
  51.  
  52. int main(int argc, char **argv)
  53. {
  54.   if (argc != 2 || argv[1][0] != '-') {
  55.     usage();
  56.     return EXIT_ERROR_ARGS;
  57.   }
  58.  
  59.   //131 => 400dpi, 132 => 800dpi, 133 => 1600dpi, 134 => 2000dpi, 135 => 4000dpi
  60.   uint16_t dpi_idx = 131;
  61.   if      (strcmp(&argv[1][1], "400" ) == 0)
  62.     dpi_idx += 0;
  63.   else if (strcmp(&argv[1][1], "800" ) == 0)
  64.     dpi_idx += 1;
  65.   else if (strcmp(&argv[1][1], "1600") == 0)
  66.     dpi_idx += 2;
  67.   else if (strcmp(&argv[1][1], "2000") == 0)
  68.     dpi_idx += 3;
  69.   else if (strcmp(&argv[1][1], "4000") == 0)
  70.     dpi_idx += 4;
  71.   else {
  72.     usage();
  73.     return EXIT_ERROR_ARGS;
  74.   }
  75.  
  76.   printf("Set new DPI: %s (index %i)\n", &argv[1][1], dpi_idx);
  77.  
  78.   libusb_init(&ctx);
  79.  
  80.   handle = libusb_open_device_with_vid_pid(ctx, G400S_VENDOR_ID, G400S_PRODUCT_ID);
  81.   libusb_set_debug(ctx, 3);
  82.  
  83.   if (!handle) {
  84.     fprintf(stderr, "Logitech G400s not found! (Do you have usb rights? Try with sudo?)\n");
  85.     cleanup();
  86.     return EXIT_ERROR_DEVICE;
  87.   }
  88.  
  89.   if (libusb_kernel_driver_active(handle, 1) == 1) {
  90.     if (libusb_detach_kernel_driver(handle, 1) != 0) {
  91.       fprintf(stderr, "Can't detach kernel driver.\n");
  92.       cleanup();
  93.       return EXIT_ERROR_KERNEL;
  94.     }
  95.  
  96.     detached = 1;
  97.   }
  98.  
  99.   if (libusb_claim_interface(handle, 1) != 0) {
  100.     fprintf(stderr, "Failed to claim interface.\n");
  101.     cleanup();
  102.     return EXIT_ERROR_CLAIM;
  103.   }
  104.  
  105.   claimed = 1;
  106.  
  107.   if (libusb_control_transfer (handle, 0x40, 2, 0x008e, dpi_idx, NULL, 0, 1000) != 0) {
  108.     fprintf(stderr, "Error writing to USB device.\n");
  109.     cleanup();
  110.     return EXIT_ERROR_WRITE;
  111.   }
  112.  
  113.   cleanup();
  114.   printf("Finished.\n");
  115.   return EXIT_SUCCESS;
  116. }
Add Comment
Please, Sign In to add comment