[visionegg] Re: Input from Wacom graphics tablet?

  • From: Neil Halelamien <neilh@xxxxxxxxxxx>
  • To: visionegg@xxxxxxxxxxxxx
  • Date: Mon, 11 Sep 2006 13:22:46 -0700

Sorry about not responding until now... I think my mail server or client is doing funny things to some of my mail.

(Also, the 2nd link you gave doesn't seem to work...)

I ended up hacking together a solution which worked, at least for my current setup under Windows. I've attached some (non-prettified) example code to this email. There were a few caveats I found:

* If the program is being run windowed, the pen position information is identical to the mouse input position. However, if it is being run fullscreen, the input mode totally changes and it becomes necessary to use the information for relative change in mouse position.

* With the relative-change information, (0,0) is the center of the tablet, so you'll need to add half the screen width and height to the x and y coords to convert to screen coords.

* When using the relative-change information, there are a couple of other problems which I think are due to either undersampling or oversampling:

** Oversampling: It seems that after the tablet input is polled, the relative-change information gets reset to (0,0). If the input is polled more often than it gets refreshed, this results in spurious (0,0)'s. This can easily be worked around by just throwing out all the (0,0)'s.

** Undersampling: If the tablet input get refreshed more than once between the times that the program polls it, the relative-change information accumulates. This causes an effect where the cursor periodically jumps away from the center. The most reliable solution I've found for this is to simply increase the thread priority; when running on maximum priority, I've never seen it undersample.

Not having tried a Wacom tablet, I don't have a whole lot of advice.
SDL and as a consequence pygame don't have direct support for a tablet, and the 
question has been asked on both lists relatively recently:
http://www.libsdl.org/pipermail/sdl/2005-October/070927.html
http://www.mail-archive.com/pygame-users@xxxxxxxx/msg00730.html

You should be able to use the tablet as a mouse however, as is suggested in the 
second link, by adding the current position to the vector components. It's 
likely you won't be able to easily use a tablet in visionegg, unless you write 
your own interface.

Mark


On Aug 30, 2006, at 7:23 PM, Neil Halelamien wrote:


Is there any way I can get input from a Wacom graphics tablet? Right now Vision Egg is treating the tablet as a drifting mouse (position on tablet becomes cursor velocity), rather than a tablet.

    It seems that pygame doesn't have any explicit tablet input method, so if I 
wanted to implement tablet support myself, what options do I have? Is there 
anything I could do without having to edit pygame itself?

    Thanks!


-- Neil Halelamien ====================================== The Vision Egg mailing list Archives: //www.freelists.org/archives/visionegg Website: http://www.visionegg.org/mailinglist.html

#!/usr/bin/env python

from VisionEgg import *
start_default_logging(); watch_exceptions()

from VisionEgg.Core import *
from VisionEgg.FlowControl import Presentation, FunctionController
from VisionEgg.Textures import *
import pygame
import Image, ImageDraw
import Numeric

import OpenGL.GL as gl

screen = get_default_screen()

image_size = screen.size

image = Image.new("L",image_size,(0)) 
draw = ImageDraw.Draw(image)


# create a TextureStimulus to allocate memory in OpenGL
stimulus = TextureStimulus(mipmaps_enabled=0,
                           texture=Texture(image),
                           size=image_size,
                           texture_min_filter=gl.GL_LINEAR,
                           position=(screen.size[0]/2.0,screen.size[1]/2.0),
                           anchor='center')

cursor = FixationSpot()

viewport = Viewport(screen=screen,
                    stimuli=[stimulus, cursor])


(x,y) = pygame.mouse.get_pos() # hack to allow scope in put_image
old_pos = [x,y]
old_xy = old_pos

# Use a controller to hook into go loop, but control texture buffer
# through direct manipulation.
texture_object = stimulus.parameters.texture.get_texture_object()
fullscreen = screen.constant_parameters.fullscreen


p = Presentation(go_duration=('forever',),viewports=[viewport])
#p = Presentation(go_duration=(10.0, 'seconds'),viewports=[viewport])

def keydown(event):
    if event.key == pygame.locals.K_ESCAPE:
        quit(event)
        
def quit(event):
    print 'quit'
    p.parameters.go_duration = (0,'frames')


p.parameters.handle_event_callbacks = [(pygame.locals.QUIT, quit),
    (pygame.locals.KEYDOWN, keydown)]

def put_image(t):
    # can run into problems with fullscreen mode if long time since last 
mouse.get_rel() call, since doubles distance from center
    # using max-priority reduces problems
    (relx,rely) = pygame.mouse.get_rel()
    (x,y) = pygame.mouse.get_pos()
    posx = x
    posy = y
    pressed = pygame.mouse.get_pressed()
    if old_pos[0] is 0 and old_pos[1] is 0:
        old_pos[0] = posx
        old_pos[1] = posy
        return
    if relx is 0 and rely is 0:
        return
    if fullscreen:
        x = relx
        y = rely
        x = x + screen.size[0]/2
        y = y + screen.size[1]/2
        #if abs(old_xy[0] - x) > rel_thresh or abs(old_xy[1] - y) > rel_thresh:
            #return
            
    cursor.parameters.position = (x,screen.size[1]-y)
    
    if pressed[0]: 
        draw.line(old_xy+[x,y],fill=(255))
        texture_object.put_sub_image(image)
    old_pos[0] = posx # can't do old_pos = (x,y), because ruins scope
    old_pos[1] = posy
    old_xy[0] = x
    old_xy[1] = y
p.add_controller(None,None,FunctionController(during_go_func=put_image))

p.go()

Other related posts: