7# import <Carbon/Carbon.h>
25 GHOST_ImeStateFlagCocoa state_flag;
26 NSRect candidate_window_position;
31 std::string composite;
32 std::string combined_result;
42 frame:(NSRect)frameRect;
54@synthesize systemCocoa = m_systemCocoa;
55@synthesize windowCocoa = m_windowCocoa;
59 frame:(NSRect)frameRect
64 m_systemCocoa = sysCocoa;
65 m_windowCocoa = winCocoa;
72 ime.candidate_window_position = NSZeroRect;
73 ime.event.cursor_position = -1;
74 ime.event.target_start = -1;
75 ime.event.target_end = -1;
80 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
81 [center addObserver:self
82 selector:@selector(ImeDidChangeCallback:)
83 name:NSTextInputContextKeyboardSelectionDidChangeNotification
92- (BOOL)acceptsFirstResponder
97- (
BOOL)acceptsFirstMouse:(NSEvent *)event
103- (void)keyDown:(NSEvent *)event
106 [
self checkKeyCodeIsControlChar:event];
107 const bool ime_process = [
self isProcessedByIme];
109 const bool ime_process =
false;
113 m_systemCocoa->handleKeyEvent(event);
117 if ([[event characters] length] == 0 || [[event charactersIgnoringModifiers] length] == 0 ||
118 composing || ime_process)
124 [
self interpretKeyEvents:[NSArray arrayWithObject:event]];
129 const int controlCharForKorean = (GHOST_IME_COMPOSITION_EVENT | GHOST_IME_RESULT_EVENT |
130 GHOST_IME_KEY_CONTROL_CHAR);
131 if (((ime.state_flag & controlCharForKorean) == controlCharForKorean)) {
132 m_systemCocoa->handleKeyEvent(event);
135 ime.state_flag &= ~(GHOST_IME_COMPOSITION_EVENT | GHOST_IME_RESULT_EVENT);
137 ime.combined_result.clear();
144#define HANDLE_KEY_EVENT(eventType) \
145 -(void)eventType : (NSEvent *)event \
147 m_systemCocoa->handleKeyEvent(event); \
150#define HANDLE_MOUSE_EVENT(eventType) \
151 -(void)eventType : (NSEvent *)event \
153 m_systemCocoa->handleMouseEvent(event); \
156#define HANDLE_TABLET_EVENT(eventType) \
157 -(void)eventType : (NSEvent *)event \
159 m_systemCocoa->handleMouseEvent(event); \
188- (void)drawRect:(NSRect)rect
190 if ([
self inLiveResize]) {
194 [
super drawRect:rect];
199 if (m_windowCocoa->getImmediateDraw()) {
200 m_systemCocoa->dispatchEvents();
207- (void)composing_free
211 if (composing_text) {
212 [composing_text release];
218- (void)insertText:(
id)chars replacementRange:(NSRange)replacementRange
220 [
self composing_free];
223 if (ime.state_flag & GHOST_IME_ENABLED) {
224 if (!(ime.state_flag & GHOST_IME_COMPOSING)) {
225 [
self processImeEvent:GHOST_kEventImeCompositionStart];
229 if (ime.state_flag & GHOST_IME_RESULT_EVENT) {
230 ime.combined_result += [
self convertNSString:chars];
233 ime.combined_result = [
self convertNSString:chars];
236 [
self setImeResult:ime.combined_result];
240 if (![
self ime_did_composition]) {
241 [
self processImeEvent:GHOST_kEventImeComposition];
243 ime.state_flag |= GHOST_IME_RESULT_EVENT;
245 [
self processImeEvent:GHOST_kEventImeCompositionEnd];
246 ime.state_flag &= ~GHOST_IME_COMPOSING;
252- (void)setMarkedText:(
id)chars
253 selectedRange:(NSRange)range
254 replacementRange:(NSRange)replacementRange
256 [
self composing_free];
258 if ([chars length] == 0) {
261 if (ime.state_flag & GHOST_IME_COMPOSING) {
262 [
self setImeResult:std::string()];
263 [
self processImeEvent:GHOST_kEventImeComposition];
264 [
self processImeEvent:GHOST_kEventImeCompositionEnd];
265 ime.state_flag &= ~GHOST_IME_COMPOSING;
277 if ([chars isKindOfClass:[NSAttributedString class]]) {
282 if ([composing_text length] == 0) {
283 [
self composing_free];
287 if (ime.state_flag & GHOST_IME_ENABLED) {
288 if (!(ime.state_flag & GHOST_IME_COMPOSING)) {
289 ime.state_flag |= GHOST_IME_COMPOSING;
290 [
self processImeEvent:GHOST_kEventImeCompositionStart];
293 [
self setImeComposition:composing_text selectedRange:range];
296 if (![
self ime_did_composition]) {
297 ime.state_flag |= GHOST_IME_COMPOSITION_EVENT;
298 [
self processImeEvent:GHOST_kEventImeComposition];
306 [
self composing_free];
311 return (composing) ? YES : NO;
314- (void)doCommandBySelector:(
SEL)selector
323- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range
324 actualRange:(NSRangePointer)actualRange
326 return [[[NSAttributedString alloc] init] autorelease];
329- (NSRange)markedRange
331 unsigned int length = (
composing_text) ? [composing_text length] : 0;
334 return NSMakeRange(0, length);
337 return NSMakeRange(NSNotFound, 0);
340- (NSRange)selectedRange
342 unsigned int length = (
composing_text) ? [composing_text length] : 0;
343 return NSMakeRange(0, length);
347- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange
350 if (ime.state_flag & GHOST_IME_ENABLED) {
351 return ime.candidate_window_position;
357- (NSUInteger)characterIndexForPoint:(NSPoint)point
362- (NSArray *)validAttributesForMarkedText
364 return [NSArray array];
368- (void)checkImeEnabled
370 ime.state_flag &= ~GHOST_IME_ENABLED;
372 if (ime.state_flag & GHOST_IME_INPUT_FOCUSED) {
375 TISInputSourceRef currentKeyboardInputSource = TISCopyCurrentKeyboardInputSource();
376 bool ime_enabled = !CFBooleanGetValue((CFBooleanRef)TISGetInputSourceProperty(
377 currentKeyboardInputSource, kTISPropertyInputSourceIsASCIICapable));
378 CFRelease(currentKeyboardInputSource);
381 ime.state_flag |= GHOST_IME_ENABLED;
388- (void)ImeDidChangeCallback:(NSNotification *)notification
390 [
self checkImeEnabled];
396 m_windowCocoa->clientToScreen(x, y, outX, outY);
397 ime.candidate_window_position = NSMakeRect((CGFloat)outX, (CGFloat)outY, (CGFloat)
w, (CGFloat)h);
402 ime.state_flag |= GHOST_IME_INPUT_FOCUSED;
403 [
self checkImeEnabled];
404 [
self setImeCandidateWinPos:x y:y w:w h:h];
411 ime.composite.clear();
415 [[NSTextInputContext currentInputContext] discardMarkedText];
427 m_systemCocoa->getMilliSeconds(), imeEventType, m_windowCocoa, &ime.event);
428 m_systemCocoa->pushEvent(event);
431- (std::string)convertNSString:(NSString *)inString
434 std::string
str(inString.UTF8String);
439- (void)setImeComposition:(NSString *)inString selectedRange:(NSRange)range
441 ime.composite = [
self convertNSString:inString];
445 if (!(ime.state_flag & GHOST_IME_RESULT_EVENT)) {
452 char *front_string = (
char *)[[inString substringWithRange:NSMakeRange(0, range.location)]
454 char *selected_string = (
char *)[[inString substringWithRange:range] UTF8String];
455 ime.event.cursor_position = strlen(front_string);
456 ime.event.target_start = ime.event.cursor_position;
457 ime.event.target_end = ime.event.target_start + strlen(selected_string);
461- (void)setImeResult:(std::
string)result
464 ime.composite.clear();
465 ime.event.cursor_position = -1;
466 ime.event.target_start = -1;
467 ime.event.target_end = -1;
470- (void)checkKeyCodeIsControlChar:(NSEvent *)event
472 ime.state_flag &= ~GHOST_IME_KEY_CONTROL_CHAR;
475 if (event.modifierFlags & (NSEventModifierFlagCommand | NSEventModifierFlagControl)) {
476 ime.state_flag |= GHOST_IME_KEY_CONTROL_CHAR;
481 switch (event.keyCode) {
482 case kVK_ANSI_KeypadEnter:
483 case kVK_ANSI_KeypadClear:
510 case kVK_ForwardDelete:
520 ime.state_flag |= GHOST_IME_KEY_CONTROL_CHAR;
525- (bool)ime_did_composition
527 return (ime.state_flag & GHOST_IME_COMPOSITION_EVENT) ||
528 (ime.state_flag & GHOST_IME_RESULT_EVENT);
533- (bool)isProcessedByIme
536 (ime.state_flag & GHOST_IME_ENABLED) &&
537 ((ime.state_flag & GHOST_IME_COMPOSING) || !(ime.state_flag & GHOST_IME_KEY_CONTROL_CHAR)));
void * GHOST_TUserDataPtr
@ GHOST_kEventWindowUpdate
#define HANDLE_KEY_EVENT(eventType)
#define HANDLE_TABLET_EVENT(eventType)
#define HANDLE_MOUSE_EVENT(eventType)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
NSString * composing_text