RazmjenaVjestina
MarcellMarsCodeGamepadX: Revision 1

= GamepadX =

at the moment i try to get account at savannah.gnu.org with this project:

'''"topot" is python scripting environment to allow classic input devices, gamepads/joysticks and midi/osc gears to mimic each other... to use mouse/keyboard as midi/osc controlers and vice versa...

visualisations of the parameters in charge is an extra layer.

the code written till now is at wiki page:
http://www.razmjenavjestina.org/MarcellMars/MarcellMarsCodeGamepadX

it allows user to use gamepad as mouse, keyboard or any other system call written in XAction class.. also there is a draft class which allows user to use MIDI controller as a regular mouse...'''

Gamepad``X is a little python script which prepares gamepad (in my case http://www.logitech.com/index.cfm/gaming/pc_gaming/gamepads/devices/287&cl=us,en Logitech Cordless Rumble Pad) to act as mouse, arrows, backspace, delete, enter, escape... whatever u put in methods of class XAction ;)

if you are looking for the "real app" for making your joystick the new mouse in X try http://qjoypad.sourceforge.net/... unfortunately i didn't test it but it seems quite matured :*

at the moment the configuration is in konf list where the first member of the list is pseudo-modifier, second is axe or button of the gamepad, third the number of ax or button and finally forth is the name of the method of class Kontroler which will be called after particular axe or button is pressed. modifiers should be used to bring extra functionality for axis or buttons and therefore should be placed before other (non-modifiers) functionalities in the conf list... when modifier is pressed the particular axe or button when pressed gets different job than when pressed without the modifier.. as easy as that ;)

the future plans are to make "while 1:" separated thread + make python OSC/MIDI server (open sound control) which will call then methods of XAction so it will be possible to use MIDI gears to cheat X server ;)

''UPDATE: the proof of concept regarding MIDI is in the code.. and at the moment MIDI controllers 72 and 73 are mouse axis and notes 49, 50 and 51 are left/middle/right click of the mouse... it is easy to catch any other midi event and make it do whatever is in XAction class... if testing just be sure that your MIDI controller is connected to Get``MIDI midi device... i recommend qjackctl for doing that''

the other thing is to make this also controller of http://www.bljak.org/rvwm rvwm fork of http://www.6809.org.uk/evilwm/ evilwm. http://www.bljak.org/rvwm rvwm are python bindings of http://www.6809.org.uk/evilwm/ evilwm controllable from interactive python sessions (separated thread)...

whatever...

it depends on http://freshmeat.net/projects/pyjsw/ pyJSW responsible for communication to gamepad and
http://www.sci.ccny.cuny.edu/~brinkman/software/pyseq/ pyseq responsible for communication to X server.

{{{

from pyrobot import *
import JSW,sys,time
from pyseq import *

class GetMIDI(PySeq):
    def __init__(self):
        PySeq.__init__(self,'GetMIDI')
        self.iport = self.createInPort('')

    def startGetMIDI(self):
        self.mt=MidiThread(self)
        self.mt.start()

    def callback(self, ev):
        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 48 \
and ev.getData().velocity > 0:
            K.leftClick(1, 'midi00')
        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 48 \
and ev.getData().velocity == 0:
            K.leftClick(0, 'midi00')

        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 49 \
and ev.getData().velocity > 0:
            K.middleClick(1, 'midi01')
        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 49 \
and ev.getData().velocity == 0:
            K.middleClick(0, 'midi01')

        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 50 \
and ev.getData().velocity > 0:
            K.rightClick(1, 'midi02')
        if ev.type == SND_SEQ_EVENT_NOTEON and ev.getData().note == 50 \
and ev.getData().velocity == 0:
            K.rightClick(0, 'midi02')

        if ev.type == SND_SEQ_EVENT_CONTROLLER and ev.getData().param == 73:
            K.mouseX = (ev.getData().value + 1)(1024/128)
            K.moveMouse()
        if ev.type == SND_SEQ_EVENT_CONTROLLER and ev.getData().param == 72:
            K.mouseY = (ev.getData().value + 1)
(1024/128)
            K.moveMouse()

        return 1

class XAction:
    def __init__(self):
        self.R = PyRobot()
        self.dev = "/dev/input/js0"
        self.cal = "/tmp/.joystick"
        self.jsd = JSW.Joystick(self.dev,self.cal)
        self.ax = self.jsd.getAxisCoeff
        self.bt = self.jsd.getButtonState
        self.mouseX = 0
        self.mouseY = 0
        self.states = {}
        for i in range(self.jsd.axisCount):
            self.states['ax'+str(i)] = 0
        for i in range(self.jsd.buttonCount):
            self.states['bt'+str(i)] = 0
        self.states['ax4b'] = 0
        self.states['ax5b'] = 0
        for i in range(3):
            self.states['midi0'+str(i)] = 0

    def getMouseCoord(self):
        self.R.grabAll()
        ev = self.R.getEvent()
        dat = ev.getData()
        self.mouseX, self.mouseY = dat.x, dat.y
        self.R.releaseAll()

    def setMouseX(self, x, state):
        step = self.getMouseStep(x)
        if x > 0:
            self.mouseX += step + 1
            if self.mouseX > 1024: self.mouseX = 1024
        elif x < 0:
            self.mouseX += step - 1
            if self.mouseX < 0: self.mouseX = 0

    def setMouseY(self, y, state):
        step = self.getMouseStep(y)
        if y > 0:
            self.mouseY = step + 1
            if self.mouseY > 768: self.mouseY = 768
        elif y < 0:
            self.mouseY
= step - 1
            if self.mouseY < 0: self.mouseY = 0

    def getMouseStep(self, s):
        return int(((round(s,2)*100)**3)/20000)

    def moveMouse(self):
        self.R.sendMotionEvent(self.mouseX, self.mouseY)

    def leftClick(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendButtonEvent(1,1)
            self.states[state] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendButtonEvent(1,0)
            self.states[state] = 0

    def rightClick(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendButtonEvent(3,1)
            self.states[state] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendButtonEvent(3,0)
            self.states[state] = 0

    def middleClick(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendButtonEvent(2,1)
            self.states[state] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendButtonEvent(2,0)
            self.states[state] = 0

    def arrowUpDownAx(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendKeyEvent(98,1)
            self.states[state] = 1
        elif click == -1 and self.states[state+'b'] == 0:
            self.R.sendKeyEvent(104,1)
            self.states[state+'b'] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendKeyEvent(98,0)
            self.states[state] = 0
        elif click == 0 and self.states[state+'b'] == 1:
            self.R.sendKeyEvent(104,0)
            self.states[state+'b'] = 0

    def arrowLeftRightAx(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendKeyEvent(102,1)
            self.states[state] = 1
        elif click == -1 and self.states[state+'b'] == 0:
            self.R.sendKeyEvent(100,1)
            self.states[state+'b'] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendKeyEvent(102,0)
            self.states[state] = 0
        elif click == 0 and self.states[state+'b'] == 1:
            self.R.sendKeyEvent(100,0)
            self.states[state+'b'] = 0

    def backspaceDeleteAx(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendKeyEvent(107,1)
            self.states[state] = 1
        elif click == -1 and self.states[state+'b'] == 0:
            self.R.sendKeyEvent(22,1)
            self.states[state+'b'] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendKeyEvent(107,0)
            self.states[state] = 0
        elif click == 0 and self.states[state+'b'] == 1:
            self.R.sendKeyEvent(22,0)
            self.states[state+'b'] = 0

    def enterEscapeAx(self, click, state):
        if click == 1 and self.states[state] == 0:
            self.R.sendKeyEvent(9,1)
            self.states[state] = 1
        elif click == -1 and self.states[state+'b'] == 0:
            self.R.sendKeyEvent(36,1)
            self.states[state+'b'] = 1
        elif click == 0 and self.states[state] == 1:
            self.R.sendKeyEvent(9,0)
            self.states[state] = 0
        elif click == 0 and self.states[state+'b'] == 1:
            self.R.sendKeyEvent(36,0)
            self.states[state+'b'] = 0

Midi = GetMIDI()
Midi.startGetMIDI()

K = XAction()
K.getMouseCoord()
nomo_state = 0

konf = [ [['bt',7], 'ax', 4, 'backspaceDeleteAx'],
                [['bt',7], 'ax', 5, 'enterEscapeAx'],
                [[], 'ax', 2, 'setMouseX'],
                [[], 'ax', 3, 'setMouseY'],
                [[], 'bt', 4, 'leftClick'],
                [[], 'bt', 6, 'rightClick'],
                [[], 'bt', 5, 'middleClick'],
                [[], 'ax', 5, 'arrowUpDownAx'],
                [[], 'ax', 4, 'arrowLeftRightAx']
                ]

try:
    while 1:
        for i in konf:
            if getattr(K,i[1])(i[2]) != 0:
                keep = True

        if K.jsd.update() or keep == True:
            keep = False
            K.moveMouse()
            for i,iobj in enumerate(konf):
                for j in iobj[0]:
                    if getattr(K, j[0])(j[1]) == 1:
                        nomo_state += 1

                if nomo_state == len(konf[i]0):
                        nomo_state = 0
                        getattr(K, konf[i]3) \
(getattr(K, konf[i]1)(konf[i]2),konf[i]1+str(konf[i]2))
                else:
                    nomo_state = 0

        sys.stdout.flush()
        time.sleep(0.02)

except KeyboardInterrupt:
    print
    sys.exit()

}}}