21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_COCOA 27 #include "../../events/SDL_events_c.h" 28 #include "../../events/SDL_keyboard_c.h" 29 #include "../../events/scancodes_darwin.h" 31 #include <Carbon/Carbon.h> 34 #define DEBUG_IME(...) 36 @interface SDLTranslatorResponder : NSView <NSTextInputClient> {
37 NSString *_markedText;
39 NSRange _selectedRange;
42 - (
void)doCommandBySelector:(
SEL)myselector;
46 @implementation SDLTranslatorResponder
53 - (
void)insertText:(
id)aString replacementRange:(NSRange)replacementRange
59 DEBUG_IME(
@"insertText: %@", aString);
63 if ([aString isKindOfClass: [NSAttributedString
class]]) {
64 str = [[aString string] UTF8String];
66 str = [aString UTF8String];
72 - (
void)insertText:(
id)insertString
77 [
self insertText:insertString replacementRange:NSMakeRange(0, 0)];
80 - (
void)doCommandBySelector:(
SEL)myselector
90 return _markedText != nil;
93 - (NSRange)markedRange
98 - (NSRange)selectedRange
100 return _selectedRange;
103 - (
void)setMarkedText:(
id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange;
105 if ([aString isKindOfClass: [NSAttributedString
class]]) {
106 aString = [aString string];
109 if ([aString
length] == 0) {
114 if (_markedText != aString) {
115 [_markedText release];
116 _markedText = [aString retain];
119 _selectedRange = selectedRange;
120 _markedRange = NSMakeRange(0, [aString
length]);
123 selectedRange.location, selectedRange.length);
125 DEBUG_IME(
@"setMarkedText: %@, (%d, %d)", _markedText,
126 selRange.location, selRange.length);
131 [_markedText release];
137 - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange;
139 NSWindow *
window = [
self window];
140 NSRect contentRect = [window contentRectForFrameRect:[window frame]];
141 float windowHeight = contentRect.size.height;
142 NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h,
143 _inputRect.w, _inputRect.h);
146 *actualRange = aRange;
149 DEBUG_IME(
@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@",
150 aRange.location, aRange.length, windowHeight,
151 NSStringFromRect(rect));
153 if ([[
self window] respondsToSelector:
@selector(convertRectToScreen:)]) {
154 rect = [[
self window] convertRectToScreen:rect];
156 rect.origin = [[
self window] convertBaseToScreen:rect.origin];
162 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange;
164 DEBUG_IME(
@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length);
168 - (NSInteger)conversationIdentifier
170 return (NSInteger)
self;
176 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
178 DEBUG_IME(
@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
187 - (NSArray *)validAttributesForMarkedText
189 return [NSArray array];
199 HandleNonDeviceModifier(
unsigned int device_independent_mask,
200 unsigned int oldMods,
201 unsigned int newMods,
204 unsigned int oldMask, newMask;
209 oldMask = oldMods & device_independent_mask;
210 newMask = newMods & device_independent_mask;
212 if (oldMask && oldMask != newMask) {
214 }
else if (newMask && oldMask != newMask) {
223 HandleModifierOneSide(
unsigned int oldMods,
unsigned int newMods,
225 unsigned int sided_device_dependent_mask)
227 unsigned int old_dep_mask, new_dep_mask;
232 old_dep_mask = oldMods & sided_device_dependent_mask;
233 new_dep_mask = newMods & sided_device_dependent_mask;
239 if (new_dep_mask && old_dep_mask != new_dep_mask) {
251 HandleModifierSide(
int device_independent_mask,
252 unsigned int oldMods,
unsigned int newMods,
255 unsigned int left_device_dependent_mask,
256 unsigned int right_device_dependent_mask)
258 unsigned int device_dependent_mask = (left_device_dependent_mask |
259 right_device_dependent_mask);
260 unsigned int diff_mod;
266 if ((device_dependent_mask & newMods) == 0) {
268 HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
273 diff_mod = (device_dependent_mask & oldMods) ^
274 (device_dependent_mask & newMods);
280 if (left_device_dependent_mask & diff_mod) {
281 HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
283 if (right_device_dependent_mask & diff_mod) {
284 HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
295 ReleaseModifierSide(
unsigned int device_independent_mask,
296 unsigned int oldMods,
unsigned int newMods,
299 unsigned int left_device_dependent_mask,
300 unsigned int right_device_dependent_mask)
302 unsigned int device_dependent_mask = (left_device_dependent_mask |
303 right_device_dependent_mask);
309 if ((device_dependent_mask & oldMods) == 0) {
323 if ( left_device_dependent_mask & oldMods ) {
326 if ( right_device_dependent_mask & oldMods ) {
335 HandleCapsLock(
unsigned short scancode,
336 unsigned int oldMods,
unsigned int newMods)
338 unsigned int oldMask, newMask;
340 oldMask = oldMods & NSAlphaShiftKeyMask;
341 newMask = newMods & NSAlphaShiftKeyMask;
343 if (oldMask != newMask) {
353 DoSidedModifiers(
unsigned short scancode,
354 unsigned int oldMods,
unsigned int newMods)
372 const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
373 const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
378 HandleCapsLock(scancode, oldMods, newMods);
381 for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
382 unsigned int oldMask, newMask;
384 oldMask = oldMods & bit;
385 newMask = newMods & bit;
391 HandleModifierSide(bit, oldMods, newMods,
392 left_mapping[i], right_mapping[i],
393 left_device_mapping[i], right_device_mapping[i]);
398 else if (oldMask && oldMask != newMask) {
399 ReleaseModifierSide(bit, oldMods, newMods,
400 left_mapping[i], right_mapping[i],
401 left_device_mapping[i], right_device_mapping[i]);
407 HandleModifiers(
_THIS,
unsigned short scancode,
unsigned int modifierFlags)
415 DoSidedModifiers(scancode, data->
modifierFlags, modifierFlags);
422 TISInputSourceRef key_layout;
423 const void *chr_data;
429 key_layout = TISCopyCurrentKeyboardLayoutInputSource();
438 CFDataRef uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData);
440 chr_data = CFDataGetBytePtr(uchrDataRef);
446 UInt32 keyboard_type = LMGetKbdType();
452 UInt32 dead_key_state;
462 err = UCKeyTranslate ((UCKeyboardLayout *) chr_data,
465 kUCKeyTranslateNoDeadKeysMask,
466 &dead_key_state, 8, &len, s);
471 if (len > 0 && s[0] != 0x10) {
472 keymap[scancode] = s[0];
483 CFRelease(key_layout);
502 if (
floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
514 NSWindow *nswindow = nil;
519 NSView *parentView = [nswindow contentView];
528 [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
531 if (![[data->
fieldEdit superview] isEqual:parentView]) {
533 [data->fieldEdit removeFromSuperview];
534 [parentView addSubview: data->fieldEdit];
535 [nswindow makeFirstResponder: data->fieldEdit];
546 [data->fieldEdit removeFromSuperview];
547 [data->fieldEdit release];
562 [data->fieldEdit setInputRect:rect];
573 unsigned short scancode = [event keyCode];
579 if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
581 scancode = 60 - scancode;
591 switch ([event
type]) {
593 if (![event isARepeat]) {
601 fprintf(stderr,
"The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
606 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
608 text = [[event characters] UTF8String];
611 [data->fieldEdit setString:@""];
621 HandleModifiers(
_this, scancode, [event modifierFlags]);
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
SDLTranslatorResponder * fieldEdit
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define SDLK_SCANCODE_MASK
#define SDL_GetKeyboardFocus
#define SDL_InvalidParamError(param)
unsigned int modifierFlags
void Cocoa_StartTextInput(_THIS)
Sint32 SDL_Keycode
The SDL virtual key representation.
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
void Cocoa_QuitKeyboard(_THIS)
static SDL_VideoDevice * _this
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
static const SDL_Scancode darwin_scancode_table[]
GLuint GLuint GLsizei GLenum type
int SDL_SendKeyboardText(const char *text)
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
static char text[MAX_TEXT_LENGTH]
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
int SDL_SendKeymapChangedEvent(void)
The type used to identify a window.
void Cocoa_InitKeyboard(_THIS)
void Cocoa_StopTextInput(_THIS)
#define SDL_arraysize(array)
GLuint GLsizei GLsizei * length
static void cleanup(void)
SDL_Scancode
The SDL keyboard scancode representation.
int SDL_SendEditingText(const char *text, int start, int length)
A rectangle, with the origin at the upper left.