Advertisement
Guest User

libg510

a guest
Apr 5th, 2013
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.21 KB | None | 0 0
  1. /*
  2.     This file is part of g15tools.
  3.  
  4.     g15tools is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     g15tools is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with libg15; if not, write to the Free Software
  16.     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  
  18.     (c) 2006-2007 The G15tools Project - g15tools.sf.net
  19.    
  20.     $Revision: 292 $ -  $Date: 2008-11-11 08:51:25 -0500 (Tue, 11 Nov 2008) $ $Author: aneurysm9 $
  21. */
  22.  
  23. #include <pthread.h>
  24. #include "libg15.h"
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #include <usb.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include "config.h"
  31.  
  32. static usb_dev_handle *keyboard_device = 0;
  33. static int libg15_debugging_enabled = 0;
  34. static int enospc_slowdown = 0;
  35.  
  36. static int found_devicetype = -1;
  37. static int shared_device = 0;
  38. static int g15_keys_endpoint = 0;
  39. static int g15_lcd_endpoint = 0;
  40. static pthread_mutex_t libusb_mutex;
  41.  
  42. /* to add a new device, simply create a new DEVICE() in this list */
  43. /* Fields are: "Name",VendorID,ProductID,Capabilities */
  44. const libg15_devices_t g15_devices[] = {
  45. /*If theres anything you need to change to get the keyboard detected it's most likely "0x46d, 0xc22d"*/
  46.     DEVICE("Logitech G510",0x46d,0xc22d, G15_LCD|G15_KEYS|G15_DEVICE_5BYTE_RETURN|G15_DEVICE_IS_SHARED),
  47.     DEVICE("Logitech G15",0x46d,0xc222,G15_LCD|G15_KEYS),
  48.     DEVICE("Logitech G11",0x46d,0xc225,G15_KEYS),
  49.     DEVICE("Logitech Z-10",0x46d,0x0a07,G15_LCD|G15_KEYS|G15_DEVICE_IS_SHARED),
  50.     DEVICE("Logitech G15 v2",0x46d,0xc227,G15_LCD|G15_KEYS|G15_DEVICE_5BYTE_RETURN),
  51.     DEVICE("Logitech Gamepanel",0x46d,0xc251,G15_LCD|G15_KEYS|G15_DEVICE_IS_SHARED),
  52.     DEVICE(NULL,0,0,0)
  53. };
  54.  
  55.  
  56. /* return device capabilities */
  57. int g15DeviceCapabilities() {
  58.     if(found_devicetype>-1)
  59.         return g15_devices[found_devicetype].caps;
  60.     else
  61.         return -1;
  62. }
  63.  
  64.  
  65. /* enable or disable debugging */
  66. void libg15Debug(int option) {
  67.  
  68.     libg15_debugging_enabled = option;
  69.     usb_set_debug(option);
  70. }
  71.  
  72. /* debugging wrapper */
  73. static int g15_log (FILE *fd, unsigned int level, const char *fmt, ...) {
  74.  
  75.     if (libg15_debugging_enabled && libg15_debugging_enabled>=level) {
  76.         fprintf(fd,"libg15: ");
  77.         va_list argp;
  78.         va_start (argp, fmt);
  79.         vfprintf(fd,fmt,argp);
  80.         va_end (argp);
  81.     }
  82.  
  83.     return 0;
  84. }
  85.  
  86. /* return number of connected and supported devices */
  87. int g15NumberOfConnectedDevices() {
  88.     struct usb_bus *bus = 0;
  89.     struct usb_device *dev = 0;
  90.     int i=0;
  91.     unsigned int found = 0;
  92.  
  93.     for (i=0; g15_devices[i].name !=NULL;i++)
  94.         for (bus = usb_busses; bus; bus = bus->next)
  95.     {
  96.         for (dev = bus->devices; dev; dev = dev->next)
  97.         {
  98.             if ((dev->descriptor.idVendor == g15_devices[i].vendorid && dev->descriptor.idProduct == g15_devices[i].productid))
  99.                 found++;
  100.         }
  101.     }
  102.     g15_log(stderr,G15_LOG_INFO,"Found %i supported devices\n",found);
  103.     return found;
  104. }
  105.  
  106. static int initLibUsb()
  107. {
  108.     usb_init();
  109.  
  110.   /**
  111.      *  usb_find_busses and usb_find_devices both report the number of devices
  112.      *  / busses added / removed since the last call. since this is the first
  113.    *  call we have to return values != 0 or else we didnt find anything */
  114.      
  115.     if (!usb_find_busses())
  116.         return G15_ERROR_OPENING_USB_DEVICE;
  117.  
  118.     if (!usb_find_devices())
  119.         return G15_ERROR_OPENING_USB_DEVICE;
  120.  
  121.     return G15_NO_ERROR;
  122. }
  123.  
  124. static usb_dev_handle * findAndOpenDevice(libg15_devices_t handled_device, int device_index)
  125. {
  126.     struct usb_bus *bus = 0;
  127.     struct usb_device *dev = 0;
  128.     int retries=0;
  129.     int j,i,k,l;
  130.     int interface=0;
  131.  
  132.     for (bus = usb_busses; bus; bus = bus->next)
  133.     {
  134.         for (dev = bus->devices; dev; dev = dev->next)
  135.         {
  136.             if ((dev->descriptor.idVendor == handled_device.vendorid && dev->descriptor.idProduct == handled_device.productid))
  137.             {
  138.                 int ret=0;
  139.                 char name_buffer[65535];
  140.                 name_buffer[0] = 0;
  141.                 usb_dev_handle *devh = 0;
  142.                 found_devicetype = device_index;
  143.                 g15_log(stderr,G15_LOG_INFO,"Found %s, trying to open it\n",handled_device.name);
  144. #if 0
  145.                 devh = usb_open(dev);
  146.                 usb_reset(devh);
  147.                 usleep(50*1000);
  148.                 usb_close(devh);
  149. #endif
  150.                 devh = usb_open(dev);
  151.                 if (!devh)
  152.                 {
  153.                     g15_log(stderr,G15_LOG_INFO, "Error, could not open the keyboard\n");
  154.                     g15_log(stderr,G15_LOG_INFO, "Perhaps you dont have enough permissions to access it\n");
  155.                     return 0;
  156.                 }
  157.  
  158.                 usleep(50*1000);
  159.  
  160.                 g15_log(stderr, G15_LOG_INFO, "Device has %i possible configurations\n",dev->descriptor.bNumConfigurations);
  161.  
  162.                 /* if device is shared with another driver, such as the Z-10 speakers sharing with alsa, we have to disable some calls */
  163.                 if(g15DeviceCapabilities() & G15_DEVICE_IS_SHARED)
  164.                   shared_device = 1;
  165.  
  166.                 for (j = 0; j<dev->descriptor.bNumConfigurations;j++){
  167.                     struct usb_config_descriptor *cfg = &dev->config[j];
  168.  
  169.                     for (i=0;i<cfg->bNumInterfaces; i++){
  170.                         struct usb_interface *ifp = &cfg->interface[i];
  171.                         /* if endpoints are already known, finish up */
  172.                         if(g15_keys_endpoint && g15_lcd_endpoint)
  173.                           break;
  174.                         g15_log(stderr, G15_LOG_INFO, "Device has %i Alternate Settings\n", ifp->num_altsetting);
  175.  
  176.                         for(k=0;k<ifp->num_altsetting;k++){
  177.                             struct usb_interface_descriptor *as = &ifp->altsetting[k];
  178.                             /* verify that the interface is for a HID device */
  179.                             if(as->bInterfaceClass==USB_CLASS_HID){
  180.                                 g15_log(stderr, G15_LOG_INFO, "Interface %i has %i Endpoints\n", i, as->bNumEndpoints);
  181.                                 usleep(50*1000);
  182.                     /* libusb functions ending in _np are not portable between OS's
  183.                                 * Non-linux users will need some way to detach the HID driver from
  184.                                 * the G15 until we work out how to do this for other OS's automatically.
  185.                                 * For the moment, we just skip this code..
  186.                                 */
  187. #ifdef LIBUSB_HAS_GET_DRIVER_NP
  188.                                 ret = usb_get_driver_np(devh, i, name_buffer, 65535);
  189.                     /* some kernel versions say that a driver is attached even though there is none
  190.                                 in this case the name buffer has not been changed
  191.                                 thanks to RobEngle for pointing this out */
  192.                                 if (!ret && name_buffer[0])
  193.                                 {
  194.                                     g15_log(stderr,G15_LOG_INFO,"Trying to detach driver currently attached: \"%s\"\n",name_buffer);
  195.  
  196.                                     ret = usb_detach_kernel_driver_np(devh, i);
  197.                                     if (!ret)
  198.                                     {
  199.                                         g15_log(stderr,G15_LOG_INFO,"Success, detached the driver\n");
  200.                                     }
  201.                                     else
  202.                                     {
  203.                                         g15_log(stderr,G15_LOG_INFO,"Sorry, I could not detach the driver, giving up\n");
  204.                                         return 0;
  205.                                     }
  206.  
  207.                                 }
  208. #endif  
  209.                                 /* don't set configuration if device is shared */
  210.                                 if(0 == shared_device) {
  211.                                   ret = usb_set_configuration(devh, 1);
  212.                                   if (ret)
  213.                                   {
  214.                                     g15_log(stderr,G15_LOG_INFO,"Error setting the configuration, this is fatal\n");
  215.                                     return 0;
  216.                                   }
  217.                                 }
  218.                                 usleep(50*1000);
  219.                                 while((ret = usb_claim_interface(devh,i)) && retries <10) {
  220.                                     usleep(50*1000);
  221.                                     retries++;
  222.                                     g15_log(stderr,G15_LOG_INFO,"Trying to claim interface\n");
  223.                                 }
  224.  
  225.                                 if (ret)
  226.                                 {
  227.                                     g15_log(stderr,G15_LOG_INFO,"Error claiming interface, good day cruel world\n");
  228.                                     return 0;
  229.                                 }
  230.  
  231.                                 for (l=0; l< as->bNumEndpoints;l++){
  232.                                     struct usb_endpoint_descriptor *ep=&as->endpoint[l];
  233.                                     g15_log(stderr, G15_LOG_INFO, "Found %s endpoint %i with address 0x%X maxtransfersize=%i \n",
  234.                                             0x80&ep->bEndpointAddress?"\"Extra Keys\"":"\"LCD\"",
  235.                                             ep->bEndpointAddress&0x0f,ep->bEndpointAddress, ep->wMaxPacketSize
  236.                                            );
  237.  
  238.                                     if(0x80 & ep->bEndpointAddress) {
  239.                                         g15_keys_endpoint = ep->bEndpointAddress;
  240.                                     } else {
  241.                                         g15_lcd_endpoint = ep->bEndpointAddress;
  242.                                     }
  243. #if 0
  244.                                     usb_resetep(devh,ep->bEndpointAddress);
  245. #endif
  246.                                 }
  247.  
  248.                                 if (ret)
  249.                                 {
  250.                                     g15_log(stderr, G15_LOG_INFO, "Error setting Alternate Interface\n");
  251.                                 }
  252.                             }
  253.                         }
  254.                     }
  255.                 }
  256.  
  257.  
  258.                 g15_log(stderr,G15_LOG_INFO,"Done opening the keyboard\n");
  259.                 usleep(500*1000); // sleep a bit for good measure
  260.                 return devh;
  261.             }
  262.         }  
  263.     }
  264.     return 0;
  265. }
  266.  
  267. /*Original code*/
  268. /*static usb_dev_handle * findAndOpenG15() {
  269.     int i;
  270.     for (i=0; g15_devices[i].name !=NULL  ;i++){
  271.         g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name);
  272.         if(keyboard_device = findAndOpenDevice(g15_devices[i],i)){
  273.             break;
  274.         }
  275.         else
  276.             g15_log(stderr,G15_LOG_INFO,"%s not found\n",g15_devices[i].name);
  277.     }
  278.     return keyboard_device;
  279. }*/
  280. /*New code added specifically for the G510*/
  281. int initG510() {
  282.     unsigned char cmd_buf_1[3] = {7, 3, 0};
  283.     unsigned char cmd_buf_2[19] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  284.     int ret = 0;
  285.  
  286.     pthread_mutex_lock(&libusb_mutex);
  287.     ret = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x301, 1, (char*)cmd_buf_2, 19, 10000);
  288.  
  289.     ret = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x307, 1, (char*)cmd_buf_1, 3, 10000);
  290.     pthread_mutex_unlock(&libusb_mutex);
  291.  
  292. /* this command is sent twice by the Logitech driver with some time distance - not 100% sure this is necessary */
  293.     usleep(200);
  294.  
  295.     pthread_mutex_lock(&libusb_mutex);
  296.     ret = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x307, 1, (char*)cmd_buf_1, 3, 10000);
  297.     pthread_mutex_unlock(&libusb_mutex);
  298.  
  299.     return 0;
  300. }
  301. static usb_dev_handle * findAndOpenG15() {
  302.     int i;
  303.     for (i=0; g15_devices[i].name !=NULL ;i++){
  304.     g15_log(stderr,G15_LOG_INFO,"Trying to find %s\n",g15_devices[i].name);
  305.     if(keyboard_device = findAndOpenDevice(g15_devices[i],i)){
  306.         if (g15DeviceCapabilities() & G15_DEVICE_G510) {
  307.         g15_log(stderr, G15_LOG_INFO, "Initializing G510\n");
  308.         initG510();
  309.         }
  310.         break;
  311.     }
  312.     else
  313.         g15_log(stderr,G15_LOG_INFO,"%s not found\n",g15_devices[i].name);
  314.     }
  315.     return keyboard_device;
  316. }
  317. /*New code ends*/
  318.  
  319. int re_initLibG15()
  320. {
  321.  
  322.     usb_init();
  323.  
  324.   /**
  325.      *  usb_find_busses and usb_find_devices both report the number of devices
  326.      *  / busses added / removed since the last call. since this is the first
  327.    *  call we have to return values != 0 or else we didnt find anything */
  328.      
  329.     if (!usb_find_devices())
  330.         return G15_ERROR_OPENING_USB_DEVICE;
  331.  
  332.     keyboard_device = findAndOpenG15();
  333.     if (!keyboard_device)
  334.         return G15_ERROR_OPENING_USB_DEVICE;
  335.  
  336.     return G15_NO_ERROR;
  337. }
  338.  
  339. int initLibG15()
  340. {
  341.     int retval = G15_NO_ERROR;
  342.     retval = initLibUsb();
  343.     if (retval)
  344.         return retval;
  345.  
  346.     g15_log(stderr,G15_LOG_INFO,"%s\n",PACKAGE_STRING);
  347.    
  348. #ifdef SUN_LIBUSB
  349.     g15_log(stderr,G15_LOG_INFO,"Using Sun libusb.\n");
  350. #endif
  351.  
  352.     g15NumberOfConnectedDevices();
  353.  
  354.     keyboard_device = findAndOpenG15();
  355.     if (!keyboard_device)
  356.         return G15_ERROR_OPENING_USB_DEVICE;
  357.  
  358.     pthread_mutex_init(&libusb_mutex, NULL);
  359.     return retval;
  360. }
  361.  
  362. /* reset the keyboard, returning it to a known state */
  363. int exitLibG15()
  364. {
  365.     int retval = G15_NO_ERROR;
  366.     if (keyboard_device){
  367. #ifndef SUN_LIBUSB
  368.         retval = usb_release_interface (keyboard_device, 0);
  369.         usleep(50*1000);
  370. #endif
  371. #if 0
  372.         retval = usb_reset(keyboard_device);
  373.         usleep(50*1000);
  374. #endif
  375.         usb_close(keyboard_device);
  376.         keyboard_device=0;
  377.         pthread_mutex_destroy(&libusb_mutex);
  378.         return retval;
  379.     }
  380.     return -1;
  381. }
  382.  
  383.  
  384. static void dumpPixmapIntoLCDFormat(unsigned char *lcd_buffer, unsigned char const *data)
  385. {
  386. /*
  387.  
  388.   For a set of bytes (A, B, C, etc.) the bits representing pixels will appear on the LCD like this:
  389.    
  390.     A0 B0 C0
  391.     A1 B1 C1
  392.     A2 B2 C2
  393.     A3 B3 C3 ... and across for G15_LCD_WIDTH bytes
  394.     A4 B4 C4
  395.     A5 B5 C5
  396.     A6 B6 C6
  397.     A7 B7 C7
  398.    
  399.     A0
  400.     A1  <- second 8-pixel-high row starts straight after the last byte on
  401.     A2     the previous row
  402.     A3
  403.     A4
  404.     A5
  405.     A6
  406.     A7
  407.     A8
  408.  
  409.     A0
  410.     ...
  411.     A0
  412.     ...
  413.     A0
  414.     ...
  415.     A0
  416.     A1 <- only the first three bits are shown on the bottom row (the last three
  417.     A2    pixels of the 43-pixel high display.)
  418.    
  419.  
  420. */
  421.  
  422.     unsigned int output_offset = G15_LCD_OFFSET;
  423.     unsigned int base_offset = 0;
  424.     unsigned int curr_row = 0;
  425.     unsigned int curr_col = 0;
  426.  
  427.     /* Five 8-pixel rows + a little 3-pixel row.  This formula will calculate
  428.        the minimum number of bytes required to hold a complete column.  (It
  429.        basically divides by eight and rounds up the result to the nearest byte,
  430.        but at compile time.
  431.       */
  432.  
  433. #define G15_LCD_HEIGHT_IN_BYTES  ((G15_LCD_HEIGHT + ((8 - (G15_LCD_HEIGHT % 8)) % 8)) / 8)
  434.  
  435.     for (curr_row = 0; curr_row < G15_LCD_HEIGHT_IN_BYTES; ++curr_row)
  436.     {
  437.         for (curr_col = 0; curr_col < G15_LCD_WIDTH; ++curr_col)
  438.         {
  439.             unsigned int bit = curr_col % 8;
  440.         /* Copy a 1x8 column of pixels across from the source image to the LCD buffer. */
  441.        
  442.             lcd_buffer[output_offset] =
  443.             (((data[base_offset                        ] << bit) & 0x80) >> 7) |
  444.             (((data[base_offset +  G15_LCD_WIDTH/8     ] << bit) & 0x80) >> 6) |
  445.             (((data[base_offset + (G15_LCD_WIDTH/8 * 2)] << bit) & 0x80) >> 5) |
  446.             (((data[base_offset + (G15_LCD_WIDTH/8 * 3)] << bit) & 0x80) >> 4) |
  447.             (((data[base_offset + (G15_LCD_WIDTH/8 * 4)] << bit) & 0x80) >> 3) |
  448.             (((data[base_offset + (G15_LCD_WIDTH/8 * 5)] << bit) & 0x80) >> 2) |
  449.             (((data[base_offset + (G15_LCD_WIDTH/8 * 6)] << bit) & 0x80) >> 1) |
  450.             (((data[base_offset + (G15_LCD_WIDTH/8 * 7)] << bit) & 0x80) >> 0);
  451.             ++output_offset;
  452.             if (bit == 7)
  453.               base_offset++;
  454.         }
  455.     /* Jump down seven pixel-rows in the source image, since we've just
  456.        done a row of eight pixels in one pass (and we counted one pixel-row
  457.        while we were going, so now we skip the next seven pixel-rows.) */
  458.     base_offset += G15_LCD_WIDTH - (G15_LCD_WIDTH / 8);
  459.     }
  460. }
  461.  
  462. int handle_usb_errors(const char *prefix, int ret) {
  463.  
  464.     switch (ret){
  465.         case -ETIMEDOUT:
  466.             return G15_ERROR_READING_USB_DEVICE;  /* backward-compatibility */
  467.             break;
  468.             case -ENOSPC: /* the we dont have enough bandwidth, apparently.. something has to give here.. */
  469.                 g15_log(stderr,G15_LOG_INFO,"usb error: ENOSPC.. reducing speed\n");
  470.                 enospc_slowdown = 1;
  471.                 break;
  472.             case -ENODEV: /* the device went away - we probably should attempt to reattach */
  473.             case -ENXIO: /* host controller bug */
  474.             case -EINVAL: /* invalid request */
  475.             case -EAGAIN: /* try again */
  476.             case -EFBIG: /* too many frames to handle */
  477.             case -EMSGSIZE: /* msgsize is invalid */
  478.                  g15_log(stderr,G15_LOG_INFO,"usb error: %s %s (%i)\n",prefix,usb_strerror(),ret);    
  479.                  break;
  480.             case -EPIPE: /* endpoint is stalled */
  481.                  g15_log(stderr,G15_LOG_INFO,"usb error: %s EPIPE! clearing...\n",prefix);    
  482.                  pthread_mutex_lock(&libusb_mutex);
  483.                  usb_clear_halt(keyboard_device, 0x81);
  484.                  pthread_mutex_unlock(&libusb_mutex);
  485.                  break;
  486.             default: /* timed out */
  487.                  g15_log(stderr,G15_LOG_INFO,"Unknown usb error: %s !! (err is %i (%s))\n",prefix,ret,usb_strerror());
  488.     }
  489.     return ret;
  490. }
  491.  
  492. int writePixmapToLCD(unsigned char const *data)
  493. {
  494.     int ret = 0;
  495.     int transfercount=0;
  496.     unsigned char lcd_buffer[G15_BUFFER_LEN];
  497.     /* The pixmap conversion function will overwrite everything after G15_LCD_OFFSET, so we only need to blank
  498.        the buffer up to this point.  (Even though the keyboard only cares about bytes 0-23.) */
  499.     memset(lcd_buffer, 0, G15_LCD_OFFSET);  /* G15_BUFFER_LEN); */
  500.  
  501.     dumpPixmapIntoLCDFormat(lcd_buffer, data);
  502.  
  503.     if(!(g15_devices[found_devicetype].caps & G15_LCD))
  504.         return 0;
  505.  
  506.     /* the keyboard needs this magic byte */
  507.     lcd_buffer[0] = 0x03;
  508.   /* in an attempt to reduce peak bus utilisation, we break the transfer into 32 byte chunks and sleep a bit in between.
  509.     It shouldnt make much difference, but then again, the g15 shouldnt be flooding the bus enough to cause ENOSPC, yet
  510.     apparently does on some machines...
  511.     I'm not sure how successful this will be in combatting ENOSPC, but we'll give it try in the real-world. */
  512.  
  513.     if(enospc_slowdown != 0){
  514. #ifndef LIBUSB_BLOCKS
  515.         pthread_mutex_lock(&libusb_mutex);  
  516. #endif
  517.         for(transfercount = 0;transfercount<=31;transfercount++){
  518.             ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer+(32*transfercount), 32, 1000);
  519.             if (ret != 32)
  520.             {
  521.                 handle_usb_errors ("LCDPixmap Slow Write",ret);
  522.                 return G15_ERROR_WRITING_PIXMAP;
  523.             }
  524.             usleep(100);
  525.         }
  526. #ifndef LIBUSB_BLOCKS
  527.         pthread_mutex_unlock(&libusb_mutex);
  528. #endif        
  529.     }else{
  530.         /* transfer entire buffer in one hit */
  531. #ifdef LIBUSB_BLOCKS
  532.         ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer, G15_BUFFER_LEN, 1000);
  533. #else
  534.         pthread_mutex_lock(&libusb_mutex);
  535.         ret = usb_interrupt_write(keyboard_device, g15_lcd_endpoint, (char*)lcd_buffer, G15_BUFFER_LEN, 1000);
  536.         pthread_mutex_unlock(&libusb_mutex);
  537. #endif
  538.         if (ret != G15_BUFFER_LEN)
  539.         {
  540.             handle_usb_errors ("LCDPixmap Write",ret);
  541.             return G15_ERROR_WRITING_PIXMAP;
  542.         }
  543.         usleep(100);
  544.     }
  545.  
  546.     return 0;
  547. }
  548.  
  549. int setLCDContrast(unsigned int level)
  550. {
  551.     int retval = 0;
  552.     unsigned char usb_data[] = { 2, 32, 129, 0 };
  553.  
  554.     if(shared_device>0)
  555.         return G15_ERROR_UNSUPPORTED;
  556.  
  557.     switch(level)
  558.     {
  559.         case 1:
  560.             usb_data[3] = 22;
  561.             break;
  562.         case 2:
  563.             usb_data[3] = 26;
  564.             break;
  565.         default:
  566.             usb_data[3] = 18;
  567.     }  
  568.     pthread_mutex_lock(&libusb_mutex);
  569.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000);
  570.     pthread_mutex_unlock(&libusb_mutex);
  571.     return retval;
  572. }
  573.  
  574. /*int setLEDs(unsigned int leds)
  575. {
  576.     int retval = 0;
  577.     unsigned char m_led_buf[4] = { 2, 4, 0, 0 };
  578.     m_led_buf[2] = ~(unsigned char)leds;
  579.  
  580.     if(shared_device>0)
  581.         return G15_ERROR_UNSUPPORTED;
  582.  
  583.     pthread_mutex_lock(&libusb_mutex);
  584.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)m_led_buf, 4, 10000);
  585.     pthread_mutex_unlock(&libusb_mutex);
  586.     return retval;
  587. }
  588. */
  589. int setLEDs(unsigned int leds)
  590. {
  591.     int retval = 0;
  592.     unsigned char m_led_buf[4] = { 2, 4, 0, 0 };
  593.     unsigned char g510_led_buf[2] = {4, 0};
  594.     m_led_buf[2] = ~(unsigned char)leds;
  595.  
  596.     if(g15DeviceCapabilities() & G15_DEVICE_G510) {
  597. // Setting a different color for each of the three macro modes - fancy, isn't it?
  598.     switch (leds & 0x07) {
  599.         case 1:
  600.         setG510LEDColor(0, 255, 0);
  601.         break;
  602.         case 2:
  603.         setG510LEDColor(255, 128, 0);
  604.         break;
  605.         case 4:
  606.         setG510LEDColor(200, 0, 0);
  607.         break;
  608.         default:
  609.         setG510LEDColor(0, 0, 0);
  610.     }
  611. /* A little conversion is needed because the led bitmap for the G510 is completely different from the other keyboards.
  612. for g510 it is: bits 0-3 = N/A; bit 4 = MR; bit 5 = M1; bit 6 = M2; bit 7 = M3; */
  613.     g510_led_buf[1] |= (leds & 0x01) << 7;
  614.     g510_led_buf[1] |= (leds & 0x02) << 5;
  615.     g510_led_buf[1] |= (leds & 0x04) << 3;
  616.     g510_led_buf[1] |= (leds & 0x08) << 1;
  617.     pthread_mutex_lock(&libusb_mutex);
  618.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x304, 1, (char*)g510_led_buf, 2, 10000);
  619.     pthread_mutex_unlock(&libusb_mutex);
  620.     }
  621.     if(shared_device>0)
  622.     return G15_ERROR_UNSUPPORTED;
  623.  
  624.     pthread_mutex_lock(&libusb_mutex);
  625.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)m_led_buf, 4, 10000);
  626.     pthread_mutex_unlock(&libusb_mutex);
  627.    
  628.     return retval;
  629. }
  630. int setLCDBrightness(unsigned int level)
  631. {
  632.     int retval = 0;
  633.     unsigned char usb_data[] = { 2, 2, 0, 0 };
  634.  
  635.     if(shared_device>0)
  636.         return G15_ERROR_UNSUPPORTED;
  637.  
  638.     switch(level)
  639.     {
  640.         case 1 :
  641.             usb_data[2] = 0x10;
  642.             break;
  643.         case 2 :
  644.             usb_data[2] = 0x20;
  645.             break;
  646.         default:
  647.             usb_data[2] = 0x00;
  648.     }
  649.     pthread_mutex_lock(&libusb_mutex);
  650.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000);
  651.     pthread_mutex_unlock(&libusb_mutex);
  652.     return retval;
  653. }
  654.  
  655. /* set the keyboard backlight. doesnt affect lcd backlight. 0==off,1==medium,2==high */
  656. int setKBBrightness(unsigned int level)
  657. {
  658.     int retval = 0;
  659.     unsigned char usb_data[] = { 2, 1, 0, 0 };
  660.  
  661.     if(shared_device>0)
  662.         return G15_ERROR_UNSUPPORTED;
  663.  
  664.     switch(level)
  665.     {
  666.         case 1 :
  667.             usb_data[2] = 0x1;
  668.             break;
  669.         case 2 :
  670.             usb_data[2] = 0x2;
  671.             break;
  672.         default:
  673.             usb_data[2] = 0x0;
  674.     }
  675.     pthread_mutex_lock(&libusb_mutex);
  676.     retval = usb_control_msg(keyboard_device, USB_TYPE_CLASS + USB_RECIP_INTERFACE, 9, 0x302, 0, (char*)usb_data, 4, 10000);
  677.     pthread_mutex_unlock(&libusb_mutex);
  678.     return retval;
  679. }
  680.  
  681. static unsigned char g15KeyToLogitechKeyCode(int key)
  682. {
  683.    // first 12 G keys produce F1 - F12, thats 0x3a + key
  684.     if (key < 12)
  685.     {
  686.         return 0x3a + key;
  687.     }
  688.    // the other keys produce Key '1' (above letters) + key, thats 0x1e + key
  689.     else
  690.     {
  691.         return 0x1e + key - 12; // sigh, half an hour to find  -12 ....
  692.     }
  693. }
  694.  
  695. static void processKeyEvent9Byte(unsigned int *pressed_keys, unsigned char *buffer)
  696. {
  697.     int i;
  698.  
  699.     *pressed_keys = 0;
  700.  
  701.     g15_log(stderr,G15_LOG_WARN,"Keyboard: %x, %x, %x, %x, %x, %x, %x, %x, %x\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8]);
  702.  
  703.     if (buffer[0] == 0x02)
  704.     {
  705.         if (buffer[1]&0x01)
  706.             *pressed_keys |= G15_KEY_G1;
  707.    
  708.         if (buffer[2]&0x02)
  709.             *pressed_keys |= G15_KEY_G2;
  710.  
  711.         if (buffer[3]&0x04)
  712.             *pressed_keys |= G15_KEY_G3;
  713.    
  714.         if (buffer[4]&0x08)
  715.             *pressed_keys |= G15_KEY_G4;
  716.    
  717.         if (buffer[5]&0x10)
  718.             *pressed_keys |= G15_KEY_G5;
  719.  
  720.         if (buffer[6]&0x20)
  721.             *pressed_keys |= G15_KEY_G6;
  722.  
  723.    
  724.         if (buffer[2]&0x01)
  725.             *pressed_keys |= G15_KEY_G7;
  726.    
  727.         if (buffer[3]&0x02)
  728.             *pressed_keys |= G15_KEY_G8;
  729.    
  730.         if (buffer[4]&0x04)
  731.             *pressed_keys |= G15_KEY_G9;
  732.    
  733.         if (buffer[5]&0x08)
  734.             *pressed_keys |= G15_KEY_G10;
  735.    
  736.         if (buffer[6]&0x10)
  737.             *pressed_keys |= G15_KEY_G11;
  738.    
  739.         if (buffer[7]&0x20)
  740.             *pressed_keys |= G15_KEY_G12;
  741.    
  742.         if (buffer[1]&0x04)
  743.             *pressed_keys |= G15_KEY_G13;
  744.    
  745.         if (buffer[2]&0x08)
  746.             *pressed_keys |= G15_KEY_G14;
  747.    
  748.         if (buffer[3]&0x10)
  749.             *pressed_keys |= G15_KEY_G15;
  750.    
  751.         if (buffer[4]&0x20)
  752.             *pressed_keys |= G15_KEY_G16;
  753.    
  754.         if (buffer[5]&0x40)
  755.             *pressed_keys |= G15_KEY_G17;
  756.    
  757.         if (buffer[8]&0x40)
  758.             *pressed_keys |= G15_KEY_G18;
  759.    
  760.         if (buffer[6]&0x01)
  761.             *pressed_keys |= G15_KEY_M1;
  762.         if (buffer[7]&0x02)
  763.             *pressed_keys |= G15_KEY_M2;
  764.         if (buffer[8]&0x04)
  765.             *pressed_keys |= G15_KEY_M3;
  766.         if (buffer[7]&0x40)
  767.             *pressed_keys |= G15_KEY_MR;
  768.  
  769.         if (buffer[8]&0x80)
  770.             *pressed_keys |= G15_KEY_L1;
  771.         if (buffer[2]&0x80)
  772.             *pressed_keys |= G15_KEY_L2;
  773.         if (buffer[3]&0x80)
  774.             *pressed_keys |= G15_KEY_L3;
  775.         if (buffer[4]&0x80)
  776.             *pressed_keys |= G15_KEY_L4;
  777.         if (buffer[5]&0x80)
  778.             *pressed_keys |= G15_KEY_L5;
  779.  
  780.         if (buffer[1]&0x80)
  781.             *pressed_keys |= G15_KEY_LIGHT;
  782.  
  783.     }
  784. }
  785.  
  786. static void processKeyEvent5Byte(unsigned int *pressed_keys, unsigned char *buffer)
  787. {
  788.     int i;
  789.  
  790.     *pressed_keys = 0;
  791.  
  792.     g15_log(stderr,G15_LOG_WARN,"Keyboard: %x, %x, %x, %x, %x\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4]);
  793.  
  794.     if (buffer[0] == 0x02)
  795.     {
  796.         if (buffer[1]&0x01)
  797.             *pressed_keys |= G15_KEY_G1;
  798.    
  799.         if (buffer[1]&0x02)
  800.             *pressed_keys |= G15_KEY_G2;
  801.  
  802.         if (buffer[1]&0x04)
  803.             *pressed_keys |= G15_KEY_G3;
  804.  
  805.         if (buffer[1]&0x08)
  806.             *pressed_keys |= G15_KEY_G4;
  807.  
  808.         if (buffer[1]&0x10)
  809.             *pressed_keys |= G15_KEY_G5;
  810.  
  811.         if (buffer[1]&0x20)
  812.             *pressed_keys |= G15_KEY_G6;
  813.            
  814.         if (buffer[1]&0x40)
  815.             *pressed_keys |= G15_KEY_M1;
  816.            
  817.         if (buffer[1]&0x80)
  818.             *pressed_keys |= G15_KEY_M2;
  819.            
  820.         if (buffer[2]&0x20)
  821.             *pressed_keys |= G15_KEY_M3;
  822.            
  823.         if (buffer[2]&0x40)
  824.             *pressed_keys |= G15_KEY_MR;
  825.  
  826.         if (buffer[2]&0x80)
  827.             *pressed_keys |= G15_KEY_L1;
  828.            
  829.         if (buffer[2]&0x2)
  830.             *pressed_keys |= G15_KEY_L2;
  831.            
  832.         if (buffer[2]&0x4)
  833.             *pressed_keys |= G15_KEY_L3;
  834.  
  835.         if (buffer[2]&0x8)
  836.             *pressed_keys |= G15_KEY_L4;
  837.            
  838.         if (buffer[2]&0x10)
  839.             *pressed_keys |= G15_KEY_L5;
  840.            
  841.         if (buffer[2]&0x1)
  842.             *pressed_keys |= G15_KEY_LIGHT;
  843.     }
  844. }
  845.  
  846.  
  847. int getPressedKeys(unsigned int *pressed_keys, unsigned int timeout)
  848. {
  849.     unsigned char buffer[G15_KEY_READ_LENGTH];
  850.     int ret = 0;
  851. #ifdef LIBUSB_BLOCKS
  852.     ret = usb_interrupt_read(keyboard_device, g15_keys_endpoint, (char*)buffer, G15_KEY_READ_LENGTH, timeout);
  853. #else
  854.     pthread_mutex_lock(&libusb_mutex);
  855.     ret = usb_interrupt_read(keyboard_device, g15_keys_endpoint, (char*)buffer, G15_KEY_READ_LENGTH, timeout);
  856.     pthread_mutex_unlock(&libusb_mutex);
  857. #endif
  858.     if(ret>0) {
  859.       if(buffer[0] == 1)
  860.         return G15_ERROR_TRY_AGAIN;    
  861.     }
  862.  
  863.     switch(ret) {
  864.       case 5:
  865.           processKeyEvent5Byte(pressed_keys, buffer);
  866.           return G15_NO_ERROR;
  867.       case 9:
  868.           processKeyEvent9Byte(pressed_keys, buffer);
  869.           return G15_NO_ERROR;
  870.       default:
  871.           return handle_usb_errors("Keyboard Read", ret); /* allow the app to deal with errors */
  872.     }
  873. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement