Esempio n. 1
0
SInt32
OSXKeyState::pollActiveGroup() const
{
	bool layoutValid = true;
	TISInputSourceRef keyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
	
	if (layoutValid) {
		GroupMap::const_iterator i = m_groupMap.find(keyboardLayout);
		if (i != m_groupMap.end()) {
			return i->second;
		}
	}
	return 0;
}
Esempio n. 2
0
void COSXKeyboardLayouts::GetLayouts()
{
  CFDictionaryRef props;
  CFStringRef keys[] = {kTISPropertyInputSourceType};
  CFStringRef vals[] = {kTISTypeKeyboardLayout};
  CFRange range = {0,0};
  
  props = CFDictionaryCreate(NULL, (const void **) keys, (const void**) vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  layouts = TISCreateInputSourceList(props, false);
  if(layouts != NULL && (range.length = CFArrayGetCount(layouts)) > 1) 
  {
    TISInputSourceRef temp;
    c_layout = CFArrayGetFirstIndexOfValue(layouts, range, (temp = TISCopyCurrentKeyboardLayoutInputSource()));
    CFRelease(temp);
  }
  
  CFRelease(props);
}
Esempio n. 3
0
SInt32
OSXKeyState::pollActiveGroup() const
{
	bool layoutValid = true;
#if defined(MAC_OS_X_VERSION_10_5)
	TISInputSourceRef keyboardLayout = TISCopyCurrentKeyboardLayoutInputSource();
#else
	KeyboardLayoutRef keyboardLayout;
	OSStatus status = KLGetCurrentKeyboardLayout(&keyboardLayout);
	layoutValid = (status == noErr);
#endif
	
	if (layoutValid) {
		GroupMap::const_iterator i = m_groupMap.find(keyboardLayout);
		if (i != m_groupMap.end()) {
			return i->second;
		}
	}
	return 0;
}
Esempio n. 4
0
    			} else if (((keyToCharData[k] & kUCKeyOutputTestForIndexMask) != kUCKeyOutputSequenceIndexMask)
						   && keyToCharData[k] != 0xFFFE
						   && keyToCharData[k] != 0xFFFF
						   && keyToCharData[k] == c) {
    				return (CGKeyCode)k;
    			}
    		}
    	}
    }
	errx(1, "Keycode for \\U%X not found", c);
}

int main (int __unused argc, const char * __unused argv[]) {
	signal(SIGCHLD, SIG_IGN);

	TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource();
	CFDataRef uchr = TISGetInputSourceProperty(tis, kTISPropertyUnicodeKeyLayoutData);
    const UCKeyboardLayout *keyboardLayoutData = (const UCKeyboardLayout *)CFDataGetBytePtr(uchr);

	char **cmds = NULL;
	unsigned cmd_top = 0;

	char *shell = getenv("SHELL");
	char *home = getenv("HOME");
	bool no_shell = shell == NULL || *shell == '\0';
	bool no_home = home == NULL || home == '\0';
	if (no_shell || no_home) {
		struct passwd *pw = getpwuid(getuid());
		if (pw == NULL)
			err(1, "getpwuid");
		if (no_shell)
Esempio n. 5
0
// This method must be executed from the main runloop to avoid the seemingly random
// Exception detected while handling key input.  TSMProcessRawKeyCode failed (-192) errors.
// CFEqual(CFRunLoopGetCurrent(), CFRunLoopGetMain())
void keycode_to_string(CGEventRef event_ref, UniCharCount size, UniCharCount *length, UniChar *buffer) {
	#if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION)
	#if defined(USE_CARBON_LEGACY)
	KeyboardLayoutRef curr_keyboard_layout;
	void *inputData = NULL;
	if (KLGetCurrentKeyboardLayout(&curr_keyboard_layout) == noErr) {
		if (KLGetKeyboardLayoutProperty(curr_keyboard_layout, kKLuchrData, (const void **) &inputData) != noErr) {
			inputData = NULL;
		}
	}
	#elif defined(USE_COREFOUNDATION)
	TISInputSourceRef curr_keyboard_layout = TISCopyCurrentKeyboardLayoutInputSource();
	CFDataRef inputData = NULL;
	if (curr_keyboard_layout != NULL && CFGetTypeID(curr_keyboard_layout) == TISInputSourceGetTypeID()) {
		CFDataRef data = (CFDataRef) TISGetInputSourceProperty(curr_keyboard_layout, kTISPropertyUnicodeKeyLayoutData);
		if (data != NULL && CFGetTypeID(data) == CFDataGetTypeID() && CFDataGetLength(data) > 0) {
			inputData = (CFDataRef) data;
		}
	}

	// Check if the keyboard layout has changed to see if the dead key state needs to be discarded.
	if (prev_keyboard_layout != NULL && curr_keyboard_layout != NULL && CFEqual(curr_keyboard_layout, prev_keyboard_layout) == false) {
		curr_deadkey_state = 0;
	}

	// Release the previous keyboard layout.
	if (prev_keyboard_layout != NULL) {
		CFRelease(prev_keyboard_layout);
	}

	// Set the previous keyboard layout to the current layout.
	if (curr_keyboard_layout != NULL) {
		prev_keyboard_layout = curr_keyboard_layout;
	}
	#endif

	if (inputData != NULL) {
		#ifdef USE_CARBON_LEGACY
		const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout *) inputData;
		#else
		const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout*) CFDataGetBytePtr(inputData);
		#endif

		if (keyboard_layout != NULL) {
			//Extract keycode and modifier information.
			CGKeyCode keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
			CGEventFlags modifiers = CGEventGetFlags(event);

			// Disable all command modifiers for translation.  This is required
			// so UCKeyTranslate will provide a keysym for the separate event.
			static const CGEventFlags cmd_modifiers = kCGEventFlagMaskCommand |
					kCGEventFlagMaskControl | kCGEventFlagMaskAlternate;
			modifiers &= ~cmd_modifiers;

			// I don't know why but UCKeyTranslate does not process the
			// kCGEventFlagMaskAlphaShift (A.K.A. Caps Lock Mask) correctly.
			// We need to basically turn off the mask and process the capital
			// letters after UCKeyTranslate().  Think Different, not because it
			// makes sense but because you want to be a hipster.
			bool is_caps_lock = modifiers & kCGEventFlagMaskAlphaShift;
			modifiers &= ~kCGEventFlagMaskAlphaShift;


			OSStatus status = noErr;
			if (curr_deadkey_state == 0) {
				// No previous deadkey, attempt a lookup.
				status = UCKeyTranslate(
									keyboard_layout,
									keycode,
									kUCKeyActionDown,
									(modifiers >> 16) & 0xFF, //(modifiers >> 16) & 0xFF, || (modifiers >> 8) & 0xFF,
									LMGetKbdType(),
									kNilOptions, //kNilOptions, //kUCKeyTranslateNoDeadKeysMask
									&curr_deadkey_state,
									size,
									length,
									buffer);
			}
			else {
Esempio n. 6
0
KeyButton 
OSXKeyState::mapKeyFromEvent(KeyIDs& ids,
				KeyModifierMask* maskOut, CGEventRef event) const
{
	ids.clear();

	// map modifier key
	if (maskOut != NULL) {
		KeyModifierMask activeMask = getActiveModifiers();
		activeMask &= ~KeyModifierAltGr;
		*maskOut    = activeMask;
	}

	// get virtual key
	UInt32 vkCode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);

	// handle up events
	UInt32 eventKind = CGEventGetType(event);
	if (eventKind == kCGEventKeyUp) {
		// the id isn't used.  we just need the same button we used on
		// the key press.  note that we don't use or reset the dead key
		// state;  up events should not affect the dead key state.
		ids.push_back(kKeyNone);
		return mapVirtualKeyToKeyButton(vkCode);
	}

	// check for special keys
	VirtualKeyMap::const_iterator i = m_virtualKeyMap.find(vkCode);
	if (i != m_virtualKeyMap.end()) {
		m_deadKeyState = 0;
		ids.push_back(i->second);
		return mapVirtualKeyToKeyButton(vkCode);
	}

	// get keyboard info

#if defined(MAC_OS_X_VERSION_10_5)
	TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); 
#else
	KeyboardLayoutRef currentKeyboardLayout;
	OSStatus status = KLGetCurrentKeyboardLayout(&currentKeyboardLayout);
#endif
	if (currentKeyboardLayout == NULL) {
		return kKeyNone;
	}

	// get the event modifiers and remove the command and control
	// keys.  note if we used them though.
	// UCKeyTranslate expects old-style Carbon modifiers, so convert.
	UInt32 modifiers;
	modifiers = mapModifiersToCarbon(CGEventGetFlags(event));
	static const UInt32 s_commandModifiers =
		cmdKey | controlKey | rightControlKey;
	bool isCommand = ((modifiers & s_commandModifiers) != 0);
	modifiers &= ~s_commandModifiers;

	// if we've used a command key then we want the glyph produced without
	// the option key (i.e. the base glyph).
	//if (isCommand) {
		modifiers &= ~optionKey;
	//}

	// choose action
	UInt16 action;
	if(eventKind==kCGEventKeyDown) {
		action = kUCKeyActionDown;
	}
	else if(CGEventGetIntegerValueField(event, kCGKeyboardEventAutorepeat)==1) {
		action = kUCKeyActionAutoKey;
	}
	else {
		return 0;
	}

	// translate via uchr resource
#if defined(MAC_OS_X_VERSION_10_5)
	CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
								kTISPropertyUnicodeKeyLayoutData);
	const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
	const bool layoutValid = (layout != NULL);
#else
	const void* resource;
	int err = KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLuchrData, &resource);
	const bool layoutValid = (err == noErr);
	const UCKeyboardLayout* layout = (const UCKeyboardLayout*)resource;
#endif

	if (layoutValid) {
		// translate key
		UniCharCount count;
		UniChar chars[2];
		LOG((CLOG_DEBUG2 "modifiers: %08x", modifiers & 0xffu));
		OSStatus status = UCKeyTranslate(layout,
							vkCode & 0xffu, action,
							(modifiers >> 8) & 0xffu,
							LMGetKbdType(), 0, &m_deadKeyState,
							sizeof(chars) / sizeof(chars[0]), &count, chars);

		// get the characters
		if (status == 0) {
			if (count != 0 || m_deadKeyState == 0) {
				m_deadKeyState = 0;
				for (UniCharCount i = 0; i < count; ++i) {
					ids.push_back(KeyResource::unicharToKeyID(chars[i]));
				}
				adjustAltGrModifier(ids, maskOut, isCommand);
				return mapVirtualKeyToKeyButton(vkCode);
			}
			return 0;
		}
	}

	return 0;
}
Esempio n. 7
0
OP_STATUS UKeyTranslate::GetUnicharFromVirtualKey(UInt32 virtualKeyCode, uni_char &outUniChar, UInt8 modifierKeyState)
{
#ifdef SIXTY_FOUR_BIT
	UInt32 deadKeyState = 0;
	OP_STATUS result = OpStatus::ERR;
	TISInputSourceRef kbInputSourceRef = TISCopyCurrentKeyboardLayoutInputSource();
	CFDataRef uchrDataRef = (CFDataRef)TISGetInputSourceProperty(kbInputSourceRef, kTISPropertyUnicodeKeyLayoutData);
	Boolean existsUchr = ((uchrDataRef != NULL) && (CFDataGetBytePtr(uchrDataRef) != NULL) && (CFDataGetLength(uchrDataRef) != 0));
	if (existsUchr)
	{
		UniCharCount actualLength = 0;
		UniChar outChar[2] = {0,0};

		OSStatus status = UCKeyTranslate((const UCKeyboardLayout *)CFDataGetBytePtr(uchrDataRef),
										 virtualKeyCode, kUCKeyActionDown,
										 modifierKeyState, LMGetKbdType(), kNilOptions,
										 &deadKeyState, 2, &actualLength, outChar);
		if (status == noErr && actualLength && outChar[0] != kFunctionKeyCharCode)
		{
			outUniChar = outChar[0];
			result = OpStatus::OK;
		}
	}
	CFRelease(kbInputSourceRef);

	return result;
#else	// !SIXTY_FOUR_BIT
	static KeyboardLayoutRef lastKbdLayout = 0;
	static const UCKeyboardLayout* ucharData = NULL;
	static const void* charData = NULL;
	KeyboardLayoutRef currentKbdLayout = 0;

	if (noErr != KLGetCurrentKeyboardLayout(&currentKbdLayout) || !currentKbdLayout)
	{
		return OpStatus::ERR;
	}

	short	keyCode;
	OSStatus error = noErr;
	UInt32 deadKeyState = 0;
	OP_STATUS result = OpStatus::ERR;

	keyCode = virtualKeyCode;

	if (!ucharData || (currentKbdLayout != lastKbdLayout))
	{
		// Don't fetch this unless we have to: Because of the KeyScript issue handled below this may in some cases return 0
		// KeyScript is an EXPENSIVE call, so by caching ucharData as long as possible we minimise the number of times
		// we need to call it.
		error = KLGetKeyboardLayoutProperty(currentKbdLayout, kKLuchrData, (const void**)&ucharData);
	}
	if (!ucharData)
	{
		static Boolean try_again = true;
		if (try_again && (smRoman == GetScriptManagerVariable(smKeyScript)))
		{
			// This is required for roman scripts in order to get something from KLGetCurrentKeyboardLayout
			KeyScript(smRoman | smKeyForceKeyScriptMask);
			error = KLGetKeyboardLayoutProperty(currentKbdLayout, kKLuchrData, (const void**)&ucharData);
			if (error || !ucharData)
				try_again = false;
		}
	}

	if ((error == noErr) && (ucharData != 0))
	{
		UniCharCount actualLength = 0;
		UniChar outChar[2] = {0,0};
		charData = NULL;
		error = UCKeyTranslate(ucharData, (unsigned short)keyCode,
									kUCKeyActionDown, modifierKeyState, LMGetKbdType(), 0,
									&deadKeyState, 2, &actualLength, outChar);
		if (error == noErr && actualLength && outChar[0] != kFunctionKeyCharCode)
		{
			outUniChar = outChar[0];
			result = OpStatus::OK;
#ifdef DEBUG_UNI_KEYSTROKES
//			if (outUniChar & 0xff00)
//				fprintf(stderr, "UKC:%x\n", outChar[0]);
#endif
		}
#ifdef DEBUG_UNI_KEYSTROKES
		else
		{
			fprintf(stderr, "UKCe:%li-%x-%lu-%x\n", error, outChar[0], virtualKeyCode, modifierKeyState);
		}
		if (actualLength != 1)
			fprintf(stderr, "UKCl:%lu-%x-%x-%lu-%x\n", actualLength, outChar[0], outChar[1], virtualKeyCode, modifierKeyState);
#endif
	}
	else
	{
#ifdef DEBUG_UNI_KEYSTROKES
		fprintf(stderr, "KLP:%li\n", error);
#endif
		error = noErr;
		if (!charData || (currentKbdLayout != lastKbdLayout))
		{
			error = KLGetKeyboardLayoutProperty(currentKbdLayout, kKLKCHRData, &charData);
		}
		if ((error == noErr) && (charData != 0))
		{
			unsigned long charcs = KeyTranslate(charData, (keyCode & 0xFF) | (modifierKeyState << 8), &deadKeyState);
			if (charcs & 0xFF)
			{
				char src = charcs & 0x00FF;
				gTextConverter->ConvertBufferFromMac(&src, 1, &outUniChar, 1);
				result = OpStatus::OK;
			}
#ifdef DEBUG_UNI_KEYSTROKES
			else
			{
				fprintf(stderr, "KTe\n", outUniChar);
			}
			if (charcs & 0xFF0000)
			{
				fprintf(stderr, "KTe:%x-%lu-%x\n", charcs, virtualKeyCode, modifierKeyState);
			}
#endif
		}
		else
		{
#ifdef DEBUG_UNI_KEYSTROKES
			fprintf(stderr, "KLPe:%li\n", error);
#endif
		}
	}
	lastKbdLayout = currentKbdLayout;
	return result;
#endif	// SIXTY_FOUR_BIT
}
Esempio n. 8
0
KeyButton 
COSXKeyState::mapKeyFromEvent(CKeyIDs& ids,
				KeyModifierMask* maskOut, EventRef event) const
{
	ids.clear();

	// map modifier key
	if (maskOut != NULL) {
		KeyModifierMask activeMask = getActiveModifiers();
		activeMask &= ~KeyModifierAltGr;
		*maskOut    = activeMask;
	}

	// get virtual key
	UInt32 vkCode;
	GetEventParameter(event, kEventParamKeyCode, typeUInt32,
							NULL, sizeof(vkCode), NULL, &vkCode);

	// handle up events
	UInt32 eventKind = GetEventKind(event);
	if (eventKind == kEventRawKeyUp) {
		// the id isn't used.  we just need the same button we used on
		// the key press.  note that we don't use or reset the dead key
		// state;  up events should not affect the dead key state.
		ids.push_back(kKeyNone);
		return mapVirtualKeyToKeyButton(vkCode);
	}

	// check for special keys
	CVirtualKeyMap::const_iterator i = m_virtualKeyMap.find(vkCode);
	if (i != m_virtualKeyMap.end()) {
		m_deadKeyState = 0;
		ids.push_back(i->second);
		return mapVirtualKeyToKeyButton(vkCode);
	}

	// get keyboard info

	TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); 
	if (currentKeyboardLayout == NULL) {
		return kKeyNone;
	}

	// get the event modifiers and remove the command and control
	// keys.  note if we used them though.
	UInt32 modifiers;
	GetEventParameter(event, kEventParamKeyModifiers, typeUInt32,
								NULL, sizeof(modifiers), NULL, &modifiers);
	static const UInt32 s_commandModifiers =
		cmdKey | controlKey | rightControlKey;
	bool isCommand = ((modifiers & s_commandModifiers) != 0);
	modifiers &= ~s_commandModifiers;

	// if we've used a command key then we want the glyph produced without
	// the option key (i.e. the base glyph).
	if (isCommand) {
		modifiers &= ~optionKey;
	}

	// choose action
	UInt16 action;
	switch (eventKind) {
	case kEventRawKeyDown:
		action = kUCKeyActionDown;
		break;

	case kEventRawKeyRepeat:
		action = kUCKeyActionAutoKey;
		break;

	default:
		return 0;
	}
	// translate via uchr resource
	CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout,
								kTISPropertyUnicodeKeyLayoutData);
	const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref);
	if (layout != NULL) {

		// translate key
		UniCharCount count;
		UniChar chars[2];
		OSStatus status = UCKeyTranslate(layout,
							vkCode & 0xffu, action,
							(modifiers >> 8) & 0xffu,
							LMGetKbdType(), 0, &m_deadKeyState,
							sizeof(chars) / sizeof(chars[0]), &count, chars);

		// get the characters
		if (status == 0) {
			if (count != 0 || m_deadKeyState == 0) {
				m_deadKeyState = 0;
				for (UniCharCount i = 0; i < count; ++i) {
					ids.push_back(CKeyResource::unicharToKeyID(chars[i]));
				}
				adjustAltGrModifier(ids, maskOut, isCommand);
				return mapVirtualKeyToKeyButton(vkCode);
			}
			return 0;
		}
	}
Esempio n. 9
0
void updateScancodes()
{
#ifdef QT_MAC_USE_COCOA
    TISInputSourceRef layout = TISCopyCurrentKeyboardLayoutInputSource();
    if (!layout) {
        qWarning() << "Error retrieving current layout";
        return;
    }
    if (layout == lastLayout) {
        CFRelease(layout);
    } else {
        // keyboard layout changed
#ifndef NDEBUG
        const void *name = TISGetInputSourceProperty(layout, kTISPropertyLocalizedName);
        qDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef)name, 0);
#endif
        lastLayout = layout;
        scancodes.clear();

        CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(layout,
                                                kTISPropertyUnicodeKeyLayoutData));
        const UCKeyboardLayout *ucData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;

        if (!ucData) {
            qWarning() << "Error retrieving current layout character data";
            return;
        }

        for (int i = 0; i < 128; ++i) {
            UInt32 tmpState = 0;
            UniChar str[4];
            UniCharCount actualLength = 0;
            OSStatus err = UCKeyTranslate(ucData, i, kUCKeyActionDown, 0, LMGetKbdType(),
                                          kUCKeyTranslateNoDeadKeysMask, &tmpState, 4, &actualLength, str);
            if (err != noErr) {
                qWarning() << "Error translating unicode key" << err;
            } else {
                if (str[0] && str[0] != kFunctionKeyCharCode) {
                    scancodes.insert(str[0], i);
                }
            }
        }
    }
#else
    KeyboardLayoutRef layout;
    if (KLGetCurrentKeyboardLayout(&layout) != noErr) {
        qWarning() << "Error retrieving current layout";
    }
    if (layout != lastLayout) {
#ifndef NDEBUG
        void *name;
        KLGetKeyboardLayoutProperty(layout, kKLName, const_cast<const void **>(&name));
        qDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef) name, 0);
#endif
        lastLayout = layout;
        scancodes.clear();
        void *kchr;
        if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast<const void **>(&kchr)) != noErr) {
            qWarning() << "Couldn't load active keyboard layout";
        } else {
            for (int i = 0; i < 128; i++) {
                UInt32 tmpState = 0;
                UInt32 chr = KeyTranslate(kchr, i, &tmpState);
                if (chr && chr != kFunctionKeyCharCode) {
                    scancodes.insert(chr, i);
                }
            }
        }
    }
#endif
}