teaching machines

OpenGL and Mouse Interaction on Raspberry Pi

October 4, 2012 by . Filed under buster, public.

Last time I was able to get a simple triangle up on my Raspberry Pi using Python bindings for OpenGL ES. My goal this week was to get mouse interaction going. My big question was, “Can I move the triangle?”

Normally I’d use a windowing toolkit like wxWidgets or SDL to get mouse events. But I’m not even running an X server on my Raspberry Pi! I looked at the demos in pyopengles and found that they could run without X and still support mouse interaction. Having grown up on supporting libraries, this was not a world I was familiar with. I found the details inĀ pymouse.py.

To get mouse interaction in my demo, I followed this progression:

And it all worked!

Here’s my crude mouse listener:

#!/usr/bin/env python

import threading
import time

class MouseListener(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    self.fd = open('/dev/input/mouse0', 'r')
    self.height = 1080
    self.width = 1920
    self.x = self.height / 2
    self.y = self.width / 2
    self.finished = False

  def run(self):
    while 1:
      while 1:
        buttons, dx, dy = map(ord, self.fd.read(3))

        # Bit 3 is always set. Always! Move on.
        if buttons & (1 << 3):
          break

        # Maybe not always? Maybe a read failed and bit 3 wasn't set.
        # The original author suggests we try to sync up again with a
        # read of one byte. Why only one?
        self.fd.read(1)

      if buttons & (1 << 1) and buttons & (1 << 0):
        print 'both pressed'
        self.finished = True
        break
      elif buttons & (1 << 2):
        print 'middle press'
      elif buttons & (1 << 1):
        print 'right press'
      elif buttons & (1 << 0):
        print 'left press'

      # Going left 
      if buttons & (1 << 4):
        dx -= 256

      # Going right
      if buttons & (1 << 5):
        dy -= 256

      self.x += dx
      self.y += dy

      if self.x < 0:
        self.x = 0
      elif self.x > self.width:
        self.x = self.width

      if self.y < 0:
        self.y = 0
      elif self.y > self.height:
        self.y = self.height

def startMouse():
  thread = MouseListener()
  thread.start()
  return thread

startMouse()