Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/awt/CInputMethod.m
38829 views
/*1* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#import <Cocoa/Cocoa.h>26#include <objc/objc-runtime.h>2728#import "sun_lwawt_macosx_CInputMethod.h"29#import "sun_lwawt_macosx_CInputMethodDescriptor.h"30#import "ThreadUtilities.h"31#import "AWTView.h"3233#import <JavaNativeFoundation/JavaNativeFoundation.h>34#import <JavaRuntimeSupport/JavaRuntimeSupport.h>3536#define JAVA_LIST @"JAVA_LIST"37#define CURRENT_KB_DESCRIPTION @"CURRENT_KB_DESCRIPTION"3839static JNF_CLASS_CACHE(jc_localeClass, "java/util/Locale");40static JNF_CTOR_CACHE(jm_localeCons, jc_localeClass, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");41static JNF_CLASS_CACHE(jc_arrayListClass, "java/util/ArrayList");42static JNF_CTOR_CACHE(jm_arrayListCons, jc_arrayListClass, "()V");43static JNF_MEMBER_CACHE(jm_listAdd, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z");44static JNF_MEMBER_CACHE(jm_listContains, jc_arrayListClass, "contains", "(Ljava/lang/Object;)Z");45464748//49// NOTE: This returns a JNI Local Ref. Any code that calls must call DeleteLocalRef with the return value.50//51static jobject CreateLocaleObjectFromNSString(JNIEnv *env, NSString *name)52{53// Break apart the string into its components.54// First, duplicate the NSString into a C string, since we're going to modify it.55char * language = strdup([name UTF8String]);56char * country;57char * variant;5859// Convert _ to NULL -- this gives us three null terminated strings in place.60for (country = language; *country != '_' && *country != '\0'; country++);61if (*country == '_') {62*country++ = '\0';63for (variant = country; *variant != '_' && *variant != '\0'; variant++);64if (*variant == '_') {65*variant++ = '\0';66}67} else {68variant = country;69}7071// Create the java.util.Locale object72jobject localeObj = NULL;73jobject langObj = (*env)->NewStringUTF(env, language);74if (langObj != NULL) {75jobject ctryObj = (*env)->NewStringUTF(env, country);76if(ctryObj != NULL) {77jobject vrntObj = (*env)->NewStringUTF(env, variant);78if (vrntObj != NULL) {79localeObj = JNFNewObject(env, jm_localeCons,langObj, ctryObj,80vrntObj);81(*env)->DeleteLocalRef(env, vrntObj);82}83(*env)->DeleteLocalRef(env, ctryObj);84}85(*env)->DeleteLocalRef(env, langObj);86}87// Clean up and return.88free(language);89return localeObj;90}9192static id inputMethodController = nil;9394static void initializeInputMethodController() {95static BOOL checkedJRSInputMethodController = NO;96if (!checkedJRSInputMethodController && (inputMethodController == nil)) {97id jrsInputMethodController = objc_lookUpClass("JRSInputMethodController");98if (jrsInputMethodController != nil) {99inputMethodController = [jrsInputMethodController performSelector:@selector(controller)];100}101checkedJRSInputMethodController = YES;102}103}104105106@interface CInputMethod : NSObject {}107@end108109@implementation CInputMethod110111+ (void) setKeyboardLayout:(NSString *)theLocale112{113AWT_ASSERT_APPKIT_THREAD;114if (!inputMethodController) return;115116[inputMethodController performSelector:@selector(setCurrentInputMethodForLocale) withObject:theLocale];117}118119+ (void) _nativeNotifyPeerWithView:(AWTView *)view inputMethod:(JNFJObjectWrapper *) inputMethod {120AWT_ASSERT_APPKIT_THREAD;121122if (!view) return;123if (!inputMethod) return;124125[view setInputMethod:[inputMethod jObject]];126}127128+ (void) _nativeEndComposition:(AWTView *)view {129if (view == nil) return;130131[view abandonInput];132}133134135@end136137/*138* Class: sun_lwawt_macosx_CInputMethod139* Method: nativeInit140* Signature: ();141*/142JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeInit143(JNIEnv *env, jclass klass)144{145initializeInputMethodController();146}147148/*149* Class: sun_lwawt_macosx_CInputMethod150* Method: nativeGetCurrentInputMethodInfo151* Signature: ()Ljava/lang/String;152*/153JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeGetCurrentInputMethodInfo154(JNIEnv *env, jclass klass)155{156if (!inputMethodController) return NULL;157jobject returnValue = 0;158__block NSString *keyboardInfo = NULL;159JNF_COCOA_ENTER(env);160161[ThreadUtilities performOnMainThreadWaiting:YES block:^(){162keyboardInfo = [inputMethodController performSelector:@selector(currentInputMethodName)];163[keyboardInfo retain];164}];165166if (keyboardInfo == nil) return NULL;167returnValue = JNFNSToJavaString(env, keyboardInfo);168[keyboardInfo release];169170JNF_COCOA_EXIT(env);171return returnValue;172}173174/*175* Class: sun_lwawt_macosx_CInputMethod176* Method: nativeActivate177* Signature: (JLsun/lwawt/macosx/CInputMethod;)V178*/179JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeNotifyPeer180(JNIEnv *env, jobject this, jlong nativePeer, jobject inputMethod)181{182JNF_COCOA_ENTER(env);183AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);184JNFJObjectWrapper *inputMethodWrapper = [[JNFJObjectWrapper alloc] initWithJObject:inputMethod withEnv:env];185[ThreadUtilities performOnMainThreadWaiting:NO block:^(){186[CInputMethod _nativeNotifyPeerWithView:view inputMethod:inputMethodWrapper];187}];188189JNF_COCOA_EXIT(env);190191}192193/*194* Class: sun_lwawt_macosx_CInputMethod195* Method: nativeEndComposition196* Signature: (J)V197*/198JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition199(JNIEnv *env, jobject this, jlong nativePeer)200{201JNF_COCOA_ENTER(env);202AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);203204[ThreadUtilities performOnMainThreadWaiting:NO block:^(){205[CInputMethod _nativeEndComposition:view];206}];207208JNF_COCOA_EXIT(env);209}210211/*212* Class: sun_lwawt_macosx_CInputMethod213* Method: getNativeLocale214* Signature: ()Ljava/util/Locale;215*/216JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_getNativeLocale217(JNIEnv *env, jobject this)218{219if (!inputMethodController) return NULL;220jobject returnValue = 0;221__block NSString *isoAbbreviation;222JNF_COCOA_ENTER(env);223224[ThreadUtilities performOnMainThreadWaiting:YES block:^(){225isoAbbreviation = (NSString *) [inputMethodController performSelector:@selector(currentInputMethodLocale)];226[isoAbbreviation retain];227}];228229if (isoAbbreviation == nil) return NULL;230231static NSString *sLastKeyboardStr = nil;232static jobject sLastKeyboardLocaleObj = NULL;233234if (![isoAbbreviation isEqualTo:sLastKeyboardStr]) {235[sLastKeyboardStr release];236sLastKeyboardStr = [isoAbbreviation retain];237jobject localObj = CreateLocaleObjectFromNSString(env, isoAbbreviation);238[isoAbbreviation release];239240if (sLastKeyboardLocaleObj) {241JNFDeleteGlobalRef(env, sLastKeyboardLocaleObj);242sLastKeyboardLocaleObj = NULL;243}244if (localObj != NULL) {245sLastKeyboardLocaleObj = JNFNewGlobalRef(env, localObj);246(*env)->DeleteLocalRef(env, localObj);247}248}249250returnValue = sLastKeyboardLocaleObj;251252JNF_COCOA_EXIT(env);253return returnValue;254}255256257/*258* Class: sun_lwawt_macosx_CInputMethod259* Method: setNativeLocale260* Signature: (Ljava/lang/String;Z)Z261*/262JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CInputMethod_setNativeLocale263(JNIEnv *env, jobject this, jstring locale, jboolean isActivating)264{265JNF_COCOA_ENTER(env);266NSString *localeStr = JNFJavaToNSString(env, locale);267[localeStr retain];268269[ThreadUtilities performOnMainThreadWaiting:YES block:^(){270[CInputMethod setKeyboardLayout:localeStr];271}];272273[localeStr release];274JNF_COCOA_EXIT(env);275return JNI_TRUE;276}277278/*279* Class: sun_lwawt_macosx_CInputMethodDescriptor280* Method: nativeInit281* Signature: ();282*/283JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeInit284(JNIEnv *env, jclass klass)285{286initializeInputMethodController();287}288289/*290* Class: sun_lwawt_macosx_CInputMethodDescriptor291* Method: nativeGetAvailableLocales292* Signature: ()[Ljava/util/Locale;293*/294JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeGetAvailableLocales295(JNIEnv *env, jclass klass)296{297if (!inputMethodController) return NULL;298jobject returnValue = 0;299300__block NSArray *selectableArray = nil;301JNF_COCOA_ENTER(env);302303[ThreadUtilities performOnMainThreadWaiting:YES block:^(){304selectableArray = (NSArray *)[inputMethodController performSelector:@selector(availableInputMethodLocales)];305[selectableArray retain];306}];307308if (selectableArray == nil) return NULL;309310// Create an ArrayList to return back to the caller.311returnValue = JNFNewObject(env, jm_arrayListCons);312313for(NSString *locale in selectableArray) {314jobject localeObj = CreateLocaleObjectFromNSString(env, locale);315if (localeObj == NULL) {316break;317}318319if (JNFCallBooleanMethod(env, returnValue, jm_listContains, localeObj) == JNI_FALSE) {320JNFCallBooleanMethod(env, returnValue, jm_listAdd, localeObj);321}322323(*env)->DeleteLocalRef(env, localeObj);324}325[selectableArray release];326JNF_COCOA_EXIT(env);327return returnValue;328}329330331332