void COSXScreen::postMouseEvent(CGPoint& pos) const { // check if cursor position is valid on the client display configuration // [email protected] CGDisplayCount displayCount = 0; CGGetDisplaysWithPoint(pos, 0, NULL, &displayCount); if (displayCount == 0) { // cursor position invalid - clamp to bounds of last valid display. // find the last valid display using the last cursor position. displayCount = 0; CGDirectDisplayID displayID; CGGetDisplaysWithPoint(CGPointMake(m_xCursor, m_yCursor), 1, &displayID, &displayCount); if (displayCount != 0) { CGRect displayRect = CGDisplayBounds(displayID); if (pos.x < displayRect.origin.x) { pos.x = displayRect.origin.x; } else if (pos.x > displayRect.origin.x + displayRect.size.width - 1) { pos.x = displayRect.origin.x + displayRect.size.width - 1; } if (pos.y < displayRect.origin.y) { pos.y = displayRect.origin.y; } else if (pos.y > displayRect.origin.y + displayRect.size.height - 1) { pos.y = displayRect.origin.y + displayRect.size.height - 1; } } } // synthesize event. CGPostMouseEvent is a particularly good // example of a bad API. we have to shadow the mouse state to // use this API and if we want to support more buttons we have // to recompile. // // the order of buttons on the mac is: // 1 - Left // 2 - Right // 3 - Middle // Whatever the USB device defined. // // It is a bit weird that the behaviour of buttons over 3 are dependent // on currently plugged in USB devices. CGPostMouseEvent(pos, true, sizeof(m_buttons) / sizeof(m_buttons[0]), m_buttons[0], m_buttons[2], m_buttons[1], m_buttons[3], m_buttons[4]); }
void QuartzWindow::warp_pointer(int x, int y) { // lprintf("warping to: %d, %d\n", x, y); # if TARGET_OS_VERSION == MACOSX_VERSION CGPoint pt; pt.x = x; pt.y = y; const int n = 16; CGDisplayCount count = 0; CGDirectDisplayID dspys[n]; CGDisplayErr err = CGGetDisplaysWithPoint( pt, n, dspys, &count); if (err != noErr) { lprintf("CGGetDisplaysWithPoint failed: %d\n", err); return; } // lprintf("CGGetDisplaysWithPoint count = %d\n", count); for (int i = 0; i < count; ++i) { // MUST adj pt to be relative to TL of display -- dmu 5/03 CGRect bounds = CGDisplayBounds(dspys[i]); CGPoint adjusted_pt; adjusted_pt.x = pt.x - bounds.origin.x; adjusted_pt.y = pt.y - bounds.origin.y; err = CGDisplayMoveCursorToPoint( dspys[i], adjusted_pt); // lprintf("CGDisplayMoveCursorToPoint %d returned %d\n", i, err); } # else Unused(x); Unused(y); # endif }
int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) { CGPoint thePoint = {(float)p.x, (float)p.y}; CGDirectDisplayID theID; CGDisplayCount theCount; CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); wxASSERT(err == CGDisplayNoErr); int nWhich = wxNOT_FOUND; if (theCount) { theCount = GetCount(); CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; err = wxOSXGetDisplayList(theCount, theIDs, &theCount); wxASSERT(err == CGDisplayNoErr); for (nWhich = 0; nWhich < (int) theCount; ++nWhich) { if (theIDs[nWhich] == theID) break; } delete [] theIDs; if (nWhich == (int) theCount) { wxFAIL_MSG(wxT("Failed to find display in display list")); nWhich = wxNOT_FOUND; } } return nWhich; }
bool MouseMac::moveMouseTo(int x, int y) { UInt32 maxDisplays = 4; CGDirectDisplayID displayID[maxDisplays]; CGDisplayCount c = 0; CGDisplayCount *count = &c; CGGetDisplaysWithPoint( CGPointMake(x, y), maxDisplays, displayID, count); if (*count > 0) { CGEventRef mouseEv = CGEventCreateMouseEvent( NULL, kCGEventMouseMoved, CGPointMake(x, y), kCGMouseButtonLeft); CGEventPost(kCGHIDEventTap, mouseEv); CFRelease(mouseEv); return true; } else { return false; } }
void COSXScreen::postMouseEvent(CGPoint& pos) const { // check if cursor position is valid on the client display configuration // [email protected] CGDisplayCount displayCount = 0; CGGetDisplaysWithPoint(pos, 0, NULL, &displayCount); if (displayCount == 0) { // cursor position invalid - clamp to bounds of last valid display. // find the last valid display using the last cursor position. displayCount = 0; CGDirectDisplayID displayID; CGGetDisplaysWithPoint(CGPointMake(m_xCursor, m_yCursor), 1, &displayID, &displayCount); if (displayCount != 0) { CGRect displayRect = CGDisplayBounds(displayID); if (pos.x < displayRect.origin.x) { pos.x = displayRect.origin.x; } else if (pos.x > displayRect.origin.x + displayRect.size.width - 1) { pos.x = displayRect.origin.x + displayRect.size.width - 1; } if (pos.y < displayRect.origin.y) { pos.y = displayRect.origin.y; } else if (pos.y > displayRect.origin.y + displayRect.size.height - 1) { pos.y = displayRect.origin.y + displayRect.size.height - 1; } } } CGEventType type = kCGEventMouseMoved; SInt8 button = m_buttonState.getFirstButtonDown(); if (button != -1) { MouseButtonEventMapType thisButtonType = MouseButtonEventMap[button]; type = thisButtonType[kMouseButtonDragged]; } CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, button); CGEventPost(kCGHIDEventTap, event); CFRelease(event); }
uint32 CGGetDisplayCount_wrap(float x, float y, float w, float h, void* FH) { CGDisplayCount count; CGDisplayErr e = w == 0.0 && h == 0.0 ? CGGetDisplaysWithPoint( CGPointMake(x, y), 0, NULL, &count) : CGGetDisplaysWithRect( CGRectMake(x, y, w, h), 0, NULL, &count); return e != CGDisplayNoErr ? (uint32)reportOSError(e, "CGGetDisplayCount", FH) : count; }
static CGDirectDisplayID displayAtPoint(QPoint point) { CGDirectDisplayID display; uint32_t matchingDisplayCount; CGGetDisplaysWithPoint(CGPointMake(point.x(), point.y()), 1, &display, &matchingDisplayCount); if (matchingDisplayCount == 0) { display = kCGNullDirectDisplay; qWarning("No display found at %ix%i", point.x(), point.y()); } return display; }
CGDirectDisplayID CGGetDisplayAt_wrap(uint32 n, float x, float y, float w, float h, void* FH) { uint32 count; ResourceMark rm; CGDirectDisplayID *displays = NEW_RESOURCE_ARRAY(CGDirectDisplayID, n + 1); CGDisplayErr e = w == 0.0 && h == 0.0 ? CGGetDisplaysWithPoint( CGPointMake(x, y), n + 1, displays, &count) : CGGetDisplaysWithRect( CGRectMake(x, y, w, h), n + 1, displays, &count); return e != CGDisplayNoErr ? (CGDirectDisplayID)reportOSError(e, "CGGetDisplayAt", FH) : count < n + 1 ? (CGDirectDisplayID)(failure(FH, "not enough displays"), NULL) : displays[n]; }
int DisplayManagerOSX::getDisplayFromPoint(int x, int y) { CGPoint point = { (double)x, (double)y }; CGDirectDisplayID foundDisplay; uint32_t numFound; CGGetDisplaysWithPoint(point, 1, &foundDisplay, &numFound); for (int i=0; i<m_osxnumDisplays; i++) { if (foundDisplay == m_osxDisplays[i]) return i; } return -1; }
int main( int argc, char ** argv) { CGSize mainScreenSize = CGDisplayScreenSize (CGMainDisplayID ()); CGDirectDisplayID currentDisplayID = CGMainDisplayID (); CGSize currentDisplaySize = mainScreenSize; CGRect displayRect; CGPoint newloc; Point pt; CGEventRef eventRef; InputEvent event; pInputEvent pEvent = &event; SOCKET s, s_accept; struct sockaddr_in s_add; //from anyone! struct sockaddr s_client; socklen_t s_client_size = sizeof( struct sockaddr ); int port = PORT; int recvsize; char reuse = 1;//SO_REUSEADDR int xDelta=0, yDelta=0; //network stuff //configure socket if ( ( s = socket( PF_INET, SOCK_STREAM, 0 ) ) == -1 ) { perror ( "Failed to create socket :(" ); exit( 2 ); } if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof( reuse ) ) == -1 ) { perror( "Failed to set reuseaddr! Trying to continue..." ); } memset( &s_add, 0, sizeof( struct sockaddr_in ) ); s_add.sin_family = AF_INET; s_add.sin_port = htons( port ); s_add.sin_addr.s_addr = INADDR_ANY; if ( bind( s, (struct sockaddr * )&s_add, sizeof( struct sockaddr_in ) ) == -1 ) { perror( "Failed to bind socket" ); exit( 2 ); } if( listen( s , 1 ) ) { perror( "Can't listen!" ); exit( 2 ); } while( 1 ) { s_accept = accept( s, &s_client, &s_client_size ); if ( s_accept == -1 ) { perror( "failed to accept!" ); return -1; } while( 1 ) { recvsize = recv( s_accept, pEvent, sizeof( InputEvent ), MSG_WAITALL ); if ( recvsize == sizeof( InputEvent ) )//got data { switch( pEvent->event_t ) { case EVENT_TYPE_MOUSE_MOVE: if(debug) printf("Mouse move\n"); GetGlobalMouse( &pt );//get cursor pos //update x/y newloc.x = pt.h + pEvent->move_info.dx * 2; newloc.y = pt.v + pEvent->move_info.dy * 2; CGDisplayCount displayCount = 0; //check if we've crossed outside the x bounds CGDirectDisplayID tempDisplayID; CGGetDisplaysWithPoint ( newloc, 1, &tempDisplayID, &displayCount); if (displayCount != 0) { currentDisplayID = tempDisplayID; } displayRect = CGDisplayBounds(currentDisplayID); if (newloc.x < displayRect.origin.x) { newloc.x = displayRect.origin.x; } else if (newloc.x > displayRect.origin.x + displayRect.size.width - 1) { newloc.x = displayRect.origin.x + displayRect.size.width - 1; } if (newloc.y < displayRect.origin.y) { newloc.y = displayRect.origin.y; } else if (newloc.y > displayRect.origin.y + displayRect.size.height - 1) { newloc.y = displayRect.origin.y + displayRect.size.height - 1; } if(debug) { printf("Current mouse location: {%d,%d}\n", pt.h, pt.v); printf("newloc: {%f,%f}\n", newloc.x, newloc.y); printf("Screen size: {%f,%f}\n", currentDisplaySize.width, currentDisplaySize.height); fflush( stdout ); } //CGPostMouseEvent( newloc, true /*yes move there*/, 0 , false); eventRef = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, newloc, kCGMouseButtonCenter); CGEventSetType(eventRef, kCGEventMouseMoved); // Apple bug... need to set the type manually CGEventPost(kCGSessionEventTap, eventRef); CFRelease(eventRef); break; case EVENT_TYPE_MOUSE_SCROLL_MOVE: if(debug) { printf( "Scrolling\n" ); fflush( stdout ); } xDelta += pEvent->move_info.dx; yDelta += pEvent->move_info.dy; //TODO: mac osx has a api to get the exact scroll amount, look into that if ( ( yDelta/SCROLL_AMT != 0 ) || ( xDelta/SCROLL_AMT != 0 ) ) {//if any clicks need to be made... //send the number of whole clicks.... CGPostScrollWheelEvent( 2, -yDelta/SCROLL_AMT, -xDelta/SCROLL_AMT ); //remove them from our counter xDelta %=SCROLL_AMT; yDelta %=SCROLL_AMT; } break; case EVENT_TYPE_MOUSE_DOWN: if(debug) printf("Mouse down\n"); GetGlobalMouse( &pt );//get cursor pos //update x/y if(debug) { printf("Current mouse location: {%d,%d}", pt.h, pt.v); fflush( stdout ); } //CGPostMouseEvent( newloc, true /*yes move there*/, 0 , false); newloc.x = pt.h; newloc.y = pt.v; eventRef = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown , newloc, kCGMouseButtonCenter); CGEventSetType(eventRef, kCGEventLeftMouseDown); // Apple bug... need to set the type manually CGEventPost(kCGSessionEventTap, eventRef); CFRelease(eventRef); break; case EVENT_TYPE_MOUSE_UP: if(debug) printf("Mouse up\n"); GetGlobalMouse( &pt );//get cursor pos //update x/y if(debug) { printf("Current mouse location: {%d,%d}", pt.h, pt.v); fflush( stdout ); } //CGPostMouseEvent( newloc, true /*yes move there*/, 0 , false); newloc.x = pt.h; newloc.y = pt.v; eventRef = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp , newloc, kCGMouseButtonCenter); CGEventSetType(eventRef, kCGEventLeftMouseUp); // Apple bug... need to set the type manually CGEventPost(kCGSessionEventTap, eventRef); CFRelease(eventRef); break; /* TODO: * so far this will only work for basic keycodes, and will probably fail on anything non-ascii, * and that has yet to be tested, etc. Right now I'm mostly interested in having the events properly * generated and support ascii keys. We will handle the rest later. */ case EVENT_TYPE_KEY_DOWN: if ( debug ) { printf( "Key down: %c\n", pEvent->key_info.keycode ); fflush( stdout ); } eventRef = CGEventCreateKeyboardEvent( NULL, (CGKeyCode)( pEvent->key_info.keycode - 1 ), true ); CGEventSetType( eventRef, kCGEventKeyDown ); CGEventPost( kCGSessionEventTap, eventRef ); CFRelease( eventRef ); break; case EVENT_TYPE_KEY_UP: if ( debug ) { printf( "Key Up: %c\n", pEvent->key_info.keycode ); fflush( stdout ); } eventRef = CGEventCreateKeyboardEvent( NULL, (CGKeyCode)( pEvent->key_info.keycode - 1 ), false ); CGEventSetType( eventRef, kCGEventKeyUp ); CGEventPost( kCGSessionEventTap, eventRef ); CFRelease( eventRef ); break; default: fprintf( stderr, "unknown message type: %d\n", pEvent->event_t ); fflush( stdout ); break; } //flush events, if needed in macosx } else if ( recvsize > 0 ) { fprintf( stderr, "partial recv!" ); } else if ( recvsize == 0 ) { //connection terminated close( s_accept ); break; //exit this while loop, wait for another connection } else { perror( "error in recv" ); } } } //shouldn't get here! return 0; }