/* Click (C) 2006 PA5CAL for MacGeneration
*
* Purpose: Simulate mouse events
* Syntax:
* click <x> <y> [l|2|r]
* Options:
* l = left button click (default)
* 2 = left button double click
* r = right button click
*/
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/hidsystem/IOHIDShared.h>
#include <IOKit/IOKitLib.h>
class HIDService
{
private:
io_connect_t event_driver;
mach_port_t io_master_port;
public:
HIDService();
~HIDService();
kern_return_t Open();
kern_return_t Close();
void SendMouseEvent(int right, int down, SInt32 x, SInt32 y);
void Click(int right, SInt32 x, SInt32 y);
void DoubleClick(int right, SInt32 x, SInt32 y);
};
#pragma mark -
#pragma mark HIDService
HIDService::HIDService()
{
event_driver = MACH_PORT_NULL;
Open();
}
HIDService::~HIDService()
{
Close();
}
kern_return_t HIDService::Close()
{
kern_return_t r = KERN_SUCCESS;
if (event_driver!=MACH_PORT_NULL)
r = IOServiceClose(event_driver);
event_driver = MACH_PORT_NULL;
return r;
}
kern_return_t HIDService::Open()
{
kern_return_t kr;
mach_port_t ev, service;
if (KERN_SUCCESS==(kr = Close())) {
if (KERN_SUCCESS!=(kr = IOMasterPort(MACH_PORT_NULL, &io_master_port)))
return kr;
if (io_master_port!=MACH_PORT_NULL) {
if (service = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching(kIOHIDSystemClass))) {
kr = IOServiceOpen(service, mach_task_self(),
kIOHIDParamConnectType, &ev);
IOObjectRelease(service);
if (KERN_SUCCESS==kr)
event_driver = ev;
}
}
}
return kr;
}
void HIDService::SendMouseEvent(int right, int down, SInt32 x, SInt32 y)
{
if (event_driver==MACH_PORT_NULL)
return;
int eventType;
if (right){
if (down)
eventType = NX_RMOUSEDOWN;
else
eventType = NX_RMOUSEUP;
} else {
if (down)
eventType = NX_LMOUSEDOWN;
else
eventType = NX_LMOUSEUP;
}
IOGPoint scrPos;
scrPos.x = x;
scrPos.y = y;
NXEventData eventData;
eventData.mouse.subType = NX_SUBTYPE_TABLET_POINT;
eventData.mouse.subx = 0;
eventData.mouse.suby = 0;
eventData.mouse.click = 0;
eventData.mouse.pressure = (down ? 255 : 0);
eventData.mouse.tablet.point.x = x;
eventData.mouse.tablet.point.y = y;
eventData.mouse.tablet.point.buttons = 0x0000;
eventData.mouse.tablet.point.tilt.x = 0;
eventData.mouse.tablet.point.tilt.y = 0;
eventData.mouse.tablet.point.deviceID = 0x81;
(void)IOHIDPostEvent(event_driver, eventType, scrPos, &eventData,
kNXEventDataVersion, 0, kIOHIDSetCursorPosition);
struct timespec rqtp = {0, 50000000};
nanosleep(&rqtp, NULL);
}
void HIDService::Click(int right, SInt32 x, SInt32 y)
{
SendMouseEvent(right, 1, x, y);
SendMouseEvent(right, 0, x, y);
}
void HIDService::DoubleClick(int right, SInt32 x, SInt32 y)
{
Click(right, x, y);
Click(right, x, y);
}
#pragma mark -
void usage()
{
printf("Click (C) 2006 PA5CAL for MacGeneration\n\n"
"Purpose:\n"
"\tSimulate mouse events\n"
"Syntax:\n"
"\tclick <x> <y> [l|2|r]\n"
"Options:\n"
"\tl = left button click (default)\n"
"\t2 = left button double click\n"
"\tr = right button click\n\n");
}
int main (int argc, char * const argv[])
{
if (argc<3) {
usage();
return 0;
}
SInt32 x, y;
x = atol(argv[1]);
y = atol(argv[2]);
int right = 0;
int dbl = 0;
if (argc>=4) {
if (argv[3][0]=='r')
right = 1;
else
if (argv[3][0]=='2')
dbl = 1;
}
HIDService *hs;
try {
hs = new HIDService();
}
catch (const char *err) {
printf("- failed -\n\n");
delete hs;
return 0;
}
if (dbl)
hs->DoubleClick(right, x, y);
else
hs->Click(right, x, y);
delete hs;
return 0;
}