#!/usr/bin/env python # # Razer device commandline configuration tool # # Copyright (C) 2007-2009 Michael Buesch # # 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. import sys import os import getopt import time from ConfigParser import * from pyrazer import * razer = None def getRazer(): global razer if razer is None: razer = Razer() return razer class OpSleep: def __init__(self, seconds): self.seconds = seconds def run(self, idstr): time.sleep(self.seconds) class OpGetFwVer: def run(self, idstr): verTuple = getRazer().getFwVer(idstr) print "The firmware version for the mouse %s is: %d.%d" %\ (idstr, verTuple[0], verTuple[1]) class OpGetFreq: def run(self, idstr): freqs = getRazer().getSupportedFreqs(idstr) profiles = getRazer().getProfiles(idstr) for profile in profiles: sys.stdout.write("Profile %u: " % (profile + 1)) curFreq = getRazer().getCurrentFreq(idstr, profile) for freq in freqs: if freq == curFreq: sys.stdout.write(">>%u Hz<<, " % freq) else: sys.stdout.write("%u Hz, " % freq) print "" class OpGetRes: def run(self, idstr): mappings = getRazer().getSupportedDpiMappings(idstr) profiles = getRazer().getProfiles(idstr) for profile in profiles: sys.stdout.write("Profile %u: " % (profile + 1)) curMapping = getRazer().getDpiMapping(idstr, profile) for mapping in mappings: if mapping[0] == curMapping: sys.stdout.write(">>%u (%u DPI)<<, " % (mapping[0] + 1, mapping[1])) else: sys.stdout.write("%u (%u DPI), " % (mapping[0] + 1, mapping[1])) print "" class OpPrintLeds: def run(self, idstr): leds = getRazer().getLeds(idstr) print "LEDs on mouse %s:" % idstr for led in leds: if led[1] == 0: state = "off" elif led[1] == 1: state = "on" else: state = "unknown" sys.stdout.write("%s => %s, " % (led[0], state)) print "" class OpSetLed: def __init__(self, cfgStr): self.cfgStr = cfgStr def run(self, idstr): cfgStr = self.cfgStr.split(":") try: newState = cfgStr[-1].strip().lower() ledName = ":".join(cfgStr[:-1]) if not ledName: raise ValueError() if newState in ["0", "off", "false"]: newState = False elif newState in ["1", "on", "true"]: newState = True else: raise ValueError() except (IndexError, ValueError): raise RazerEx("Invalid parameter to --setled option") error = getRazer().setLed(idstr, ledName, newState) if error: raise RazerEx("Failed to set LED state. Error code is %d" % error) class OpSetRes: def __init__(self, param): self.param = param def run(self, idstr): try: p = self.param.split(":") if len(p) != 2: raise ValueError profile = int(p[0].strip()) mapping = int(p[1].strip()) except ValueError: raise RazerEx("Invalid parameter to --res option") error = getRazer().setDpiMapping(idstr, profile - 1, mapping - 1) if error: raise RazerEx("Failed to set resolution to %u (error=%d)" %\ (mapping, error)) class OpSetFreq: def __init__(self, param): self.param = param def run(self, idstr): try: p = self.param.split(":") if len(p) != 2: raise ValueError profile = int(p[0].strip()) freq = int(p[1].strip()) except ValueError: raise RazerEx("Invalid parameter to --freq option") error = getRazer().setFrequency(idstr, profile - 1, freq) if error: raise RazerEx("Failed to set frequency to %d Hz (error=%d)" %\ (freq, error)) class OpFlashFw: def __init__(self, filename): self.filename = filename def run(self, idstr): p = RazerFirmwareParser(self.filename) data = p.getImage() print "Flashing firmware on %s ..." % idstr print "!!! DO NOT DISCONNECT ANY DEVICE !!!" print "Sending %d bytes..." % len(data) error = getRazer().flashFirmware(idstr, data) if error: raise RazerEx("Failed to flash firmware (error=%d)" % error) print "Firmware successfully flashed." # Operations on a device class DevOps: def __init__(self, idstr): self.idstr = idstr self.ops = [] def add(self, op): self.ops.append(op) def runAll(self): for op in self.ops: op.run(self.idstr) def scanDevices(): getRazer().rescanMice() mice = getRazer().getMice() for mouse in mice: print mouse def backgroundRescan(): if os.fork() == 0: getRazer().rescanMice() def exit(exitcode): sys.exit(exitcode) def prVersion(): print "Razer device configuration tool" print "Version", RAZER_VERSION def usage(): prVersion() print "" print "Usage: razercfg [OPTIONS] [-d DEV DEVOPS] [-d DEV DEVOPS]..." print "" print "-h|--help Print this help text" print "-v|--version Print the program version number" print "-s|--scan Scan for devices and print the bus IDs" print "" print "-d|--device DEV Selects the device with the bus ID \"DEV\"" print " Use the special value \"mouse\" for DEV to select" print " the first razer mouse device found in the system." print "-c|--config FILE Read the config file and apply it." print " Use the special value \".\" for FILE to select the default file" print "" print "-S|--sleep SECS Sleep SECS seconds." print "" print "Device operations (DEVOPS):" print "These options apply to the device that is specified with -d" print "" print "Options for mice:" print "-V|--fwver Print the firmware version number" print "-r|--res profile:DPI Changes the scan resolution" print "-R|--getres Prints the resolutions" print "-f|--freq profile:FREQ Changes the scan frequency" print "-F|--getfreq Prints the frequencies" print "-L|--leds Print the identifiers of the LEDs on the device" print "-l|--setled LED:off Toggle the LED with the identifier \"LED\" ON or OFF" print "-X|--flashfw FILE Flash a firmware image to the device" def findDevice(deviceType=None): if deviceType is None or deviceType == "mouse": getRazer().rescanMice() mice = getRazer().getMice() if mice: return mice[0] # Return the first idstr if deviceType: raise RazerEx("No Razer mouse found in the system") raise RazerEx("No Razer device found in the system") def parse_args(): devOpsList = [] currentDevOps = None try: (opts, args) = getopt.getopt(sys.argv[1:], "hvsd:r:Rf:FLl:Vc:S:X:", [ "help", "version", "scan", "bg-rescan", "device=", "res=", "getres", "freq=", "getfreq", "leds", "setled=", "fwver", "config=", "sleep=", "flashfw=", ]) except getopt.GetoptError: usage() exit(1) for (o, v) in opts: if o in ("-h", "--help"): usage() exit(0) if o in ("-v", "--version"): prVersion() exit(0) if o in ("-s", "--scan"): scanDevices() exit(0) if o in ("--bg-rescan", ): backgroundRescan() exit(0) if o in ("-d", "--device"): if v == "mouse": # magic; select the first mouse v = findDevice("mouse") if currentDevOps and currentDevOps.ops: devOpsList.append(currentDevOps) currentDevOps = DevOps(v) continue # if o in ("-c", "--config"): # pass#TODO if o in ("-r", "--res"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpSetRes(v)) continue if o in ("-R", "--getres"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpGetRes()) continue if o in ("-f", "--freq"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpSetFreq(v)) continue if o in ("-F", "--getfreq"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpGetFreq()) continue if o in ("-L", "--leds"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpPrintLeds()) continue if o in ("-l", "--setled"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpSetLed(v)) continue if o in ("-V", "--fwver"): if not currentDevOps: currentDevOps = DevOps(findDevice()) currentDevOps.add(OpGetFwVer()) continue if o in ("-S", "--sleep"): ops = currentDevOps if not currentDevOps: ops = DevOps(None) try: v = float(v) except ValueError: raise RazerEx("Value for -S|--sleep must be a floating point value") ops.add(OpSleep(v)) if not currentDevOps: devOpsList.append(ops) continue if o in ("-X", "--flashfw"): if not currentDevOps: raise RazerEx("Must specify a device (-d) before -X|--flashfw") currentDevOps.add(OpFlashFw(v)) continue if currentDevOps and currentDevOps.ops: devOpsList.append(currentDevOps) if not devOpsList: usage() exit(1) return devOpsList def main(): try: devOpsList = parse_args() for devOps in devOpsList: devOps.runAll() except (RazerEx), e: print e return 1 return 0 if __name__ == "__main__": exit(main())