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)doCommandBySelector:(
SEL)myselector
82 return _markedText != nil;
85 - (NSRange)markedRange
90 - (NSRange)selectedRange
92 return _selectedRange;
95 - (
void)setMarkedText:(
id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
97 if ([aString isKindOfClass:[NSAttributedString
class]]) {
98 aString = [aString string];
101 if ([aString
length] == 0) {
106 if (_markedText != aString) {
107 [_markedText release];
108 _markedText = [aString retain];
111 _selectedRange = selectedRange;
112 _markedRange = NSMakeRange(0, [aString
length]);
115 (
int) selectedRange.location, (
int) selectedRange.length);
117 DEBUG_IME(
@"setMarkedText: %@, (%d, %d)", _markedText,
118 selRange.location, selRange.length);
123 [_markedText release];
129 - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
131 NSWindow *
window = [
self window];
132 NSRect contentRect = [window contentRectForFrameRect:[window frame]];
133 float windowHeight = contentRect.size.height;
134 NSRect
rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h,
135 _inputRect.w, _inputRect.h);
138 *actualRange = aRange;
141 DEBUG_IME(
@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@",
142 aRange.location, aRange.length, windowHeight,
143 NSStringFromRect(
rect));
145 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
146 if (![
window respondsToSelector:
@selector(convertRectToScreen:)]) {
147 rect.origin = [window convertBaseToScreen:rect.origin];
151 rect = [window convertRectToScreen:rect];
157 - (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
159 DEBUG_IME(
@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length);
163 - (NSInteger)conversationIdentifier
165 return (NSInteger)
self;
171 - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
173 DEBUG_IME(
@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y);
182 - (NSArray *)validAttributesForMarkedText
184 return [NSArray array];
195 HandleNonDeviceModifier(
unsigned int device_independent_mask,
196 unsigned int oldMods,
197 unsigned int newMods,
200 unsigned int oldMask, newMask;
205 oldMask = oldMods & device_independent_mask;
206 newMask = newMods & device_independent_mask;
208 if (oldMask && oldMask != newMask) {
210 }
else if (newMask && oldMask != newMask) {
219 HandleModifierOneSide(
unsigned int oldMods,
unsigned int newMods,
221 unsigned int sided_device_dependent_mask)
223 unsigned int old_dep_mask, new_dep_mask;
228 old_dep_mask = oldMods & sided_device_dependent_mask;
229 new_dep_mask = newMods & sided_device_dependent_mask;
235 if (new_dep_mask && old_dep_mask != new_dep_mask) {
247 HandleModifierSide(
int device_independent_mask,
248 unsigned int oldMods,
unsigned int newMods,
251 unsigned int left_device_dependent_mask,
252 unsigned int right_device_dependent_mask)
254 unsigned int device_dependent_mask = (left_device_dependent_mask |
255 right_device_dependent_mask);
256 unsigned int diff_mod;
262 if ((device_dependent_mask & newMods) == 0) {
264 HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
269 diff_mod = (device_dependent_mask & oldMods) ^
270 (device_dependent_mask & newMods);
276 if (left_device_dependent_mask & diff_mod) {
277 HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
279 if (right_device_dependent_mask & diff_mod) {
280 HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
291 ReleaseModifierSide(
unsigned int device_independent_mask,
292 unsigned int oldMods,
unsigned int newMods,
295 unsigned int left_device_dependent_mask,
296 unsigned int right_device_dependent_mask)
298 unsigned int device_dependent_mask = (left_device_dependent_mask |
299 right_device_dependent_mask);
305 if ((device_dependent_mask & oldMods) == 0) {
319 if ( left_device_dependent_mask & oldMods ) {
322 if ( right_device_dependent_mask & oldMods ) {
331 DoSidedModifiers(
unsigned short scancode,
332 unsigned int oldMods,
unsigned int newMods)
350 const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
351 const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
356 for (
i = 0, bit = NSEventModifierFlagShift; bit <= NSEventModifierFlagCommand; bit <<= 1, ++
i) {
357 unsigned int oldMask, newMask;
359 oldMask = oldMods & bit;
360 newMask = newMods & bit;
366 HandleModifierSide(bit, oldMods, newMods,
367 left_mapping[
i], right_mapping[
i],
368 left_device_mapping[
i], right_device_mapping[
i]);
373 else if (oldMask && oldMask != newMask) {
374 ReleaseModifierSide(bit, oldMods, newMods,
375 left_mapping[
i], right_mapping[
i],
376 left_device_mapping[
i], right_device_mapping[
i]);
382 HandleModifiers(
_THIS,
unsigned short scancode,
unsigned int modifierFlags)
386 if (modifierFlags ==
data->modifierFlags) {
390 DoSidedModifiers(scancode,
data->modifierFlags, modifierFlags);
391 data->modifierFlags = modifierFlags;
397 TISInputSourceRef key_layout;
398 const void *chr_data;
404 key_layout = TISCopyCurrentKeyboardLayoutInputSource();
405 if (key_layout ==
data->key_layout) {
408 data->key_layout = key_layout;
413 CFDataRef uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData);
415 chr_data = CFDataGetBytePtr(uchrDataRef);
421 UInt32 keyboard_type = LMGetKbdType();
427 UInt32 dead_key_state;
437 err = UCKeyTranslate ((UCKeyboardLayout *) chr_data,
440 kUCKeyTranslateNoDeadKeysMask,
441 &dead_key_state, 8, &
len,
s);
446 if (
len > 0 &&
s[0] != 0x10) {
447 keymap[scancode] =
s[0];
458 CFRelease(key_layout);
476 data->modifierFlags = (
unsigned int)[NSEvent modifierFlags];
486 NSWindow *nswindow = nil;
491 NSView *parentView = [nswindow contentView];
498 if (!
data->fieldEdit) {
500 [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
503 if (![[
data->fieldEdit superview] isEqual:parentView]) {
505 [data->fieldEdit removeFromSuperview];
506 [parentView addSubview: data->fieldEdit];
507 [nswindow makeFirstResponder: data->fieldEdit];
518 [data->fieldEdit removeFromSuperview];
519 [data->fieldEdit release];
520 data->fieldEdit = nil;
534 [data->fieldEdit setInputRect:rect];
545 unsigned short scancode = [event keyCode];
551 if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
553 scancode = 60 - scancode;
564 case NSEventTypeKeyDown:
565 if (![
event isARepeat]) {
573 fprintf(stderr,
"The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
578 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
580 text = [[event characters] UTF8String];
583 [data->fieldEdit setString:@""];
588 case NSEventTypeKeyUp:
591 case NSEventTypeFlagsChanged:
593 HandleModifiers(
_this, scancode, (
unsigned int)[
event modifierFlags]);
void Cocoa_QuitKeyboard(_THIS)
void Cocoa_StartTextInput(_THIS)
void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
void Cocoa_InitKeyboard(_THIS)
void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
void Cocoa_StopTextInput(_THIS)
static const NSUInteger NSEventModifierFlagCapsLock
#define SDL_GetKeyboardFocus
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
#define SDL_InvalidParamError(param)
int SDL_SendKeymapChangedEvent(void)
void SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
void SDL_GetDefaultKeymap(SDL_Keycode *keymap)
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
void SDL_SetKeymap(int start, SDL_Keycode *keys, int length)
int SDL_SendEditingText(const char *text, int start, int length)
int SDL_SendKeyboardText(const char *text)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
#define SDLK_SCANCODE_MASK
Sint32 SDL_Keycode
The SDL virtual key representation.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLuint GLuint GLsizei GLenum type
GLuint GLsizei GLsizei * length
SDL_Scancode
The SDL keyboard scancode representation.
#define SDL_arraysize(array)
static SDL_VideoDevice * _this
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)
EGLSurface EGLNativeWindowType * window
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
static const SDL_Scancode darwin_scancode_table[]
A rectangle, with the origin at the upper left (integer).
The type used to identify a window.
static char text[MAX_TEXT_LENGTH]
typedef int(__stdcall *FARPROC)()