1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "WKTextInputWindowController.h" 28 29#import <WebKitSystemInterface.h> 30 31@interface WKTextInputPanel : NSPanel { 32 NSTextView *_inputTextView; 33} 34 35- (NSTextInputContext *)_inputContext; 36- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string; 37 38@end 39 40#define inputWindowHeight 20 41 42@implementation WKTextInputPanel 43 44- (void)dealloc 45{ 46 [[NSNotificationCenter defaultCenter] removeObserver:self]; 47 48 [_inputTextView release]; 49 50 [super dealloc]; 51} 52 53- (id)init 54{ 55 self = [super initWithContentRect:NSZeroRect styleMask:WKGetInputPanelWindowStyle() backing:NSBackingStoreBuffered defer:YES]; 56 if (!self) 57 return nil; 58 59 // Set the frame size. 60 NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame]; 61 NSRect frame = NSMakeRect(visibleFrame.origin.x, visibleFrame.origin.y, visibleFrame.size.width, inputWindowHeight); 62 63 [self setFrame:frame display:NO]; 64 65 _inputTextView = [[NSTextView alloc] initWithFrame:[self.contentView frame]]; 66 _inputTextView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable | NSViewMaxXMargin | NSViewMinXMargin | NSViewMaxYMargin | NSViewMinYMargin; 67 68 NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[self.contentView frame]]; 69 scrollView.documentView = _inputTextView; 70 self.contentView = scrollView; 71 [scrollView release]; 72 73 [self setFloatingPanel:YES]; 74 75 return self; 76} 77 78- (void)_keyboardInputSourceChanged 79{ 80 [_inputTextView setString:@""]; 81 [self orderOut:nil]; 82} 83 84- (BOOL)_interpretKeyEvent:(NSEvent *)event string:(NSString **)string 85{ 86 BOOL hadMarkedText = [_inputTextView hasMarkedText]; 87 88 *string = nil; 89 90 // Let TSM know that a bottom input window would be created for marked text. 91 EventRef carbonEvent = static_cast<EventRef>(const_cast<void*>([event eventRef])); 92 if (carbonEvent) { 93 Boolean ignorePAH = true; 94 SetEventParameter(carbonEvent, 'iPAH', typeBoolean, sizeof(ignorePAH), &ignorePAH); 95 } 96 97 if (![[_inputTextView inputContext] handleEvent:event]) 98 return NO; 99 100 if ([_inputTextView hasMarkedText]) { 101 // Don't show the input method window for dead keys 102 if ([[event characters] length] > 0) 103 [self orderFront:nil]; 104 105 return YES; 106 } 107 108 if (hadMarkedText) { 109 [self orderOut:nil]; 110 111 NSString *text = [[_inputTextView textStorage] string]; 112 if ([text length] > 0) 113 *string = [[text copy] autorelease]; 114 } 115 116 [_inputTextView setString:@""]; 117 return hadMarkedText; 118} 119 120- (NSTextInputContext *)_inputContext 121{ 122 return [_inputTextView inputContext]; 123} 124 125@end 126 127@implementation WKTextInputWindowController 128 129+ (WKTextInputWindowController *)sharedTextInputWindowController 130{ 131 static WKTextInputWindowController *textInputWindowController; 132 if (!textInputWindowController) 133 textInputWindowController = [[WKTextInputWindowController alloc] init]; 134 135 return textInputWindowController; 136} 137 138- (id)init 139{ 140 self = [super init]; 141 if (!self) 142 return nil; 143 144 _panel = [[WKTextInputPanel alloc] init]; 145 146 return self; 147} 148 149- (NSTextInputContext *)inputContext 150{ 151 return [_panel _inputContext]; 152} 153 154- (BOOL)interpretKeyEvent:(NSEvent *)event string:(NSString **)string 155{ 156 return [_panel _interpretKeyEvent:event string:string]; 157} 158 159- (void)keyboardInputSourceChanged 160{ 161 [_panel _keyboardInputSourceChanged]; 162} 163 164@end 165