web-dev-qa-db-fra.com

Simuler la saisie de la souris par programmation sous OS X

Est-il possible de simuler les actions d'une souris à partir d'un programme sous OS X? Plus précisément, la version courte est que j'essaie de simuler un écran tactile en utilisant deux webcams. Donc, en supposant que je puisse obtenir les positions X, Y, puis-je envoyer des informations au système d'exploitation sous la forme d'un mouvement de souris ou d'un clic?

Edit- Ou si c'est particulièrement facile dans un autre système d'exploitation, je serais prêt à considérer cela.

63
Rob Lourens

Oui c'est possible. Vous pouvez utiliser Quartz Event Services pour simuler des événements d'entrée.

En supposant C, j'ai écrit cet exemple rapide:

#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>

int main() {
    // Move to 200x200
    CGEventRef move1 = CGEventCreateMouseEvent(
        NULL, kCGEventMouseMoved,
        CGPointMake(200, 200),
        kCGMouseButtonLeft // ignored
    );
    // Move to 250x250
    CGEventRef move2 = CGEventCreateMouseEvent(
        NULL, kCGEventMouseMoved,
        CGPointMake(250, 250),
        kCGMouseButtonLeft // ignored
    );
    // Left button down at 250x250
    CGEventRef click1_down = CGEventCreateMouseEvent(
        NULL, kCGEventLeftMouseDown,
        CGPointMake(250, 250),
        kCGMouseButtonLeft
    );
    // Left button up at 250x250
    CGEventRef click1_up = CGEventCreateMouseEvent(
        NULL, kCGEventLeftMouseUp,
        CGPointMake(250, 250),
        kCGMouseButtonLeft
    );

    // Now, execute these events with an interval to make them noticeable
    CGEventPost(kCGHIDEventTap, move1);
    sleep(1);
    CGEventPost(kCGHIDEventTap, move2);
    sleep(1);
    CGEventPost(kCGHIDEventTap, click1_down);
    CGEventPost(kCGHIDEventTap, click1_up);

    // Release the events
    CFRelease(click1_up);
    CFRelease(click1_down);
    CFRelease(move2);
    CFRelease(move1);

    return 0;
}

Et en supposant GCC, compilez avec:

gcc -o program program.c -Wall -framework ApplicationServices

Profitez de la magie.

88
jweyrich

Swift exemple de déplacement et de clic de souris:

func mouseMoveAndClick(onPoint point: CGPoint) { 
    guard let moveEvent = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: point, mouseButton: .left) else {
        return
    }
    guard let downEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left) else {
        return
    }
    guard let upEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left) else {
        return
    }
    moveEvent.post(tap: CGEventTapLocation.cghidEventTap)
    downEvent.post(tap: CGEventTapLocation.cghidEventTap)
    upEvent.post(tap: CGEventTapLocation.cghidEventTap)
}
10
Alexey Pichukov

Si vous ne voulez pas compiler des choses et cherchez un outil basé sur Shell, Cliclick peut être la solution.

7
ghoti

Voici un programme C fonctionnel basé sur la réponse de jweyrick:

// Compile instructions:
//
// gcc -o click click.c -Wall -framework ApplicationServices

#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int x = 0, y = 0, n = 1;
  float duration = 0.1;

  if (argc < 3) {
    printf("USAGE: click X Y [N] [DURATION]\n");
    exit(1);
  }

  x = atoi(argv[1]);
  y = atoi(argv[2]);

  if (argc >= 4) {
    n = atoi(argv[3]);
  }

  if (argc >= 5) {
    duration = atof(argv[4]);
  }

  CGEventRef click_down = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseDown,
    CGPointMake(x, y),
    kCGMouseButtonLeft
  );

  CGEventRef click_up = CGEventCreateMouseEvent(
    NULL, kCGEventLeftMouseUp,
    CGPointMake(x, y),
    kCGMouseButtonLeft
  );

  // Now, execute these events with an interval to make them noticeable
  for (int i = 0; i < n; i++) {
    CGEventPost(kCGHIDEventTap, click_down);
    sleep(duration);
    CGEventPost(kCGHIDEventTap, click_up);
    sleep(duration);
  }

  // Release the events
  CFRelease(click_down);
  CFRelease(click_up);

  return 0;
}

Hébergé chez https://Gist.github.com/Dorian/5ae010cd70f02adf2107

2
Dorian