void SendString(CFStringRef str, unsigned delayMS) { //virtual keycodes copied from 10.6 SDK. Could not find them in 10.4 SDK enum { VK_RETURN = 0x24 /*KVK_Return*/, VK_TAB = 0x30 /*kVK_Tab*/, VK_SPACE = 0x31/*kVK_Space*/}; //A list of chars for which we must specify the virtual keycode static const CFStringRef specialChars = CFSTR("\n\t "); static const UniChar verticalTab = CFStringGetCharacterAtIndex(CFSTR("\v"), 0); //each keycode must correspond to the correct char in 'specialChars' CGKeyCode specialKeyCodes[] = {VK_RETURN, VK_TAB, VK_SPACE }; assert(CFStringGetLength(specialChars) == NumberOf(specialKeyCodes)); for (unsigned i = 0, len = CFStringGetLength(str); i < len; ++i) { //The next char to send UniChar c = CFStringGetCharacterAtIndex(str, i); //throw away 'vertical tab' chars which are only used on Windows to send a shift+tab //as a workaround for some issues with IE if (verticalTab == c) continue; //see if we need to specify the virtual keycode for this char CGKeyCode vKey = 0; //0 = kVK_ANSI_A, but I don't know of a more appropriate default value for (size_t j = 0; j < NumberOf(specialKeyCodes); ++j) { if ( CFStringGetCharacterAtIndex(specialChars, j) == c) { vKey = specialKeyCodes[j]; break; } } CGEventRef keyDown = CGEventCreateKeyboardEvent(NULL, vKey, true); CGEventRef keyUp = CGEventCreateKeyboardEvent(NULL, vKey, false); if (keyDown && keyUp) { //may be we should not do this if we found the virtual keycode? CGEventKeyboardSetUnicodeString(keyDown, 1, &c); CGEventKeyboardSetUnicodeString(keyUp, 1, &c); CGEventPost(kCGSessionEventTap, keyDown); CGEventPost(kCGSessionEventTap, keyUp); pws_os::sleep_ms(delayMS); CFRelease(keyDown); CFRelease(keyUp); } else { if (keyDown) CFRelease(keyDown); if (keyUp) CFRelease(keyUp); pws_os::IssueError(_T("Out of memory trying to allocate CGEventRef")); return; } } }
static inline void SendString(short theCode) { UniChar unicodeString[1]; unicodeString[0] = theCode; CGEventRef e = CGEventCreateKeyboardEvent(NULL, 0, true); CGEventKeyboardSetUnicodeString(e, 1, unicodeString); CGEventPost(kCGHIDEventTap, e); CFRelease(e); }
void MacOSKeyboardOStream::sendKey(char c) { #if __APPLE__ if (ofGetElapsedTimeMillis() < elapsed_time_ + kGracePeriod) { return; } elapsed_time_ = ofGetElapsedTimeMillis(); // Get the process number for the front application. ProcessSerialNumber psn = { 0, kNoProcess }; GetFrontProcess( &psn ); UniChar uni_char = c; CGEventRef key_down = CGEventCreateKeyboardEvent(NULL, 0, true); CGEventRef key_up = CGEventCreateKeyboardEvent(NULL, 0, false); CGEventKeyboardSetUnicodeString(key_down, 1, &uni_char); CGEventKeyboardSetUnicodeString(key_up, 1, &uni_char); CGEventPostToPSN(&psn, key_down); CGEventPostToPSN(&psn, key_up); CFRelease(key_down); CFRelease(key_up); #endif }
/* void char_down (in char key); */ NS_IMETHODIMP SendKeys::Char_down(PRUnichar key) { #if _DEBUG printf("charDown: %c (%d)\n", key, key); #endif UniChar letter = key; CGEventRef event; CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); event = CGEventCreateKeyboardEvent (eventSource, 1, true); CGEventKeyboardSetUnicodeString(event, 1, &letter); CGEventPost(kCGHIDEventTap, event); CFRelease(event); CFRelease(eventSource); return NS_OK; }
void KwmEmitKeystrokes(std::string Text) { CFStringRef TextRef = CFStringCreateWithCString(NULL, Text.c_str(), kCFStringEncodingMacRoman); CGEventRef EventKeyDown = CGEventCreateKeyboardEvent(NULL, 0, true); CGEventRef EventKeyUp = CGEventCreateKeyboardEvent(NULL, 0, false); UniChar OutputBuffer; for(std::size_t CharIndex = 0; CharIndex < Text.size(); ++CharIndex) { CFStringGetCharacters(TextRef, CFRangeMake(CharIndex, 1), &OutputBuffer); CGEventSetFlags(EventKeyDown, 0); CGEventKeyboardSetUnicodeString(EventKeyDown, 1, &OutputBuffer); CGEventPost(kCGHIDEventTap, EventKeyDown); CGEventSetFlags(EventKeyUp, 0); CGEventKeyboardSetUnicodeString(EventKeyUp, 1, &OutputBuffer); CGEventPost(kCGHIDEventTap, EventKeyUp); } CFRelease(EventKeyUp); CFRelease(EventKeyDown); CFRelease(TextRef); }
void MacOSKeyboardOStream::sendString(const std::string& str) { #if __APPLE__ // Get the process number for the front application. ProcessSerialNumber psn = { 0, kNoProcess }; GetFrontProcess( &psn ); UniChar s[str.length()]; for (uint32_t i = 0; i < str.length(); i++) { s[i] = str[i]; } CGEventRef e = CGEventCreateKeyboardEvent(NULL, 0, true); CGEventKeyboardSetUnicodeString(e, str.length(), s); CGEventPostToPSN(&psn, e); CFRelease(e); #endif }
void toggleUniKey(char c, const bool down) { /* This function relies on the convenient * CGEventKeyboardSetUnicodeString(), which allows us to not have to * convert characters to a keycode, but does not support adding modifier * flags. It is therefore only used in typeString() and typeStringDelayed() * -- if you need modifier keys, use the above functions instead. */ UniChar ch = (UniChar)c; /* Convert to unsigned char */ CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, 0, down); if (keyEvent == NULL) { fputs("Could not create keyboard event.\n", stderr); return; } CGEventKeyboardSetUnicodeString(keyEvent, 1, &ch); CGEventPost(kCGSessionEventTap, keyEvent); CFRelease(keyEvent); }