Mercurial > sdl-ios-xcode
comparison src/video/cocoa/SDL_cocoakeyboard.m @ 3280:00cace2d9080
Merged a cleaned up version of Jiang's code changes from Google Summer of Code 2009
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 19 Sep 2009 13:29:40 +0000 |
parents | 2dcfb4e07a57 |
children | d390778b59c1 |
comparison
equal
deleted
inserted
replaced
3279:fd207dce9f94 | 3280:00cace2d9080 |
---|---|
26 #include "../../events/SDL_keyboard_c.h" | 26 #include "../../events/SDL_keyboard_c.h" |
27 #include "../../events/scancodes_darwin.h" | 27 #include "../../events/scancodes_darwin.h" |
28 | 28 |
29 #include <Carbon/Carbon.h> | 29 #include <Carbon/Carbon.h> |
30 | 30 |
31 //#define DEBUG_IME NSLog | |
32 #define DEBUG_IME | |
31 | 33 |
32 #ifndef NX_DEVICERCTLKEYMASK | 34 #ifndef NX_DEVICERCTLKEYMASK |
33 #define NX_DEVICELCTLKEYMASK 0x00000001 | 35 #define NX_DEVICELCTLKEYMASK 0x00000001 |
34 #endif | 36 #endif |
35 #ifndef NX_DEVICELSHIFTKEYMASK | 37 #ifndef NX_DEVICELSHIFTKEYMASK |
52 #endif | 54 #endif |
53 #ifndef NX_DEVICERCTLKEYMASK | 55 #ifndef NX_DEVICERCTLKEYMASK |
54 #define NX_DEVICERCTLKEYMASK 0x00002000 | 56 #define NX_DEVICERCTLKEYMASK 0x00002000 |
55 #endif | 57 #endif |
56 | 58 |
57 @interface SDLTranslatorResponder : NSTextView | 59 @interface SDLTranslatorResponder : NSView <NSTextInput> |
58 { | 60 { |
61 NSString *_markedText; | |
62 NSRange _markedRange; | |
63 NSRange _selectedRange; | |
64 SDL_Rect _inputRect; | |
65 int _keyboard; | |
59 } | 66 } |
60 - (void) doCommandBySelector:(SEL)myselector; | 67 - (void) doCommandBySelector:(SEL)myselector; |
68 - (void) setInputRect:(SDL_Rect *) rect; | |
69 - (void) setKeyboard:(int) keyboard; | |
61 @end | 70 @end |
62 | 71 |
63 @implementation SDLTranslatorResponder | 72 @implementation SDLTranslatorResponder |
64 - (void) doCommandBySelector:(SEL) myselector {} | 73 |
74 - (void) setKeyboard:(int) keyboard | |
75 { | |
76 _keyboard = keyboard; | |
77 } | |
78 | |
79 - (void) setInputRect:(SDL_Rect *) rect | |
80 { | |
81 _inputRect = *rect; | |
82 } | |
83 | |
84 - (void) insertText:(id) aString | |
85 { | |
86 const char *str; | |
87 | |
88 DEBUG_IME(@"insertText: %@", aString); | |
89 | |
90 /* Could be NSString or NSAttributedString, so we have | |
91 * to test and convert it before return as SDL event */ | |
92 if ([aString isKindOfClass: [NSAttributedString class]]) | |
93 str = [[aString string] UTF8String]; | |
94 else | |
95 str = [aString UTF8String]; | |
96 | |
97 SDL_SendKeyboardText(_keyboard, str); | |
98 } | |
99 | |
100 - (void) doCommandBySelector:(SEL) myselector | |
101 { | |
102 [super doCommandBySelector: myselector]; | |
103 } | |
104 | |
105 - (BOOL) hasMarkedText | |
106 { | |
107 return _markedText != nil; | |
108 } | |
109 | |
110 - (NSRange) markedRange | |
111 { | |
112 return _markedRange; | |
113 } | |
114 | |
115 - (NSRange) selectedRange | |
116 { | |
117 return _selectedRange; | |
118 } | |
119 | |
120 - (void) setMarkedText:(id) aString | |
121 selectedRange:(NSRange) selRange | |
122 { | |
123 if ([aString isKindOfClass: [NSAttributedString class]]) | |
124 aString = [aString string]; | |
125 | |
126 if ([aString length] == 0) | |
127 { | |
128 [self unmarkText]; | |
129 return; | |
130 } | |
131 | |
132 if (_markedText != aString) | |
133 { | |
134 [_markedText release]; | |
135 _markedText = [aString retain]; | |
136 } | |
137 | |
138 _selectedRange = selRange; | |
139 _markedRange = NSMakeRange(0, [aString length]); | |
140 | |
141 SDL_SendEditingText([aString UTF8String], selRange.location, selRange.length); | |
142 | |
143 DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText, | |
144 selRange.location, selRange.length); | |
145 } | |
146 | |
147 - (void) unmarkText | |
148 { | |
149 [_markedText release]; | |
150 _markedText = nil; | |
151 } | |
152 | |
153 - (NSRect) firstRectForCharacterRange: (NSRange) theRange | |
154 { | |
155 float windowHeight = [[self window] frame].size.height; | |
156 NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h, | |
157 _inputRect.w, _inputRect.h); | |
158 | |
159 DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@", | |
160 theRange.location, theRange.length, windowHeight, | |
161 NSStringFromRect(rect)); | |
162 rect.origin = [[self window] convertBaseToScreen: rect.origin]; | |
163 | |
164 return rect; | |
165 } | |
166 | |
167 - (NSAttributedString *) attributedSubstringFromRange: (NSRange) theRange | |
168 { | |
169 DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", theRange.location, theRange.length); | |
170 return nil; | |
171 } | |
172 | |
173 - (NSInteger) conversationIdentifier | |
174 { | |
175 return (NSInteger) self; | |
176 } | |
177 | |
178 // This method returns the index for character that is | |
179 // nearest to thePoint. thPoint is in screen coordinate system. | |
180 - (NSUInteger) characterIndexForPoint:(NSPoint) thePoint | |
181 { | |
182 DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y); | |
183 return 0; | |
184 } | |
185 | |
186 // This method is the key to attribute extension. | |
187 // We could add new attributes through this method. | |
188 // NSInputServer examines the return value of this | |
189 // method & constructs appropriate attributed string. | |
190 - (NSArray *) validAttributesForMarkedText | |
191 { | |
192 return [NSArray array]; | |
193 } | |
194 | |
65 @end | 195 @end |
66 | 196 |
67 /* This is the original behavior, before support was added for | 197 /* This is the original behavior, before support was added for |
68 * differentiating between left and right versions of the keys. | 198 * differentiating between left and right versions of the keys. |
69 */ | 199 */ |
476 void | 606 void |
477 Cocoa_InitKeyboard(_THIS) | 607 Cocoa_InitKeyboard(_THIS) |
478 { | 608 { |
479 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | 609 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; |
480 SDL_Keyboard keyboard; | 610 SDL_Keyboard keyboard; |
481 NSAutoreleasePool *pool; | 611 |
482 | |
483 pool = [[NSAutoreleasePool alloc] init]; | |
484 data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; | |
485 [pool release]; | |
486 | |
487 SDL_zero(keyboard); | 612 SDL_zero(keyboard); |
488 data->keyboard = SDL_AddKeyboard(&keyboard, -1); | 613 data->keyboard = SDL_AddKeyboard(&keyboard, -1); |
489 UpdateKeymap(data); | 614 UpdateKeymap(data); |
490 | 615 |
491 /* Set our own names for the platform-dependent but layout-independent keys */ | 616 /* Set our own names for the platform-dependent but layout-independent keys */ |
496 SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option"); | 621 SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option"); |
497 SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); | 622 SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); |
498 } | 623 } |
499 | 624 |
500 void | 625 void |
626 Cocoa_StartTextInput(_THIS) | |
627 { | |
628 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | |
629 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | |
630 NSView *parentView = [[NSApp keyWindow] contentView]; | |
631 | |
632 data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; | |
633 [data->fieldEdit setKeyboard: data->keyboard]; | |
634 | |
635 if (! [[data->fieldEdit superview] isEqual: parentView]) | |
636 { | |
637 // DEBUG_IME(@"add fieldEdit to window contentView"); | |
638 [data->fieldEdit removeFromSuperview]; | |
639 [parentView addSubview: data->fieldEdit]; | |
640 [[NSApp keyWindow] makeFirstResponder: data->fieldEdit]; | |
641 } | |
642 | |
643 [pool release]; | |
644 } | |
645 | |
646 void | |
647 Cocoa_StopTextInput(_THIS) | |
648 { | |
649 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | |
650 | |
651 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | |
652 [data->fieldEdit removeFromSuperview]; | |
653 [data->fieldEdit release]; | |
654 data->fieldEdit = nil; | |
655 [pool release]; | |
656 } | |
657 | |
658 void | |
659 Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect) | |
660 { | |
661 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | |
662 | |
663 [data->fieldEdit setInputRect: rect]; | |
664 } | |
665 | |
666 void | |
501 Cocoa_HandleKeyEvent(_THIS, NSEvent *event) | 667 Cocoa_HandleKeyEvent(_THIS, NSEvent *event) |
502 { | 668 { |
503 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | 669 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; |
504 unsigned short scancode = [event keyCode]; | 670 unsigned short scancode = [event keyCode]; |
505 SDL_scancode code; | 671 SDL_scancode code; |
531 #endif | 697 #endif |
532 } | 698 } |
533 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { | 699 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { |
534 /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ | 700 /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ |
535 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; | 701 [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; |
702 #if 0 | |
536 text = [[event characters] UTF8String]; | 703 text = [[event characters] UTF8String]; |
537 if(text && *text) { | 704 if(text && *text) { |
538 SDL_SendKeyboardText(data->keyboard, text); | 705 SDL_SendKeyboardText(data->keyboard, text); |
539 [data->fieldEdit setString:@""]; | 706 [data->fieldEdit setString:@""]; |
540 } | 707 } |
708 #endif | |
541 } | 709 } |
542 break; | 710 break; |
543 case NSKeyUp: | 711 case NSKeyUp: |
544 SDL_SendKeyboardKey(data->keyboard, SDL_RELEASED, code); | 712 SDL_SendKeyboardKey(data->keyboard, SDL_RELEASED, code); |
545 break; | 713 break; |
557 { | 725 { |
558 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | 726 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; |
559 NSAutoreleasePool *pool; | 727 NSAutoreleasePool *pool; |
560 | 728 |
561 SDL_DelKeyboard(data->keyboard); | 729 SDL_DelKeyboard(data->keyboard); |
562 | |
563 pool = [[NSAutoreleasePool alloc] init]; | |
564 [data->fieldEdit release]; | |
565 [pool release]; | |
566 } | 730 } |
567 | 731 |
568 /* vi: set ts=4 sw=4 expandtab: */ | 732 /* vi: set ts=4 sw=4 expandtab: */ |