1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594 |
- /*
- * Razer device access library
- *
- * Copyright (C) 2007-2018 Michael Buesch <m@bues.ch>
- *
- * 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 2
- * 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.
- */
- #include "librazer.h"
- #include "razer_private.h"
- #include "config.h"
- #include "profile_emulation.h"
- #include "hw_deathadder.h"
- #include "hw_deathadder2013.h"
- #include "hw_deathadder_chroma.h"
- #include "hw_naga.h"
- #include "hw_krait.h"
- #include "hw_lachesis.h"
- #include "hw_lachesis5k6.h"
- #include "hw_copperhead.h"
- #include "hw_boomslangce.h"
- #include "hw_imperator.h"
- #include "hw_taipan.h"
- #include "hw_mamba_tournament_edition.h"
- #include "hw_diamondback_chroma.h"
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- enum razer_devtype {
- RAZER_DEVTYPE_MOUSE,
- };
- /** struct razer_mouse_base_ops - Basic device-init operations
- *
- * @type: The type ID.
- *
- * @init: Initialize the device and its private data structures.
- *
- * @release: Release device and data structures.
- */
- struct razer_mouse_base_ops {
- enum razer_mouse_type type;
- int (*init)(struct razer_mouse *m, struct libusb_device *udev);
- void (*release)(struct razer_mouse *m);
- };
- struct razer_usb_device {
- uint16_t vendor; /* Vendor ID */
- uint16_t product; /* Product ID */
- enum razer_devtype type;
- union {
- const struct razer_mouse_base_ops *mouse_ops;
- } u;
- };
- static const struct razer_mouse_base_ops razer_deathadder_base_ops = {
- .type = RAZER_MOUSETYPE_DEATHADDER,
- .init = razer_deathadder_init,
- .release = razer_deathadder_release,
- };
- static const struct razer_mouse_base_ops razer_deathadder2013_base_ops = {
- .type = RAZER_MOUSETYPE_DEATHADDER,
- .init = razer_deathadder2013_init,
- .release = razer_deathadder2013_release,
- };
- static const struct razer_mouse_base_ops razer_deathadder_chroma_base_ops = {
- .type = RAZER_MOUSETYPE_DEATHADDER,
- .init = razer_deathadder_chroma_init,
- .release = razer_deathadder_chroma_release,
- };
- static const struct razer_mouse_base_ops razer_naga_base_ops = {
- .type = RAZER_MOUSETYPE_NAGA,
- .init = razer_naga_init,
- .release = razer_naga_release,
- };
- static const struct razer_mouse_base_ops razer_krait_base_ops = {
- .type = RAZER_MOUSETYPE_KRAIT,
- .init = razer_krait_init,
- .release = razer_krait_release,
- };
- static const struct razer_mouse_base_ops razer_lachesis_base_ops = {
- .type = RAZER_MOUSETYPE_LACHESIS,
- .init = razer_lachesis_init,
- .release = razer_lachesis_release,
- };
- #if 0
- static const struct razer_mouse_base_ops razer_lachesis5k6_base_ops = {
- .type = RAZER_MOUSETYPE_LACHESIS,
- .init = razer_lachesis5k6_init,
- .release = razer_lachesis5k6_release,
- };
- #endif
- static const struct razer_mouse_base_ops razer_copperhead_base_ops = {
- .type = RAZER_MOUSETYPE_COPPERHEAD,
- .init = razer_copperhead_init,
- .release = razer_copperhead_release,
- };
- static const struct razer_mouse_base_ops razer_boomslangce_base_ops = {
- .type = RAZER_MOUSETYPE_BOOMSLANGCE,
- .init = razer_boomslangce_init,
- .release = razer_boomslangce_release,
- };
- static const struct razer_mouse_base_ops razer_imperator_base_ops = {
- .type = RAZER_MOUSETYPE_IMPERATOR,
- .init = razer_imperator_init,
- .release = razer_imperator_release,
- };
- static const struct razer_mouse_base_ops razer_taipan_base_ops = {
- .type = RAZER_MOUSETYPE_TAIPAN,
- .init = razer_taipan_init,
- .release = razer_taipan_release,
- };
- static const struct razer_mouse_base_ops razer_mamba_te_base_ops = {
- .type = RAZER_MOUSETYPE_MAMBA_TE,
- .init = razer_mamba_te_init,
- .release = razer_mamba_te_release,
- };
- static const struct razer_mouse_base_ops razer_diamondback_chroma_base_ops = {
- .type = RAZER_MOUSETYPE_DIAMONDBACK_CHROMA,
- .init = razer_diamondback_chroma_init,
- .release = razer_diamondback_chroma_release,
- };
- #define USBVENDOR_ANY 0xFFFF
- #define USBPRODUCT_ANY 0xFFFF
- #define USB_MOUSE(_vendor, _product, _mouse_ops) \
- { .vendor = _vendor, .product = _product, \
- .type = RAZER_DEVTYPE_MOUSE, \
- .u = { .mouse_ops = _mouse_ops, }, }
- /* Table of supported USB devices. */
- static const struct razer_usb_device razer_usbdev_table[] = {
- USB_MOUSE(0x1532, 0x0007, &razer_deathadder_base_ops), /* classic */
- USB_MOUSE(0x1532, 0x0016, &razer_deathadder_base_ops), /* 3500 DPI */
- USB_MOUSE(0x1532, 0x0029, &razer_deathadder_base_ops), /* black edition */
- USB_MOUSE(0x1532, 0x0037, &razer_deathadder2013_base_ops), /* 2013 edition */
- USB_MOUSE(0x1532, 0x0038, &razer_deathadder2013_base_ops), /* 1800 edition/Korea PCBang edition */
- USB_MOUSE(0x1532, 0x0043, &razer_deathadder_chroma_base_ops), /* Chroma edition */
- // USB_MOUSE(0x04B4, 0xE006, &razer_deathadder_base_ops), /* cypress bootloader */
- USB_MOUSE(0x1532, 0x0003, &razer_krait_base_ops),
- USB_MOUSE(0x1532, 0x000C, &razer_lachesis_base_ops), /* classic */
- // USB_MOUSE(0x1532, 0x001E, &razer_lachesis5k6_base_ops), /* 5600 DPI */
- USB_MOUSE(0x1532, RAZER_NAGA_PID_CLASSIC, &razer_naga_base_ops),
- USB_MOUSE(0x1532, RAZER_NAGA_PID_EPIC, &razer_naga_base_ops),
- USB_MOUSE(0x1532, RAZER_NAGA_PID_2012, &razer_naga_base_ops),
- USB_MOUSE(0x1532, RAZER_NAGA_PID_HEX, &razer_naga_base_ops),
- USB_MOUSE(0x1532, RAZER_NAGA_PID_2014, &razer_naga_base_ops),
- USB_MOUSE(0x1532, RAZER_NAGA_PID_HEX_2014, &razer_naga_base_ops),
- USB_MOUSE(0x1532, 0x0101, &razer_copperhead_base_ops),
- USB_MOUSE(0x1532, 0x0005, &razer_boomslangce_base_ops),
- USB_MOUSE(0x1532, 0x0017, &razer_imperator_base_ops),
- USB_MOUSE(0x1532, 0x0034, &razer_taipan_base_ops),
- USB_MOUSE(0x1532, 0x0046, &razer_mamba_te_base_ops), /*mamba tournament edition*/
- USB_MOUSE(0x1532, 0x004C, &razer_diamondback_chroma_base_ops),
- { 0, }, /* List end */
- };
- #undef USB_MOUSE
- static struct libusb_context *libusb_ctx;
- static struct razer_mouse *mice_list = NULL;
- /* We currently only have one handler. */
- static razer_event_handler_t event_handler;
- static struct config_file *razer_config_file = NULL;
- static bool profile_emu_enabled;
- razer_logfunc_t razer_logfunc_info;
- razer_logfunc_t razer_logfunc_error;
- razer_logfunc_t razer_logfunc_debug;
- static inline bool razer_initialized(void)
- {
- return !!libusb_ctx;
- }
- int razer_register_event_handler(razer_event_handler_t handler)
- {
- if (event_handler)
- return -EEXIST;
- event_handler = handler;
- return 0;
- }
- void razer_unregister_event_handler(razer_event_handler_t handler)
- {
- event_handler = NULL;
- }
- static void razer_notify_event(enum razer_event type,
- const struct razer_event_data *data)
- {
- if (event_handler)
- event_handler(type, data);
- }
- static int match_usbdev(const struct libusb_device_descriptor *desc,
- const struct razer_usb_device *id)
- {
- if ((desc->idVendor != id->vendor) &&
- (id->vendor != USBVENDOR_ANY))
- return 0;
- if ((desc->idProduct != id->product) &&
- (id->product != USBPRODUCT_ANY))
- return 0;
- return 1;
- }
- static const struct razer_usb_device * usbdev_lookup(const struct libusb_device_descriptor *desc)
- {
- const struct razer_usb_device *id = &(razer_usbdev_table[0]);
- while (id->vendor || id->product) {
- if (match_usbdev(desc, id))
- return id;
- id++;
- }
- return NULL;
- }
- static void mouse_list_add(struct razer_mouse **base, struct razer_mouse *new_entry)
- {
- struct razer_mouse *i;
- new_entry->next = NULL;
- if (!(*base)) {
- *base = new_entry;
- return;
- }
- for (i = *base; i->next; i = i->next)
- ;
- i->next = new_entry;
- }
- static void mouse_list_del(struct razer_mouse **base, struct razer_mouse *del_entry)
- {
- struct razer_mouse *i;
- if (del_entry == *base) {
- *base = (*base)->next;
- return;
- }
- for (i = *base; i && (i->next != del_entry); i = i->next)
- ;
- if (i)
- i->next = del_entry->next;
- }
- static struct razer_mouse * mouse_list_find(struct razer_mouse *base,
- struct libusb_device *udev)
- {
- struct razer_mouse *m, *next;
- uint8_t busnr = libusb_get_bus_number(udev);
- uint8_t devaddr = libusb_get_device_address(udev);
- razer_for_each_mouse(m, next, base) {
- if (m->usb_ctx) {
- if (libusb_get_bus_number(m->usb_ctx->dev) == busnr &&
- libusb_get_device_address(m->usb_ctx->dev) == devaddr)
- return m;
- }
- }
- return NULL;
- }
- static int parse_idstr(char *idstr, char **devtype, char **devname,
- char **buspos, char **devid)
- {
- *devtype = idstr;
- *devname = razer_strsplit(*devtype, ':');
- *buspos = razer_strsplit(*devname, ':');
- *devid = razer_strsplit(*buspos, ':');
- if (!*devtype || !*devname || !*buspos || !*devid)
- return -EINVAL;
- return 0;
- }
- static bool simple_globcmp(const char *string,
- const char *template)
- {
- char s, t, tnext;
- while (1) {
- s = string[0];
- t = template[0];
- if (s == '\0' && t == '\0')
- break;
- if (t == '*') {
- tnext = template[1];
- if (s == '\0') {
- if (tnext == '\0')
- break;
- return 0;
- }
- if (s == tnext) {
- template++;
- continue;
- }
- } else {
- if (s == '\0' || t == '\0')
- return 0;
- if (s != t)
- return 0;
- template++;
- }
- string++;
- }
- return 1; /* Match */
- }
- static bool mouse_idstr_glob_match(struct config_file *f,
- void *context, void *data,
- const char *section)
- {
- struct razer_mouse *m = context;
- const char **matched_section = data;
- char idstr[RAZER_IDSTR_MAX_SIZE + 1] = { 0, };
- char *idstr_devtype, *idstr_devname, *idstr_buspos, *idstr_devid;
- char globstr[RAZER_IDSTR_MAX_SIZE + 1] = { 0, };
- char *globstr_devtype, *globstr_devname, *globstr_buspos, *globstr_devid;
- if (strlen(section) > RAZER_IDSTR_MAX_SIZE) {
- razer_error("globbed idstr \"%s\" in config too long\n",
- section);
- return 1;
- }
- strcpy(globstr, section);
- strcpy(idstr, m->idstr);
- if (parse_idstr(globstr, &globstr_devtype, &globstr_devname,
- &globstr_buspos, &globstr_devid))
- return 1;
- if (parse_idstr(idstr, &idstr_devtype, &idstr_devname,
- &idstr_buspos, &idstr_devid)) {
- razer_error("INTERNAL-ERROR: Failed to parse idstr \"%s\"\n",
- idstr);
- return 1;
- }
- if (!simple_globcmp(idstr_devtype, globstr_devtype))
- return 1;
- if (!simple_globcmp(idstr_devname, globstr_devname))
- return 1;
- if (!simple_globcmp(idstr_buspos, globstr_buspos))
- return 1;
- if (!simple_globcmp(idstr_devid, globstr_devid))
- return 1;
- *matched_section = section;
- return 0; /* Match */
- }
- static struct razer_mouse_profile * find_prof(struct razer_mouse *m, unsigned int nr)
- {
- struct razer_mouse_profile *list;
- unsigned int i;
- if (!m->get_profiles)
- return NULL;
- list = m->get_profiles(m);
- if (!list)
- return NULL;
- for (i = 0; i < m->nr_profiles; i++) {
- if (list[i].nr == nr)
- return &list[i];
- }
- return NULL;
- }
- static int parse_int_int_pair(const char *str, int *val0, int *val1)
- {
- char a[64] = { 0, }, b[64] = { 0, };
- int err;
- *val0 = *val1 = -1;
- err = razer_split_tuple(str, ':', min(sizeof(a), sizeof(b)),
- a, b, NULL);
- if (err) {
- /* It's not a pair. Interpret it as one value. */
- razer_strlcpy(a, str, sizeof(a));
- err = razer_string_to_int(razer_string_strip(a), val1);
- if (err)
- return -EINVAL;
- return 1;
- }
- err = razer_string_to_int(razer_string_strip(a), val0);
- err |= razer_string_to_int(razer_string_strip(b), val1);
- if (err)
- return -EINVAL;
- return 0;
- }
- static bool mouse_apply_one_config(struct config_file *f,
- void *context, void *data,
- const char *section,
- const char *item,
- const char *value)
- {
- struct razer_mouse *m = context;
- struct razer_mouse_profile *prof;
- bool *error_status = data;
- int err, nr;
- static const size_t tmplen = 128;
- char a[tmplen], b[tmplen], c[tmplen];
- //FIXME fixes for glob/prof configs
- if (strcasecmp(item, "profile") == 0) {
- int profile;
- err = razer_string_to_int(value, &profile);
- if (err || profile < 1 || (unsigned int)profile > m->nr_profiles)
- goto error;
- if (m->set_active_profile) {
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- err = m->set_active_profile(m, prof);
- if (err)
- goto error;
- }
- } else if (strcasecmp(item, "res") == 0) {
- int profile, resolution, i;
- struct razer_mouse_dpimapping *mappings;
- err = parse_int_int_pair(value, &profile, &resolution);
- if (err == 1) {
- prof = m->get_active_profile(m);
- profile = prof->nr + 1;
- } else if (err)
- goto error;
- if (profile < 1 || resolution < 1)
- goto error;
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- nr = m->supported_dpimappings(m, &mappings);
- if (nr <= 0)
- goto error;
- //FIXME dims
- for (i = 0; i < nr; i++) {
- if (resolution >= 100) {
- if ((int)(mappings[i].res[RAZER_DIM_0]) != resolution)
- continue;
- } else {
- if (mappings[i].nr != (unsigned int)resolution)
- continue;
- }
- err = prof->set_dpimapping(prof, NULL, &mappings[i]);
- if (err)
- goto error;
- goto ok;
- }
- goto invalid; /* res is invalid. Ignore it. */
- } else if (strcasecmp(item, "freq") == 0) {
- int profile, freq, i;
- enum razer_mouse_freq *freqs;
- err = parse_int_int_pair(value, &profile, &freq);
- if (err == 1) {
- prof = m->get_active_profile(m);
- profile = prof->nr + 1;
- } else if (err)
- goto error;
- if (profile < 1 || freq < 1)
- goto error;
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- nr = m->supported_freqs(m, &freqs);
- if (nr <= 0)
- goto error;
- for (i = 0; i < nr; i++) {
- if (freqs[i] != (enum razer_mouse_freq)freq)
- continue;
- if (!prof->set_freq)
- goto invalid;
- err = prof->set_freq(prof, freqs[i]);
- razer_free_freq_list(freqs, nr);
- if (err)
- goto error;
- goto ok;
- }
- razer_free_freq_list(freqs, nr);
- goto error;
- } else if (strcasecmp(item, "led") == 0) {
- bool on;
- struct razer_led *leds, *led;
- const char *ledname, *ledstate;
- int profile;
- err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
- if (err && err != -ENODATA)
- goto error;
- if (!strlen(a) || !strlen(b))
- goto error;
- if (strlen(c)) {
- /* A profile was specified */
- err = razer_string_to_int(razer_string_strip(a), &profile);
- if (err || profile < 1)
- goto error;
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- ledname = razer_string_strip(b);
- ledstate = razer_string_strip(c);
- } else {
- /* Modify global LEDs */
- prof = NULL;
- ledname = razer_string_strip(a);
- ledstate = razer_string_strip(b);
- }
- err = razer_string_to_bool(ledstate, &on);
- if (err)
- goto error;
- if (prof) {
- if (prof->get_leds) {
- err = prof->get_leds(prof, &leds);
- } else {
- /* Try to fall back to global */
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- } else {
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- if (err < 0)
- goto error;
- if (err == 0)
- goto ok; /* No LEDs. Ignore config. */
- for (led = leds; led; led = led->next) {
- if (strcasecmp(led->name, ledname) != 0)
- continue;
- if (!led->toggle_state) {
- razer_free_leds(leds);
- goto invalid;
- }
- err = led->toggle_state(led,
- on ? RAZER_LED_ON : RAZER_LED_OFF);
- razer_free_leds(leds);
- if (err)
- goto error;
- goto ok;
- }
- razer_free_leds(leds);
- goto error;
- } else if (strcasecmp(item, "mode") == 0) {
- enum razer_led_mode mode;
- struct razer_led *leds, *led;
- const char *ledname, *ledmode;
- int profile;
- err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
- if (err && err != -ENODATA)
- goto error;
- if (!strlen(a) || !strlen(b))
- goto error;
- if (strlen(c)) {
- /* A profile was specified */
- err = razer_string_to_int(razer_string_strip(a), &profile);
- if (err || profile < 1)
- goto error;
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- ledname = razer_string_strip(b);
- ledmode = razer_string_strip(c);
- } else {
- /* Modify global LEDs */
- prof = NULL;
- ledname = razer_string_strip(a);
- ledmode = razer_string_strip(b);
- }
- err = razer_string_to_mode(ledmode, &mode);
- if (err)
- goto error;
- if (prof) {
- if (prof->get_leds) {
- err = prof->get_leds(prof, &leds);
- } else {
- /* Try to fall back to global */
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- } else {
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- if (err < 0)
- goto error;
- if (err == 0)
- goto ok; /* No LEDs. Ignore config. */
- for (led = leds; led; led = led->next) {
- if (strcasecmp(led->name, ledname) != 0)
- continue;
- if (!led->set_mode) {
- razer_free_leds(leds);
- goto invalid;
- }
- err = led->set_mode(led, mode);
- razer_free_leds(leds);
- if (err)
- goto error;
- goto ok;
- }
- razer_free_leds(leds);
- goto error;
- } else if (strcasecmp(item, "color") == 0) {
- struct razer_rgb_color color;
- struct razer_led *leds, *led;
- const char *ledname, *ledcolor;
- int profile;
- err = razer_split_tuple(value, ':', tmplen, a, b, c, NULL);
- if (err && err != -ENODATA)
- goto error;
- if (!strlen(a) || !strlen(b))
- goto error;
- if (strlen(c)) {
- /* A profile was specified */
- err = razer_string_to_int(razer_string_strip(a), &profile);
- if (err || profile < 1)
- goto error;
- prof = find_prof(m, profile - 1);
- if (!prof)
- goto error;
- ledname = razer_string_strip(b);
- ledcolor = razer_string_strip(c);
- } else {
- /* Modify global LEDs */
- prof = NULL;
- ledname = razer_string_strip(a);
- ledcolor = razer_string_strip(b);
- }
- err = razer_string_to_color(ledcolor, &color);
- if (err)
- goto error;
- if (prof) {
- if (prof->get_leds) {
- err = prof->get_leds(prof, &leds);
- } else {
- /* Try to fall back to global */
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- } else {
- if (!m->global_get_leds)
- goto ok; /* No LEDs. Ignore config. */
- err = m->global_get_leds(m, &leds);
- }
- if (err < 0)
- goto error;
- if (err == 0)
- goto ok; /* No LEDs. Ignore config. */
- for (led = leds; led; led = led->next) {
- if (strcasecmp(led->name, ledname) != 0)
- continue;
- if (!led->change_color) {
- razer_free_leds(leds);
- goto invalid;
- }
- err = led->change_color(led, &color);
- razer_free_leds(leds);
- if (err)
- goto error;
- goto ok;
- }
- razer_free_leds(leds);
- goto error;
- } else if (strcasecmp(item, "disabled") == 0) {
- goto ok;
- } else
- goto invalid;
- ok:
- return 1;
- error:
- *error_status = 1;
- invalid:
- razer_error("Config section \"%s\" item \"%s\" "
- "invalid.\n", section, item);
- return *error_status ? 0 : 1;
- }
- static void mouse_apply_initial_config(struct razer_mouse *m)
- {
- const char *section = NULL;
- int err;
- bool error_status = 0;
- config_for_each_section(razer_config_file,
- m, §ion,
- mouse_idstr_glob_match);
- if (!section)
- return;
- if (config_get_bool(razer_config_file, section,
- "disabled", 0, CONF_NOCASE)) {
- razer_debug("Initial config for \"%s\" is disabled. Not applying.\n",
- m->idstr);
- return;
- }
- razer_debug("Applying config section \"%s\" to \"%s\"\n",
- section, m->idstr);
- err = m->claim(m);
- if (err) {
- razer_error("Failed to claim \"%s\"\n", m->idstr);
- return;
- }
- config_for_each_item(razer_config_file,
- m, &error_status,
- section,
- mouse_apply_one_config);
- m->release(m);
- if (error_status) {
- razer_error("Failed to apply initial config "
- "to \"%s\"\n", m->idstr);
- }
- }
- static struct razer_usb_context * razer_create_usb_ctx(struct libusb_device *dev)
- {
- struct razer_usb_context *ctx;
- ctx = zalloc(sizeof(*ctx));
- if (!ctx)
- return NULL;
- ctx->dev = dev;
- ctx->bConfigurationValue = 1;
- return ctx;
- }
- static int mouse_default_claim(struct razer_mouse *m)
- {
- return razer_generic_usb_claim_refcount(m->usb_ctx, &m->claim_count);
- }
- static int mouse_default_release(struct razer_mouse *m)
- {
- int err = 0;
- if (m->claim_count == 1) {
- if (m->commit)
- err = m->commit(m, 0);
- }
- razer_generic_usb_release_refcount(m->usb_ctx, &m->claim_count);
- return err;
- }
- static struct razer_mouse * mouse_new(const struct razer_usb_device *id,
- struct libusb_device *udev)
- {
- struct razer_event_data ev;
- struct razer_mouse *m;
- int err;
- libusb_ref_device(udev);
- m = zalloc(sizeof(*m));
- if (!m)
- return NULL;
- m->usb_ctx = razer_create_usb_ctx(udev);
- if (!m->usb_ctx)
- goto err_free_mouse;
- /* Set default values and callbacks */
- m->nr_profiles = 1;
- m->claim = mouse_default_claim;
- m->release = mouse_default_release;
- /* Call the driver init */
- m->base_ops = id->u.mouse_ops;
- err = m->base_ops->init(m, udev);
- if (err)
- goto err_free_ctx;
- udev = m->usb_ctx->dev;
- if (WARN_ON(m->nr_profiles <= 0))
- goto err_release;
- if (m->nr_profiles == 1 && !m->get_active_profile)
- m->get_active_profile = m->get_profiles;
- if (profile_emu_enabled && m->nr_profiles == 1) {
- err = razer_mouse_init_profile_emulation(m);
- if (err)
- goto err_release;
- }
- mouse_apply_initial_config(m);
- razer_debug("Allocated and initialized new mouse \"%s\"\n",
- m->idstr);
- ev.u.mouse = m;
- razer_notify_event(RAZER_EV_MOUSE_ADD, &ev);
- return m;
- err_release:
- m->base_ops->release(m);
- err_free_ctx:
- razer_free(m->usb_ctx, sizeof(*(m->usb_ctx)));
- err_free_mouse:
- razer_free(m, sizeof(*m));
- libusb_unref_device(udev);
- return NULL;
- }
- static void razer_free_mouse(struct razer_mouse *m)
- {
- struct razer_event_data ev;
- razer_debug("Freeing mouse (type=%d)\n",
- m->base_ops->type);
- ev.u.mouse = m;
- razer_notify_event(RAZER_EV_MOUSE_REMOVE, &ev);
- if (m->release == mouse_default_release) {
- while (m->claim_count)
- m->release(m);
- }
- razer_mouse_exit_profile_emulation(m);
- m->base_ops->release(m);
- libusb_unref_device(m->usb_ctx->dev);
- razer_free(m->usb_ctx, sizeof(*(m->usb_ctx)));
- razer_free(m, sizeof(*m));
- }
- static void razer_free_mice(struct razer_mouse *mouse_list)
- {
- struct razer_mouse *mouse, *next;
- for (mouse = mouse_list; mouse; ) {
- next = mouse->next;
- razer_free_mouse(mouse);
- mouse = next;
- }
- }
- struct new_razer_usb_device {
- const struct razer_usb_device *id;
- struct usb_device *udev;
- };
- struct razer_mouse * razer_rescan_mice(void)
- {
- struct libusb_device **devlist, *dev;
- ssize_t nr_devices;
- unsigned int i;
- int err;
- struct libusb_device_descriptor desc;
- const struct razer_usb_device *id;
- struct razer_mouse *m, *next;
- nr_devices = libusb_get_device_list(libusb_ctx, &devlist);
- if (nr_devices < 0) {
- razer_error("razer_rescan_mice: Failed to get USB device list\n");
- return NULL;
- }
- for (i = 0; i < nr_devices; i++) {
- dev = devlist[i];
- err = libusb_get_device_descriptor(dev, &desc);
- if (err) {
- razer_error("razer_rescan_mice: Failed to get descriptor\n");
- continue;
- }
- id = usbdev_lookup(&desc);
- if (!id || id->type != RAZER_DEVTYPE_MOUSE)
- continue;
- m = mouse_list_find(mice_list, dev);
- if (m) {
- /* We already had this mouse */
- m->flags |= RAZER_MOUSEFLG_PRESENT;
- } else {
- /* We don't have this mouse, yet. Create a new one */
- m = mouse_new(id, dev);
- if (m) {
- m->flags |= RAZER_MOUSEFLG_PRESENT;
- mouse_list_add(&mice_list, m);
- }
- }
- }
- /* Remove mice that are not connected anymore. */
- razer_for_each_mouse(m, next, mice_list) {
- if (m->flags & RAZER_MOUSEFLG_PRESENT) {
- m->flags &= ~RAZER_MOUSEFLG_PRESENT;
- continue;
- }
- mouse_list_del(&mice_list, m);
- razer_free_mouse(m);
- }
- libusb_free_device_list(devlist, 1);
- return mice_list;
- }
- int razer_reconfig_mice(void)
- {
- struct razer_mouse *m, *next;
- int err;
- razer_for_each_mouse(m, next, mice_list) {
- err = m->claim(m);
- if (err)
- return err;
- if (m->commit)
- err = m->commit(m, 1);
- m->release(m);
- if (err)
- return err;
- }
- return 0;
- }
- void razer_free_freq_list(enum razer_mouse_freq *freq_list, int count)
- {
- if (freq_list)
- free(freq_list);
- }
- void razer_free_resolution_list(enum razer_mouse_res *res_list, int count)
- {
- if (res_list)
- free(res_list);
- }
- void razer_free_leds(struct razer_led *led_list)
- {
- struct razer_led *led, *next;
- for (led = led_list; led; ) {
- next = led->next;
- free(led);
- led = next;
- }
- }
- int razer_init(int enable_profile_emu)
- {
- int err = 0;
- if (!razer_initialized())
- err = libusb_init(&libusb_ctx);
- if (!err)
- profile_emu_enabled = enable_profile_emu;
- return err ? -EINVAL : 0;
- }
- void razer_exit(void)
- {
- if (!razer_initialized())
- return;
- razer_free_mice(mice_list);
- mice_list = NULL;
- config_file_free(razer_config_file);
- razer_config_file = NULL;
- libusb_exit(libusb_ctx);
- libusb_ctx = NULL;
- }
- int razer_usb_add_used_interface(struct razer_usb_context *ctx,
- int bInterfaceNumber,
- int bAlternateSetting)
- {
- struct razer_usb_interface *interf;
- if (ctx->nr_interfaces >= ARRAY_SIZE(ctx->interfaces)) {
- razer_error("USB context interface array overflow\n");
- return -ENOSPC;
- }
- interf = &ctx->interfaces[ctx->nr_interfaces];
- interf->bInterfaceNumber = bInterfaceNumber;
- interf->bAlternateSetting = bAlternateSetting;
- ctx->nr_interfaces++;
- return 0;
- }
- static void razer_reattach_usb_kdrv(struct razer_usb_context *ctx,
- int bInterfaceNumber)
- {
- int res;
- res = libusb_kernel_driver_active(ctx->h, bInterfaceNumber);
- if (res == 1)
- return;
- if (res) {
- razer_error("Failed to get kernel driver state\n");
- return;
- }
- res = libusb_attach_kernel_driver(ctx->h, bInterfaceNumber);
- if (res) {
- razer_error("Failed to reconnect the kernel driver (%d).\n"
- "The device most likely won't work now. Try to replug it.\n", res);
- return;
- }
- }
- static void razer_usb_release(struct razer_usb_context *ctx,
- int bInterfaceNumber)
- {
- libusb_release_interface(ctx->h, bInterfaceNumber);
- razer_reattach_usb_kdrv(ctx, bInterfaceNumber);
- }
- int razer_generic_usb_claim(struct razer_usb_context *ctx)
- {
- unsigned int tries, i;
- int err, config;
- struct razer_usb_interface *interf;
- err = libusb_open(ctx->dev, &ctx->h);
- if (err) {
- razer_error("razer_generic_usb_claim: Failed to open USB device\n");
- return -ENODEV;
- }
- /* Detach kernel drivers for all interfaces. */
- for (i = 0; i < ctx->nr_interfaces; i++) {
- interf = &ctx->interfaces[i];
- err = libusb_kernel_driver_active(ctx->h, interf->bInterfaceNumber);
- if (err == 1) {
- err = libusb_detach_kernel_driver(ctx->h, interf->bInterfaceNumber);
- if (err) {
- err = -EBUSY;
- razer_error("Failed to detach kernel driver\n");
- goto err_close;
- }
- } else if (err) {
- err = -ENODEV;
- razer_error("Failed to get kernel driver state\n");
- goto err_close;
- }
- }
- tries = 0;
- while (1) {
- if (tries >= 10) {
- razer_error("razer_generic_usb_claim: Failed to claim config\n");
- goto err_close;
- }
- /* Select the correct configuration */
- err = libusb_get_configuration(ctx->h, &config);
- if (err) {
- err = -EBUSY;
- razer_error("razer_generic_usb_claim: Failed to get configuration\n");
- goto err_close;
- }
- if (config != ctx->bConfigurationValue) {
- err = libusb_set_configuration(ctx->h, ctx->bConfigurationValue);
- if (err) {
- err = -EBUSY;
- razer_error("razer_generic_usb_claim: Failed to set configuration\n");
- goto err_close;
- }
- }
- /* And finally claim all interfaces. */
- for (i = 0; i < ctx->nr_interfaces; i++) {
- interf = &ctx->interfaces[i];
- err = libusb_claim_interface(ctx->h, interf->bInterfaceNumber);
- if (err) {
- err = -EIO;
- razer_error("Failed to claim USB interface\n");
- goto err_close;
- }
- err = libusb_set_interface_alt_setting(ctx->h, interf->bInterfaceNumber,
- interf->bAlternateSetting);
- if (err) {
- /* This error triggers on some devices.
- * Just print a warning and ignore. */
- razer_info("razer_generic_usb_claim: "
- "Failed to set alt setting %d on interface %d. "
- "Ignoring...\n",
- (int)interf->bAlternateSetting,
- (int)interf->bInterfaceNumber);
- }
- }
- /* To make sure there was no race, check config value again */
- err = libusb_get_configuration(ctx->h, &config);
- if (err) {
- err = -EBUSY;
- razer_error("razer_generic_usb_claim: Failed to get configuration\n");
- goto err_close;
- }
- if (config == ctx->bConfigurationValue)
- break;
- razer_msleep(100);
- tries++;
- }
- return 0;
- err_close:
- libusb_close(ctx->h);
- return err;
- }
- int razer_generic_usb_claim_refcount(struct razer_usb_context *ctx,
- unsigned int *refcount)
- {
- int err;
- if (!(*refcount)) {
- err = razer_generic_usb_claim(ctx);
- if (err)
- return err;
- }
- (*refcount)++;
- return 0;
- }
- void razer_generic_usb_release(struct razer_usb_context *ctx)
- {
- int i;
- for (i = ctx->nr_interfaces - 1; i >= 0; i--)
- razer_usb_release(ctx, ctx->interfaces[i].bInterfaceNumber);
- libusb_close(ctx->h);
- }
- void razer_generic_usb_release_refcount(struct razer_usb_context *ctx,
- unsigned int *refcount)
- {
- if (*refcount) {
- (*refcount)--;
- if (!(*refcount))
- razer_generic_usb_release(ctx);
- }
- }
- void razer_generic_usb_gen_idstr(struct libusb_device *udev,
- struct libusb_device_handle *h,
- const char *devname,
- bool include_devicenr,
- const char *serial,
- char *idstr_buf)
- {
- char devid[96];
- char serial_buf[64];
- char buspos[16];
- char c;
- size_t i;
- unsigned int serial_index = 0;
- int err;
- struct libusb_device_descriptor devdesc;
- struct razer_usb_context usbctx = {
- .dev = udev,
- .h = h,
- };
- err = libusb_get_device_descriptor(udev, &devdesc);
- if (err) {
- razer_error("razer_generic_usb_gen_idstr: Failed to get "
- "device descriptor (%d)\n", err);
- return;
- }
- if (serial && strlen(serial)) {
- /* Enforce ASCII characters. */
- for (i = 0; i < ARRAY_SIZE(serial_buf) - 1; i++) {
- c = serial[i];
- if (c == '\0')
- break;
- if ((unsigned char)c <= 0x7Fu)
- serial_buf[i] = c;
- else
- serial_buf[i] = '?'; /* Non-ASCII char. */
- }
- serial_buf[i] = '\0';
- serial = serial_buf;
- } else {
- serial_buf[0] = '\0';
- serial_index = devdesc.iSerialNumber;
- err = -EINVAL;
- if (serial_index) {
- err = 0;
- if (!h)
- err = razer_generic_usb_claim(&usbctx);
- if (err) {
- razer_error("Failed to claim device for serial fetching.\n");
- } else {
- err = libusb_get_string_descriptor_ascii(
- usbctx.h, serial_index,
- (unsigned char *)serial_buf, sizeof(serial_buf));
- if (!h)
- razer_generic_usb_release(&usbctx);
- /* Enforce ASCII characters. */
- for (i = 0; i < ARRAY_SIZE(serial_buf); i++) {
- if (serial_buf[i] == '\0')
- break;
- if ((unsigned char)serial_buf[i] > 0x7Fu)
- serial_buf[i] = '?'; /* Non-ASCII char. */
- }
- }
- }
- if (err <= 0)
- strcpy(serial_buf, "0");
- serial = serial_buf;
- }
- snprintf(devid, sizeof(devid), "%04X-%04X-%s",
- devdesc.idVendor,
- devdesc.idProduct, serial);
- if (include_devicenr) {
- snprintf(buspos, sizeof(buspos), "%03d-%03d",
- libusb_get_bus_number(udev),
- libusb_get_device_address(udev));
- } else {
- snprintf(buspos, sizeof(buspos), "%03d",
- libusb_get_bus_number(udev));
- }
- razer_create_idstr(idstr_buf, BUSTYPESTR_USB, buspos,
- DEVTYPESTR_MOUSE, devname, devid);
- }
- /** razer_usb_force_hub_reset
- * Force reset of the hub the specified device is on
- */
- int razer_usb_force_hub_reset(struct razer_usb_context *device_ctx)
- {
- struct libusb_device_handle *h;
- struct libusb_device *hub = NULL, *dev;
- uint8_t hub_bus_number, hub_device_address;
- struct razer_usb_reconnect_guard rg;
- int err;
- struct libusb_device **devlist;
- ssize_t devlist_size, i;
- razer_debug("Forcing hub reset for device %03u:%03u\n",
- libusb_get_bus_number(device_ctx->dev),
- libusb_get_device_address(device_ctx->dev));
- razer_usb_reconnect_guard_init(&rg, device_ctx);
- hub_bus_number = libusb_get_bus_number(device_ctx->dev);
- hub_device_address = 1; /* Constant */
- devlist_size = libusb_get_device_list(libusb_ctx, &devlist);
- for (i = 0; i < devlist_size; i++) {
- dev = devlist[i];
- if (libusb_get_bus_number(dev) == hub_bus_number &&
- libusb_get_device_address(dev) == hub_device_address) {
- hub = dev;
- break;
- }
- }
- if (!hub) {
- razer_error("razer_usb_force_reinit: Failed to find hub\n");
- err = -ENODEV;
- goto error;
- }
- razer_debug("Resetting root hub %03u:%03u\n",
- hub_bus_number, hub_device_address);
- err = libusb_open(hub, &h);
- if (err) {
- razer_error("razer_usb_force_reinit: Failed to open hub device\n");
- err = -ENODEV;
- goto error;
- }
- libusb_reset_device(h);
- libusb_close(h);
- err = razer_usb_reconnect_guard_wait(&rg, 1);
- if (err) {
- razer_error("razer_usb_force_reinit: "
- "Failed to discover the reconnected device\n");
- goto error;
- }
- razer_debug("Hub reset completed. Device rediscovered as %03u:%03u\n",
- libusb_get_bus_number(device_ctx->dev),
- libusb_get_device_address(device_ctx->dev));
- err = 0;
- error:
- libusb_free_device_list(devlist, 1);
- return err;
- }
- /** razer_usb_reconnect_guard_init - Init the reconnect-guard context
- *
- * Call this _before_ triggering any device operations that might
- * reset the device.
- */
- int razer_usb_reconnect_guard_init(struct razer_usb_reconnect_guard *guard,
- struct razer_usb_context *ctx)
- {
- int err;
- guard->ctx = ctx;
- err = libusb_get_device_descriptor(ctx->dev, &guard->old_desc);
- if (err) {
- razer_error("razer_usb_reconnect_guard_init: Failed to "
- "get device descriptor\n");
- return err;
- }
- guard->old_busnr = libusb_get_bus_number(ctx->dev);
- guard->old_devaddr = libusb_get_device_address(ctx->dev);
- return 0;
- }
- static struct libusb_device * guard_find_usb_dev(const struct libusb_device_descriptor *expected_desc,
- uint8_t expected_bus_number,
- uint8_t expected_dev_addr,
- bool exact_match)
- {
- struct libusb_device **devlist, *dev;
- struct libusb_device_descriptor desc;
- uint8_t dev_addr;
- ssize_t nr_devices, i, j;
- int err;
- nr_devices = libusb_get_device_list(libusb_ctx, &devlist);
- if (nr_devices < 0) {
- razer_error("guard_find_usb_dev: Failed to get device list\n");
- return NULL;
- }
- for (i = 0; i < nr_devices; i++) {
- dev = devlist[i];
- if (libusb_get_bus_number(dev) != expected_bus_number)
- continue;
- err = libusb_get_device_descriptor(dev, &desc);
- if (err)
- continue;
- if (memcmp(&desc, expected_desc, sizeof(desc)) != 0)
- continue;
- dev_addr = libusb_get_device_address(dev);
- if (exact_match) {
- if (dev_addr == expected_dev_addr)
- goto found_dev;
- } else {
- for (j = 0; j < 64; j++) {
- if (dev_addr == ((expected_dev_addr + j) & 0x7F))
- goto found_dev;
- }
- }
- }
- libusb_free_device_list(devlist, 1);
- return NULL;
- found_dev:
- libusb_ref_device(dev);
- libusb_free_device_list(devlist, 1);
- return dev;
- }
- /** razer_usb_reconnect_guard_wait - Protect against a firmware reconnect.
- *
- * If the firmware does a reconnect of the device on the USB bus, this
- * function tries to keep track of the device and it will update the
- * usb context information.
- * Of course, this is not completely race-free, but we try to do our best.
- *
- * hub_reset is true, if the device reconnects due to a HUB reset event.
- * Otherwise it's assumed that the device reconnects on behalf of itself.
- * If hub_reset is false, the device is expected to be claimed.
- */
- int razer_usb_reconnect_guard_wait(struct razer_usb_reconnect_guard *guard, bool hub_reset)
- {
- uint8_t reconn_dev_addr;
- uint8_t old_dev_addr = guard->old_devaddr;
- uint8_t old_bus_number = guard->old_busnr;
- int res, errorcode = 0;
- struct libusb_device *dev;
- struct timeval now, timeout;
- if (!hub_reset) {
- /* Release the device, so the kernel can detect the bus reconnect. */
- razer_generic_usb_release(guard->ctx);
- }
- /* Wait for the device to disconnect. */
- gettimeofday(&timeout, NULL);
- razer_timeval_add_msec(&timeout, 3000);
- while (1) {
- dev = guard_find_usb_dev(&guard->old_desc,
- old_bus_number, old_dev_addr, 1);
- if (!dev)
- break;
- libusb_unref_device(dev);
- gettimeofday(&now, NULL);
- if (razer_timeval_after(&now, &timeout)) {
- /* Timeout. Hm. It seems the device won't reconnect.
- * That's probably OK. Reclaim it. */
- razer_error("razer_usb_reconnect_guard: "
- "The device did not disconnect! If it "
- "does not work anymore, try to replug it.\n");
- goto reclaim;
- }
- razer_msleep(50);
- }
- /* Construct the device address it will reconnect on.
- * On a device reset the new dev addr will be >= reconn_dev_addr.
- */
- reconn_dev_addr = (old_dev_addr + 1) & 0x7F;
- /* Wait for the device to reconnect. */
- gettimeofday(&timeout, NULL);
- razer_timeval_add_msec(&timeout, 3000);
- while (1) {
- dev = guard_find_usb_dev(&guard->old_desc,
- old_bus_number, reconn_dev_addr, 0);
- if (dev)
- break;
- gettimeofday(&now, NULL);
- if (razer_timeval_after(&now, &timeout)) {
- razer_error("razer_usb_reconnect_guard: The device did not "
- "reconnect! It might not work anymore. Try to replug it.\n");
- razer_debug("Expected reconnect busid was: %02u:>=%03u\n",
- old_dev_addr, reconn_dev_addr);
- errorcode = -EBUSY;
- goto out;
- }
- razer_msleep(50);
- }
- /* Update the USB context. */
- libusb_unref_device(guard->ctx->dev);
- guard->ctx->dev = dev;
- reclaim:
- if (!hub_reset) {
- /* Reclaim the new device. */
- res = razer_generic_usb_claim(guard->ctx);
- if (res) {
- razer_error("razer_usb_reconnect_guard: Reclaim failed.\n");
- return res;
- }
- }
- out:
- return errorcode;
- }
- int razer_load_config(const char *path)
- {
- struct config_file *conf = NULL;
- if (!razer_initialized())
- return -EINVAL;
- if (!path)
- path = RAZER_DEFAULT_CONFIG;
- if (strlen(path)) {
- conf = config_file_parse(path, 1);
- if (!conf)
- return -ENOENT;
- }
- config_file_free(razer_config_file);
- razer_config_file = conf;
- return 0;
- }
- void razer_set_logging(razer_logfunc_t info_callback,
- razer_logfunc_t error_callback,
- razer_logfunc_t debug_callback)
- {
- razer_logfunc_info = info_callback;
- razer_logfunc_error = error_callback;
- razer_logfunc_debug = debug_callback;
- }
- static void do_init_axis(struct razer_axis *axis,
- unsigned int id, const char *name, unsigned int flags)
- {
- if (name) {
- axis->id = id;
- axis->name = name;
- axis->flags = flags;
- }
- }
- void razer_init_axes(struct razer_axis *axes,
- const char *name0, unsigned int flags0,
- const char *name1, unsigned int flags1,
- const char *name2, unsigned int flags2)
- {
- do_init_axis(&axes[0], 0, name0, flags0);
- do_init_axis(&axes[1], 1, name1, flags1);
- do_init_axis(&axes[2], 2, name2, flags2);
- }
- struct razer_mouse_dpimapping * razer_mouse_get_dpimapping_by_res(
- struct razer_mouse_dpimapping *mappings, size_t nr_mappings,
- enum razer_dimension dim, enum razer_mouse_res res)
- {
- struct razer_mouse_dpimapping *mapping = NULL;
- size_t i;
- for (i = 0; i < nr_mappings; i++) {
- if (mappings[i].res[dim] == res) {
- mapping = &mappings[i];
- break;
- }
- }
- return mapping;
- }
- void razer_event_spacing_init(struct razer_event_spacing *es,
- unsigned int msec)
- {
- memset(es, 0, sizeof(*es));
- es->spacing_msec = msec;
- }
- void razer_event_spacing_enter(struct razer_event_spacing *es)
- {
- struct timeval now, deadline;
- int wait_msec;
- gettimeofday(&now, NULL);
- deadline = es->last_event;
- razer_timeval_add_msec(&deadline, es->spacing_msec);
- if (razer_timeval_after(&deadline, &now)) {
- /* We have to sleep long enough to ensure we're
- * after the deadline. */
- wait_msec = razer_timeval_msec_diff(&deadline, &now);
- WARN_ON(wait_msec < 0);
- razer_msleep(wait_msec + 1);
- gettimeofday(&now, NULL);
- razer_error_on(razer_timeval_after(&deadline, &now),
- "Failed to maintain event spacing\n");
- }
- }
- void razer_event_spacing_leave(struct razer_event_spacing *es)
- {
- gettimeofday(&es->last_event, NULL);
- }
|