2009-04-10 9 views
6

Estoy desarrollando una extensión de PsychToolbox de MATLAB que permite un mejor control del mouse durante experimentos psicofísicos (específicamente, evitando que los límites de la pantalla limiten las operaciones de arrastre ... debería sentir como si pudieras mover el mouse "infinitamente" en todas las direcciones). Como MATLAB no admite la creación de subprocesos adicionales (y eso se complicaría innecesariamente para esta situación), no puedo utilizar los gestores de eventos Carbon o Cocoa.Mac OS X: CGGetLastMouseDelta y moviendo el mouse programáticamente

CGGetLastMouseDelta es casi perfecto para lo que tengo que hacer (me pone la cantidad que el ratón se ha movido "desde el último evento de movimiento del ratón recibida por la aplicación" ignorando límites de la pantalla), sin embargo hay un pequeño problema. Al mover el mouse de forma programática (utilizando CGWarpMouseCursorPosition o CGDisplayMoveCursorToPoint), no se generan eventos. Por lo tanto, CGGetLastMouseDelta no parece saber que el mouse se ha movido en absoluto. En otras palabras, si muevo el mouse 50 píxeles hacia arriba y 50 píxeles hacia abajo mediante programación, CGGetLastMouseDelta regresa (0, 0) después para el delta del mouse. Este es un comportamiento indeseable en mi contexto y requiere soluciones desagradables. He intentado mover el ratón mediante la publicación de eventos a través del sistema de eventos, de la siguiente manera (se trata de una "mexFunction", forma de MATLAB de llamar a código C):

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 
    CGEventRef event; 
    CGPoint offset; 
    CGPoint currentLocation; 
    CGPoint newLocation; 

    if (nrhs != 2) 
     mexErrMsgTxt("The global x and y coordinates (and only those) must be supplied."); 

    event = CGEventCreate(NULL); 
    currentLocation = CGEventGetLocation(event); 
    CFRelease(event); 

    offset = CGPointMake((CGFloat) mxGetScalar(prhs[0]), (CGFloat) mxGetScalar(prhs[1])); 
    newLocation = CGPointMake(currentLocation.x + offset.x, currentLocation.y + offset.y); 

    event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, newLocation, kCGMouseButtonLeft); 
    CGEventPost(kCGHIDEventTap, event); 
    CFRelease(event); 
} 

Esta felizmente se mueve el ratón, pero no lo hace parece cambiar el comportamiento de CGGetLastMouseDelta en absoluto. ¿Alguien sabe las especificaciones exactas con respecto a lo que CGGetLastMouseDelta devuelve (y cuándo?). La documentación de Apple sobre este material (la referencia de Quartz) es casi inútil (o al menos, carece de los detalles necesarios).

Gracias!

Respuesta

2

Una buena idea podría ser utilizar CGAssociateMouseAndMouseCursorPosition(0) para desconectar el movimiento del mouse desde el cursor. Entonces no obtienes el problema con los límites de la pantalla.

0

Opción (1) Genere su propio evento que especifique que hizo que se moviera el mouse.
Opción (2) Llamar a la función del controlador de eventos movido del mouse desde Movió la rutina del mouse.