static UniChar OSKeyCodeToUnicode( UInt16 osKeyCode, bool shift = false ) { // Translate the key code. UniChar uniChar = 0; if( sKeyLayoutKind == kKLKCHRKind ) { // KCHR mapping. void* KCHRData; KLGetKeyboardLayoutProperty( sKeyLayout, kKLKCHRData, ( const void** ) & KCHRData ); UInt16 key = ( osKeyCode & 0x7f ); if( shift ) key |= NSShiftKeyMask; UInt32 keyTranslateState = 0; UInt32 charCode = KeyTranslate( KCHRData, key, &keyTranslateState ); charCode &= 0xff; if( keyTranslateState == 0 && charCode ) uniChar = charCode; } else { // UCHR mapping. UCKeyboardLayout* uchrData; KLGetKeyboardLayoutProperty( sKeyLayout, kKLuchrData, ( const void** ) &uchrData ); UInt32 deadKeyState; UniCharCount actualStringLength; UniChar unicodeString[ 4 ]; UCKeyTranslate( uchrData, osKeyCode, kUCKeyActionDown, ( shift ? 0x02 : 0 ), // Oh yeah... Apple docs are fun... LMGetKbdType(), 0, &deadKeyState, sizeof( unicodeString ) / sizeof( unicodeString[ 0 ] ), &actualStringLength, unicodeString ); if( actualStringLength ) uniChar = unicodeString[ 0 ]; // Well, Unicode is something else, but... } return uniChar; }
void _glfwHandleMacKeyChange( UInt32 keyCode, int action ) { switch ( keyCode ) { case MAC_KEY_ESC: _glfwInputKey( GLFW_KEY_ESC, action); break; case MAC_KEY_F1: _glfwInputKey( GLFW_KEY_F1, action); break; case MAC_KEY_F2: _glfwInputKey( GLFW_KEY_F2, action); break; case MAC_KEY_F3: _glfwInputKey( GLFW_KEY_F3, action); break; case MAC_KEY_F4: _glfwInputKey( GLFW_KEY_F4, action); break; case MAC_KEY_F5: _glfwInputKey( GLFW_KEY_F5, action); break; case MAC_KEY_F6: _glfwInputKey( GLFW_KEY_F6, action); break; case MAC_KEY_F7: _glfwInputKey( GLFW_KEY_F7, action); break; case MAC_KEY_F8: _glfwInputKey( GLFW_KEY_F8, action); break; case MAC_KEY_F9: _glfwInputKey( GLFW_KEY_F9, action); break; case MAC_KEY_F10: _glfwInputKey( GLFW_KEY_F10, action); break; case MAC_KEY_F11: _glfwInputKey( GLFW_KEY_F11, action); break; case MAC_KEY_F12: _glfwInputKey( GLFW_KEY_F12, action); break; case MAC_KEY_F13: _glfwInputKey( GLFW_KEY_F13, action); break; case MAC_KEY_F14: _glfwInputKey( GLFW_KEY_F14, action); break; case MAC_KEY_F15: _glfwInputKey( GLFW_KEY_F15, action); break; case MAC_KEY_UP: _glfwInputKey( GLFW_KEY_UP, action); break; case MAC_KEY_DOWN: _glfwInputKey( GLFW_KEY_DOWN, action); break; case MAC_KEY_LEFT: _glfwInputKey( GLFW_KEY_LEFT, action); break; case MAC_KEY_RIGHT: _glfwInputKey( GLFW_KEY_RIGHT, action); break; case MAC_KEY_TAB: _glfwInputKey( GLFW_KEY_TAB, action); break; case MAC_KEY_BACKSPACE: _glfwInputKey( GLFW_KEY_BACKSPACE, action); break; case MAC_KEY_HELP: _glfwInputKey( GLFW_KEY_INSERT, action); break; case MAC_KEY_DEL: _glfwInputKey( GLFW_KEY_DEL, action); break; case MAC_KEY_PAGEUP: _glfwInputKey( GLFW_KEY_PAGEUP, action); break; case MAC_KEY_PAGEDOWN: _glfwInputKey( GLFW_KEY_PAGEDOWN, action); break; case MAC_KEY_HOME: _glfwInputKey( GLFW_KEY_HOME, action); break; case MAC_KEY_END: _glfwInputKey( GLFW_KEY_END, action); break; case MAC_KEY_KP_0: _glfwInputKey( GLFW_KEY_KP_0, action); break; case MAC_KEY_KP_1: _glfwInputKey( GLFW_KEY_KP_1, action); break; case MAC_KEY_KP_2: _glfwInputKey( GLFW_KEY_KP_2, action); break; case MAC_KEY_KP_3: _glfwInputKey( GLFW_KEY_KP_3, action); break; case MAC_KEY_KP_4: _glfwInputKey( GLFW_KEY_KP_4, action); break; case MAC_KEY_KP_5: _glfwInputKey( GLFW_KEY_KP_5, action); break; case MAC_KEY_KP_6: _glfwInputKey( GLFW_KEY_KP_6, action); break; case MAC_KEY_KP_7: _glfwInputKey( GLFW_KEY_KP_7, action); break; case MAC_KEY_KP_8: _glfwInputKey( GLFW_KEY_KP_8, action); break; case MAC_KEY_KP_9: _glfwInputKey( GLFW_KEY_KP_9, action); break; case MAC_KEY_KP_DIVIDE: _glfwInputKey( GLFW_KEY_KP_DIVIDE, action); break; case MAC_KEY_KP_MULTIPLY: _glfwInputKey( GLFW_KEY_KP_MULTIPLY, action); break; case MAC_KEY_KP_SUBTRACT: _glfwInputKey( GLFW_KEY_KP_SUBTRACT, action); break; case MAC_KEY_KP_ADD: _glfwInputKey( GLFW_KEY_KP_ADD, action); break; case MAC_KEY_KP_DECIMAL: _glfwInputKey( GLFW_KEY_KP_DECIMAL, action); break; case MAC_KEY_KP_EQUAL: _glfwInputKey( GLFW_KEY_KP_EQUAL, action); break; case MAC_KEY_KP_ENTER: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break; default: { UInt32 state = 0; const void *KCHR = (const void *)GetScriptVariable(smCurrentScript, smKCHRCache); char charCode = (char)KeyTranslate( KCHR, keyCode, &state ); UppercaseText( &charCode, 1, smSystemScript ); _glfwInputKey( charCode, action ); } break; } }
int _glfwPlatformInit( void ) { struct timeval tv; UInt32 nullDummy = 0; _glfwWin.MacWindow = NULL; _glfwWin.AGLContext = NULL; _glfwWin.WindowFunctions = NULL; _glfwWin.MouseUPP = NULL; _glfwWin.CommandUPP = NULL; _glfwWin.KeyboardUPP = NULL; _glfwWin.WindowUPP = NULL; _glfwInput.Modifiers = 0; _glfwLibs.OpenGLFramework = CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) ); if( _glfwLibs.OpenGLFramework == NULL ) { return GL_FALSE; } _glfwDesktopVideoMode = CGDisplayCurrentMode( kCGDirectMainDisplay ); if( _glfwDesktopVideoMode == NULL ) { return GL_FALSE; } _glfwInitThreads(); if( !_glfwChangeToResourcesDirectory() ) { return GL_FALSE; } if( !_glfwInstallEventHandlers() ) { _glfwPlatformTerminate(); return GL_FALSE; } // Ugly hack to reduce the nasty jump that occurs at the first non- // sys keypress, caused by OS X loading certain meta scripts used // for lexical- and raw keycode translation - instead of letting // this happen while our application is running, we do some blunt // function calls in advance just to get the script caching out of // the way, BEFORE our window/screen is opened. These calls might // generate err return codes, but we don't care in this case. // NOTE: KCHRPtr is declared globally, because we need it later on. KCHRPtr = (void *)GetScriptVariable( smCurrentScript, smKCHRCache ); KeyTranslate( KCHRPtr, 0, &nullDummy ); UppercaseText( (char *)&nullDummy, 0, smSystemScript ); gettimeofday( &tv, NULL ); _glfwTimer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0; return GL_TRUE; }
KeySym XKeycodeToKeysym( Display* display, KeyCode keycode, int index) { register Tcl_HashEntry *hPtr; register char c; char virtualKey; int newKeycode; unsigned long dummy, newChar; if (!initialized) { InitKeyMaps(); } c = keycode & charCodeMask; virtualKey = (keycode & keyCodeMask) >> 8; /* * When determining what keysym to produce we firt check to see if * the key is a function key. We then check to see if the character * is another non-printing key. Finally, we return the key syms * for all ASCI chars. */ if (c == 0x10) { hPtr = Tcl_FindHashEntry(&vkeyTable, (char *) virtualKey); if (hPtr != NULL) { return (KeySym) Tcl_GetHashValue(hPtr); } } hPtr = Tcl_FindHashEntry(&keycodeTable, (char *) virtualKey); if (hPtr != NULL) { return (KeySym) Tcl_GetHashValue(hPtr); } /* * Recompute the character based on the Shift key only. * TODO: The index may also specify the NUM_LOCK. */ newKeycode = virtualKey; if (index & 0x01) { newKeycode += 0x0200; } dummy = 0; newChar = KeyTranslate(KCHRPtr, (short) newKeycode, &dummy); c = newChar & charCodeMask; if (c >= XK_space && c < XK_asciitilde) { return c; } return NoSymbol; }
int _glfwPlatformInit( void ) { struct timeval tv; UInt32 nullDummy = 0; _glfwWin.window = NULL; _glfwWin.aglContext = NULL; _glfwWin.cglContext = NULL; _glfwWin.windowUPP = NULL; _glfwInput.Modifiers = 0; _glfwLibrary.Unbundled = 0; _glfwLibrary.Libs.OpenGLFramework = CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) ); if( _glfwLibrary.Libs.OpenGLFramework == NULL ) { fprintf( stderr, "glfwInit failing because you aren't linked to OpenGL\n" ); return GL_FALSE; } _glfwPlatformGetDesktopMode( &_glfwLibrary.desktopMode ); // Install atexit routine atexit( glfw_atexit ); _glfwInitThreads(); _glfwChangeToResourcesDirectory(); // Ugly hack to reduce the nasty jump that occurs at the first non- // sys keypress, caused by OS X loading certain meta scripts used // for lexical- and raw keycode translation - instead of letting // this happen while our application is running, we do some blunt // function calls in advance just to get the script caching out of // the way BEFORE our window/screen is opened. These calls might // generate err return codes, but we don't care in this case. // NOTE: KCHRPtr is declared globally, because we need it later on. KCHRPtr = (void *)GetScriptVariable( smCurrentScript, smKCHRCache ); KeyTranslate( KCHRPtr, 0, &nullDummy ); UppercaseText( (char *)&nullDummy, 0, smSystemScript ); gettimeofday( &tv, NULL ); _glfwLibrary.Timer.t0 = tv.tv_sec + (double) tv.tv_usec / 1000000.0; return GL_TRUE; }
static GHOST_TKey convertKey(int rawCode) { /* This bit of magic converts the rawCode into a virtual * Mac key based on the current keyboard mapping, but * without regard to the modifiers (so we don't get 'a' * and 'A' for example. */ static UInt32 dummy = 0; Handle transData = (Handle) GetScriptManagerVariable(smKCHRCache); unsigned char vk = KeyTranslate(transData, rawCode, &dummy); /* Map numpad based on rawcodes first, otherwise they * look like non-numpad events. * Added too: mapping the number keys, for french keyboards etc (ton) */ // printf("GHOST: vk: %d %c raw: %d\n", vk, vk, rawCode); switch (rawCode) { case 18: return GHOST_kKey1; case 19: return GHOST_kKey2; case 20: return GHOST_kKey3; case 21: return GHOST_kKey4; case 23: return GHOST_kKey5; case 22: return GHOST_kKey6; case 26: return GHOST_kKey7; case 28: return GHOST_kKey8; case 25: return GHOST_kKey9; case 29: return GHOST_kKey0; case 82: return GHOST_kKeyNumpad0; case 83: return GHOST_kKeyNumpad1; case 84: return GHOST_kKeyNumpad2; case 85: return GHOST_kKeyNumpad3; case 86: return GHOST_kKeyNumpad4; case 87: return GHOST_kKeyNumpad5; case 88: return GHOST_kKeyNumpad6; case 89: return GHOST_kKeyNumpad7; case 91: return GHOST_kKeyNumpad8; case 92: return GHOST_kKeyNumpad9; case 65: return GHOST_kKeyNumpadPeriod; case 76: return GHOST_kKeyNumpadEnter; case 69: return GHOST_kKeyNumpadPlus; case 78: return GHOST_kKeyNumpadMinus; case 67: return GHOST_kKeyNumpadAsterisk; case 75: return GHOST_kKeyNumpadSlash; } if ((vk >= 'a') && (vk <= 'z')) { return (GHOST_TKey) (vk - 'a' + GHOST_kKeyA); } else if ((vk >= '0') && (vk <= '9')) { return (GHOST_TKey) (vk - '0' + GHOST_kKey0); } else if (vk == 16) { switch (rawCode) { case 122: return GHOST_kKeyF1; case 120: return GHOST_kKeyF2; case 99: return GHOST_kKeyF3; case 118: return GHOST_kKeyF4; case 96: return GHOST_kKeyF5; case 97: return GHOST_kKeyF6; case 98: return GHOST_kKeyF7; case 100: return GHOST_kKeyF8; case 101: return GHOST_kKeyF9; case 109: return GHOST_kKeyF10; case 103: return GHOST_kKeyF11; case 111: return GHOST_kKeyF12; // Never get, is used for ejecting the CD! } } else { switch (vk) { case kUpArrowCharCode: return GHOST_kKeyUpArrow; case kDownArrowCharCode: return GHOST_kKeyDownArrow; case kLeftArrowCharCode: return GHOST_kKeyLeftArrow; case kRightArrowCharCode: return GHOST_kKeyRightArrow; case kReturnCharCode: return GHOST_kKeyEnter; case kBackspaceCharCode: return GHOST_kKeyBackSpace; case kDeleteCharCode: return GHOST_kKeyDelete; case kEscapeCharCode: return GHOST_kKeyEsc; case kTabCharCode: return GHOST_kKeyTab; case kSpaceCharCode: return GHOST_kKeySpace; case kHomeCharCode: return GHOST_kKeyHome; case kEndCharCode: return GHOST_kKeyEnd; case kPageUpCharCode: return GHOST_kKeyUpPage; case kPageDownCharCode: return GHOST_kKeyDownPage; case '-': return GHOST_kKeyMinus; case '=': return GHOST_kKeyEqual; case ',': return GHOST_kKeyComma; case '.': return GHOST_kKeyPeriod; case '/': return GHOST_kKeySlash; case ';': return GHOST_kKeySemicolon; case '\'': return GHOST_kKeyQuote; case '\\': return GHOST_kKeyBackslash; case '[': return GHOST_kKeyLeftBracket; case ']': return GHOST_kKeyRightBracket; case '`': return GHOST_kKeyAccentGrave; } } // printf("GHOST: unknown key: %d %d\n", vk, rawCode); return GHOST_kKeyUnknown; }
// This method handles common code for SendKeyDown, SendKeyUp, and SendChar events. void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) { #if wxOSX_USE_COCOA_OR_CARBON short keycode, keychar ; keychar = short(keymessage & charCodeMask); keycode = short(keymessage & keyCodeMask) >> 8 ; if ( !(event.GetEventType() == wxEVT_CHAR) && (modifiers & (controlKey | shiftKey | optionKey) ) ) { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after #ifdef __LP64__ // TODO new implementation using TextInputSources #else UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); #endif } long keyval = wxMacTranslateKey(keychar, keycode) ; if ( keyval == keychar && ( event.GetEventType() == wxEVT_KEY_UP || event.GetEventType() == wxEVT_KEY_DOWN ) ) keyval = wxToupper( keyval ) ; // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the // WXK_NUMPAD constants, but for the CHAR event we want to use the // standard ascii values if ( event.GetEventType() != wxEVT_CHAR ) { if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) { keyval = (keyval - '0') + WXK_NUMPAD0; } else if (keycode >= 65 && keycode <= 81) { switch (keycode) { case 76 : keyval = WXK_NUMPAD_ENTER; break; case 81: keyval = WXK_NUMPAD_EQUAL; break; case 67: keyval = WXK_NUMPAD_MULTIPLY; break; case 75: keyval = WXK_NUMPAD_DIVIDE; break; case 78: keyval = WXK_NUMPAD_SUBTRACT; break; case 69: keyval = WXK_NUMPAD_ADD; break; case 65: keyval = WXK_NUMPAD_DECIMAL; break; default: break; } } } event.m_shiftDown = modifiers & shiftKey; event.m_rawControlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_controlDown = modifiers & cmdKey; event.m_keyCode = keyval ; #if wxUSE_UNICODE event.m_uniChar = uniChar ; #endif event.m_rawCode = keymessage; event.m_rawFlags = modifiers; event.SetTimestamp(when); event.SetEventObject(focus); #else wxUnusedVar(event); wxUnusedVar(focus); wxUnusedVar(keymessage); wxUnusedVar(modifiers); wxUnusedVar(when); wxUnusedVar(uniChar); #endif }
OSStatus CL_DisplayWindow_OpenGL::on_window_event(EventHandlerCallRef call_ref, EventRef event_ref, void *user_data) { CL_DisplayWindow_OpenGL *self = (CL_DisplayWindow_OpenGL *) user_data; OSStatus result = CallNextEventHandler(call_ref, event_ref); UInt32 event_class = GetEventClass(event_ref); UInt32 event_kind = GetEventKind(event_ref); if (event_class == kEventClassKeyboard) { Point mouse_pos; UInt32 key_modifiers = 0; UInt32 click_count = 0; UInt32 key_code = 0; // Todo: // KeyboardLayoutRef layout; // KLGetCurrentKeyboardLayout(&layout); // KLGetKeyboardLayoutProperty(layout, kKLuchrData, &data); // call UCKeyTranslate to get unicode string for keys being pressed. GetMouse(&mouse_pos); GetEventParameter(event_ref, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &key_modifiers); GetEventParameter(event_ref, kEventParamKeyCode, typeUInt32, 0, sizeof(UInt32), 0, &key_code); GetEventParameter(event_ref, kEventParamClickCount, typeUInt32, 0, sizeof(UInt32), 0, &click_count); if (!self->fullscreen) { Rect wbounds; GetWindowBounds(self->window_ref, kWindowContentRgn, &wbounds); mouse_pos.h -= wbounds.left; mouse_pos.v -= wbounds.top; } static unsigned long state = 0; static Ptr keymap = nil; Ptr new_keymap; // Get the current keyboard map resource new_keymap = (Ptr)GetScriptManagerVariable(smKCHRCache); if (new_keymap != keymap) { keymap = new_keymap; state = 0; } CL_InputEvent event; event.str = KeyTranslate(keymap, key_code|key_modifiers, &state) & 0xffff; event.device = self->keyboard; event.mouse_pos = CL_Point(mouse_pos.h, mouse_pos.v); event.repeat_count = click_count; self->mouse_pos = event.mouse_pos; // if kEventParamMouseLocation is not valid here, reverse this. switch (event_kind) { case kEventRawKeyModifiersChanged: { std::set<int> current_keys = modifiercode_to_clkeys(key_modifiers); for (std::set<int>::iterator i=current_keys.begin(); i!=current_keys.end(); i++) { if (!self->prev_modifier_keys.count(*i)) { event.id = *i; event.type = CL_InputEvent::pressed; self->keyboard.sig_key_down().call(event); } } for (std::set<int>::iterator i=self->prev_modifier_keys.begin(); i!=self->prev_modifier_keys.end(); i++) { if (!current_keys.count(*i)) { event.id = *i; event.type = CL_InputEvent::released; self->keyboard.sig_key_up().call(event); } } self->prev_modifier_keys = current_keys; return noErr; } case kEventRawKeyDown: // first tests for cmd-q(12) or cmd-w(13) to close the window if needed if ((key_modifiers & cmdKey) && (key_code==12 || key_code==13)) { EventRef close_event; CreateEvent(NULL, kEventClassWindow, kEventWindowClose, 0, kEventAttributeNone, &close_event); EventTargetRef target = GetWindowEventTarget(self->window_ref); SendEventToEventTarget(close_event, target); return noErr; } else { event.id = keycode_to_clkey(key_code); event.type = CL_InputEvent::pressed; self->keyboard.sig_key_down().call(event); return noErr; } case kEventRawKeyRepeat: event.id = keycode_to_clkey(key_code); event.type = CL_InputEvent::pressed; self->keyboard.sig_key_down().call(event); return noErr; case kEventRawKeyUp: event.id = keycode_to_clkey(key_code); event.type = CL_InputEvent::released; self->keyboard.sig_key_up().call(event); return noErr; } } else if (event_class == kEventClassMouse) { Point mouse_pos; EventMouseButton mouse_button; UInt32 key_modifiers = 0; GetEventParameter(event_ref, kEventParamMouseLocation, typeQDPoint, 0, sizeof(Point), 0, &mouse_pos); GetEventParameter(event_ref, kEventParamMouseButton, typeMouseButton, 0, sizeof(EventMouseButton), 0, &mouse_button); GetEventParameter(event_ref, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &key_modifiers); if (!self->fullscreen) { Rect wbounds; GetWindowBounds(self->window_ref, kWindowContentRgn, &wbounds); mouse_pos.h -= wbounds.left; mouse_pos.v -= wbounds.top; } CL_InputEvent event; event.id = mouse_button-1; event.device = self->mouse; event.mouse_pos = CL_Point(mouse_pos.h, mouse_pos.v); // Simulate second mouse button. if ((key_modifiers & controlKey) && (event.id == CL_MOUSE_LEFT)) event.id = CL_MOUSE_RIGHT; self->mouse_pos = event.mouse_pos; switch (event_kind) { case kEventMouseDown: self->mouse_states[event.id] = true; event.type = CL_InputEvent::pressed; self->mouse.sig_key_down().call(event); return noErr; case kEventMouseUp: self->mouse_states[event.id] = false; event.type = CL_InputEvent::released; self->mouse.sig_key_up().call(event); return noErr; case kEventMouseMoved: case kEventMouseDragged: self->mouse.sig_pointer_move().call(event); return noErr; case kEventMouseWheelMoved: //Note, this is not properly handling large quick wheel movements, but the implementation on other //platforms don't seem to either so I will do it their way for consistancy - mrfun EventMouseWheelAxis axis; GetEventParameter(event_ref, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(axis), NULL, &axis); if (axis == kEventMouseWheelAxisY) { long wheel_delta = 0; GetEventParameter(event_ref, kEventParamMouseWheelDelta, typeLongInteger, 0, sizeof(long), 0, &wheel_delta); //Ok, let me explain this bIgnoreThisOne thing. We are being passed two identical wheel events for every wheel movement - //This behavior is also in the apple example app GLCarbonAGLWindow and I can't figure out a way to get it to send only one //event or a difference in the events. (like a press and release tag differentiating them) //So the hack solution is to simply ignore every other mouse wheel event. This way, programs behave the same on every //platform instead of wheel zooming being twice as fast on macs. //If anybody has a better solution or finds a problem here please feel free to dig in. -mrfun static bool bIgnoreThisOne = true; bIgnoreThisOne = !bIgnoreThisOne; if (bIgnoreThisOne) if (wheel_delta) { if (wheel_delta > 0) { event.id = CL_MOUSE_WHEEL_UP; } else { event.id = CL_MOUSE_WHEEL_DOWN; } //sending both the down and up event, like the linux version event.type = CL_InputEvent::pressed; self->mouse.sig_key_down().call(event); event.type = CL_InputEvent::released; self->mouse.sig_key_up().call(event); } else { //handle the X axis someday? } } return noErr; } } else if (event_class == kEventClassWindow) { switch (event_kind) { case kEventWindowCollapsing: break; case kEventWindowDrawContent: { if (!self->fullscreen) { Rect rectPort; GetWindowPortBounds(self->window_ref, &rectPort); self->sig_paint( CL_Rect( rectPort.left, rectPort.top, rectPort.right, rectPort.bottom)); } } break; case kEventWindowShown: // called on initial show (not on un-minimize) break; case kEventWindowClose: self->sig_window_close(); return noErr; case kEventWindowActivated: case kEventWindowFocusAcquired: self->focus = true; self->sig_got_focus(); return noErr; case kEventWindowDeactivated: case kEventWindowFocusRelinquish: self->focus = false; self->sig_lost_focus(); return noErr; case kEventWindowBoundsChanged: { if (!self->fullscreen) { Rect rectPort; GetWindowPortBounds (self->window_ref, &rectPort); self->set_size(rectPort.right-rectPort.left, rectPort.bottom-rectPort.top); } } return noErr; case kEventWindowZoomed: // when maximized, but kEventWindowBoundsChanged is also called break; } } return result; }
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(¤tKbdLayout) || !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 }
bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { if ( !focus ) return false ; short keycode ; short keychar ; keychar = short(keymessage & charCodeMask); keycode = short(keymessage & keyCodeMask) >> 8 ; if ( modifiers & ( controlKey|shiftKey|optionKey ) ) { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); } long keyval = wxMacTranslateKey(keychar, keycode) ; if ( keyval == keychar ) { keyval = wxToupper( keyval ) ; } // Check for NUMPAD keys if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) { keyval = keyval - '0' + WXK_NUMPAD0; } else if (keycode >= 67 && keycode <= 81) { switch (keycode) { case 76 : keyval = WXK_NUMPAD_ENTER; break; case 81: keyval = WXK_NUMPAD_EQUAL; break; case 67: keyval = WXK_NUMPAD_MULTIPLY; break; case 75: keyval = WXK_NUMPAD_DIVIDE; break; case 78: keyval = WXK_NUMPAD_SUBTRACT; break; case 69: keyval = WXK_NUMPAD_ADD; break; case 65: keyval = WXK_NUMPAD_DECIMAL; break; } // end switch } bool handled = false ; wxKeyEvent event(wxEVT_KEY_UP); event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; event.m_keyCode = keyval ; #if wxUSE_UNICODE event.m_uniChar = uniChar ; #endif event.m_rawCode = keymessage; event.m_rawFlags = modifiers; event.m_x = wherex; event.m_y = wherey; event.SetTimestamp(when); event.SetEventObject(focus); handled = focus->GetEventHandler()->ProcessEvent( event ) ; return handled ; }
bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { if ( !focus ) return false ; short keycode ; short keychar ; keychar = short(keymessage & charCodeMask); keycode = short(keymessage & keyCodeMask) >> 8 ; if ( modifiers & ( controlKey|shiftKey|optionKey ) ) { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); } long keyval = wxMacTranslateKey(keychar, keycode) ; long realkeyval = keyval ; if ( keyval == keychar ) { // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first) realkeyval = short(keymessage & charCodeMask) ; keyval = wxToupper( keyval ) ; } // Check for NUMPAD keys if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) { keyval = keyval - '0' + WXK_NUMPAD0; } else if (keycode >= 67 && keycode <= 81) { switch (keycode) { case 76 : keyval = WXK_NUMPAD_ENTER; break; case 81: keyval = WXK_NUMPAD_EQUAL; break; case 67: keyval = WXK_NUMPAD_MULTIPLY; break; case 75: keyval = WXK_NUMPAD_DIVIDE; break; case 78: keyval = WXK_NUMPAD_SUBTRACT; break; case 69: keyval = WXK_NUMPAD_ADD; break; case 65: keyval = WXK_NUMPAD_DECIMAL; break; } // end switch } wxKeyEvent event(wxEVT_KEY_DOWN); bool handled = false ; event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; event.m_keyCode = keyval ; #if wxUSE_UNICODE event.m_uniChar = uniChar ; #endif event.m_rawCode = keymessage; event.m_rawFlags = modifiers; event.m_x = wherex; event.m_y = wherey; event.SetTimestamp(when); event.SetEventObject(focus); handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) handled = false ; if ( !handled ) { #if wxUSE_ACCEL if (!handled) { wxWindow *ancestor = focus; while (ancestor) { int command = ancestor->GetAcceleratorTable()->GetCommand( event ); if (command != -1) { wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); break; } if (ancestor->IsTopLevel()) break; ancestor = ancestor->GetParent(); } } #endif // wxUSE_ACCEL } if (!handled) { wxTopLevelWindowMac *tlw = focus->MacGetTopLevelWindow() ; if (tlw) { event.Skip( FALSE ) ; event.SetEventType( wxEVT_CHAR_HOOK ); // raw value again event.m_keyCode = realkeyval ; handled = tlw->GetEventHandler()->ProcessEvent( event ); if ( handled && event.GetSkipped() ) handled = false ; } } if ( !handled ) { event.Skip( FALSE ) ; event.SetEventType( wxEVT_CHAR ) ; // raw value again event.m_keyCode = realkeyval ; handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) handled = false ; } if ( !handled && (keyval == WXK_TAB) ) { wxWindow* iter = focus->GetParent() ; while( iter && !handled ) { if ( iter->HasFlag( wxTAB_TRAVERSAL ) ) { wxNavigationKeyEvent new_event; new_event.SetEventObject( focus ); new_event.SetDirection( !event.ShiftDown() ); /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ new_event.SetWindowChange( event.ControlDown() ); new_event.SetCurrentFocus( focus ); handled = focus->GetParent()->GetEventHandler()->ProcessEvent( new_event ); if ( handled && new_event.GetSkipped() ) handled = false ; } iter = iter->GetParent() ; } } // backdoor handler for default return and command escape if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) ) { // if window is not having a focus still testing for default enter or cancel // TODO add the UMA version for ActiveNonFloatingWindow wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; if ( focus ) { if ( keyval == WXK_RETURN ) { wxButton *def = wxDynamicCast(focus->GetDefaultItem(), wxButton); if ( def && def->IsEnabled() ) { wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); event.SetEventObject(def); def->Command(event); return true ; } } /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */ else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) { wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); new_event.SetEventObject( focus ); handled = focus->GetEventHandler()->ProcessEvent( new_event ); } } } return handled ; }
void BindingsManager::Initialize() { SpecialKeys.clear(); for (int i = 0; i < NUM_OF_STATIC_SPECIAL_KEYS; i++) SpecialKeys.push_back(StaticSpecialKeys[i]); //controllerToUse = 1; should use this if the user entered garbage data (anything that isn't a number) controllerToUse = (int)Configuration::GetConfigf("ControllerNumber") - 1; if (glfwJoystickPresent(controllerToUse)) { int numOfButtons; glfwGetJoystickButtons(controllerToUse, &numOfButtons); if (numOfButtons) { for (int i = 1; i <= numOfButtons; i++) { char name[32]; sprintf(name, "Controller%d", i); sk_s thisButton; strcpy(thisButton.KeyString, name); thisButton.boundkey = 1000 + i; SpecialKeys.push_back(thisButton); } } } JoystickEnabled = (glfwJoystickPresent(GLFW_JOYSTICK_1) == GL_TRUE); std::map <GString, GString> fields; Configuration::GetConfigListS("SystemKeys", fields, ""); // key = function // e.g. Z = gameclick, X = gameclick for (auto i = fields.begin(); i != fields.end(); i++) { // transform special name into keytype index int idx = getIndexForKeytype(i->second.c_str()); // ah it's valid if (idx != -1) { // get the key in either int or name or char format and save that into the key -> command translator int Key = KeyTranslate(i->first.c_str()); if (Key) // a valid key, probably ScanFunction[Key] = (KeyType)idx; } } // fill missing default keys after it's done for (int i = 0; i < DEFAULT_KEYS_COUNT; i++) { if (ScanFunction.find(defaultKeys[i].key) == ScanFunction.end()) { // fill the key -> command translation ScanFunction[defaultKeys[i].key] = defaultKeys[i].command; // write it out to the config file GString charOut; if (defaultKeys[i].key <= 255 && isgraph(defaultKeys[i].key)) // we're not setting like, gibberish { charOut = Utility::CharToStr(defaultKeys[i].key); } else { charOut = getNameForUntranslatedKey(defaultKeys[i].key); } Configuration::SetConfig(charOut, getNameForKeytype(defaultKeys[i].command), "SystemKeys"); } } int i = 1; std::map<GString, GString> Keys; Configuration::GetConfigListS("Keys7K", Keys, ""); for (auto v : Keys) { int Binding = KeyTranslate(v.first); if (Binding) ScanFunction7K[Binding] = floor(latof(v.second)); } }
static void handleMacKeyChange( UInt32 keyCode, int action ) { switch ( keyCode ) { case MAC_KEY_ENTER: _glfwInputKey( GLFW_KEY_ENTER, action); break; case MAC_KEY_RETURN: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break; case MAC_KEY_ESC: _glfwInputKey( GLFW_KEY_ESC, action); break; case MAC_KEY_F1: _glfwInputKey( GLFW_KEY_F1, action); break; case MAC_KEY_F2: _glfwInputKey( GLFW_KEY_F2, action); break; case MAC_KEY_F3: _glfwInputKey( GLFW_KEY_F3, action); break; case MAC_KEY_F4: _glfwInputKey( GLFW_KEY_F4, action); break; case MAC_KEY_F5: _glfwInputKey( GLFW_KEY_F5, action); break; case MAC_KEY_F6: _glfwInputKey( GLFW_KEY_F6, action); break; case MAC_KEY_F7: _glfwInputKey( GLFW_KEY_F7, action); break; case MAC_KEY_F8: _glfwInputKey( GLFW_KEY_F8, action); break; case MAC_KEY_F9: _glfwInputKey( GLFW_KEY_F9, action); break; case MAC_KEY_F10: _glfwInputKey( GLFW_KEY_F10, action); break; case MAC_KEY_F11: _glfwInputKey( GLFW_KEY_F11, action); break; case MAC_KEY_F12: _glfwInputKey( GLFW_KEY_F12, action); break; case MAC_KEY_F13: _glfwInputKey( GLFW_KEY_F13, action); break; case MAC_KEY_F14: _glfwInputKey( GLFW_KEY_F14, action); break; case MAC_KEY_F15: _glfwInputKey( GLFW_KEY_F15, action); break; case MAC_KEY_UP: _glfwInputKey( GLFW_KEY_UP, action); break; case MAC_KEY_DOWN: _glfwInputKey( GLFW_KEY_DOWN, action); break; case MAC_KEY_LEFT: _glfwInputKey( GLFW_KEY_LEFT, action); break; case MAC_KEY_RIGHT: _glfwInputKey( GLFW_KEY_RIGHT, action); break; case MAC_KEY_TAB: _glfwInputKey( GLFW_KEY_TAB, action); break; case MAC_KEY_BACKSPACE: _glfwInputKey( GLFW_KEY_BACKSPACE, action); break; case MAC_KEY_HELP: _glfwInputKey( GLFW_KEY_INSERT, action); break; case MAC_KEY_DEL: _glfwInputKey( GLFW_KEY_DEL, action); break; case MAC_KEY_PAGEUP: _glfwInputKey( GLFW_KEY_PAGEUP, action); break; case MAC_KEY_PAGEDOWN: _glfwInputKey( GLFW_KEY_PAGEDOWN, action); break; case MAC_KEY_HOME: _glfwInputKey( GLFW_KEY_HOME, action); break; case MAC_KEY_END: _glfwInputKey( GLFW_KEY_END, action); break; case MAC_KEY_KP_0: _glfwInputKey( GLFW_KEY_KP_0, action); break; case MAC_KEY_KP_1: _glfwInputKey( GLFW_KEY_KP_1, action); break; case MAC_KEY_KP_2: _glfwInputKey( GLFW_KEY_KP_2, action); break; case MAC_KEY_KP_3: _glfwInputKey( GLFW_KEY_KP_3, action); break; case MAC_KEY_KP_4: _glfwInputKey( GLFW_KEY_KP_4, action); break; case MAC_KEY_KP_5: _glfwInputKey( GLFW_KEY_KP_5, action); break; case MAC_KEY_KP_6: _glfwInputKey( GLFW_KEY_KP_6, action); break; case MAC_KEY_KP_7: _glfwInputKey( GLFW_KEY_KP_7, action); break; case MAC_KEY_KP_8: _glfwInputKey( GLFW_KEY_KP_8, action); break; case MAC_KEY_KP_9: _glfwInputKey( GLFW_KEY_KP_9, action); break; case MAC_KEY_KP_DIVIDE: _glfwInputKey( GLFW_KEY_KP_DIVIDE, action); break; case MAC_KEY_KP_MULTIPLY: _glfwInputKey( GLFW_KEY_KP_MULTIPLY, action); break; case MAC_KEY_KP_SUBTRACT: _glfwInputKey( GLFW_KEY_KP_SUBTRACT, action); break; case MAC_KEY_KP_ADD: _glfwInputKey( GLFW_KEY_KP_ADD, action); break; case MAC_KEY_KP_DECIMAL: _glfwInputKey( GLFW_KEY_KP_DECIMAL, action); break; case MAC_KEY_KP_EQUAL: _glfwInputKey( GLFW_KEY_KP_EQUAL, action); break; case MAC_KEY_KP_ENTER: _glfwInputKey( GLFW_KEY_KP_ENTER, action); break; case MAC_KEY_NUMLOCK: _glfwInputKey( GLFW_KEY_KP_NUM_LOCK, action); break; default: { extern void *KCHRPtr; UInt32 state = 0; char charCode = (char)KeyTranslate( KCHRPtr, keyCode, &state ); UppercaseText( &charCode, 1, smSystemScript ); _glfwInputKey( (unsigned char)charCode, action ); } break; } }
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 }