13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import <Cocoa/Cocoa.h>
27 #include <objc/objc-runtime.h>
28
29 #import "sun_lwawt_macosx_CInputMethod.h"
30 #import "sun_lwawt_macosx_CInputMethodDescriptor.h"
31 #import "ThreadUtilities.h"
32 #import "AWTView.h"
33
34 #import <JavaNativeFoundation/JavaNativeFoundation.h>
35 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
36
37 #define JAVA_LIST @"JAVA_LIST"
38 #define CURRENT_KB_DESCRIPTION @"CURRENT_KB_DESCRIPTION"
39
40 static JNF_CLASS_CACHE(jc_localeClass, "java/util/Locale");
41 static JNF_CTOR_CACHE(jm_localeCons, jc_localeClass, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
42 static JNF_CLASS_CACHE(jc_arrayListClass, "java/util/ArrayList");
43 static JNF_CTOR_CACHE(jm_arrayListCons, jc_arrayListClass, "()V");
44 static JNF_MEMBER_CACHE(jm_listAdd, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z");
45 static JNF_MEMBER_CACHE(jm_listContains, jc_arrayListClass, "contains", "(Ljava/lang/Object;)Z");
46
47
48
49 //
50 // NOTE: This returns a JNI Local Ref. Any code that calls must call DeleteLocalRef with the return value.
51 //
52 static jobject CreateLocaleObjectFromNSString(JNIEnv *env, NSString *name)
53 {
54 // Break apart the string into its components.
55 // First, duplicate the NSString into a C string, since we're going to modify it.
56 char * language = strdup([name UTF8String]);
57 char * country;
58 char * variant;
59
60 // Convert _ to NULL -- this gives us three null terminated strings in place.
61 for (country = language; *country != '_' && *country != '\0'; country++);
62 if (*country == '_') {
63 *country++ = '\0';
64 for (variant = country; *variant != '_' && *variant != '\0'; variant++);
65 if (*variant == '_') {
66 *variant++ = '\0';
67 }
68 } else {
69 variant = country;
70 }
71
72 // Create the java.util.Locale object
73 jobject localeObj = NULL;
74 jobject langObj = (*env)->NewStringUTF(env, language);
75 if (langObj != NULL) {
76 jobject ctryObj = (*env)->NewStringUTF(env, country);
77 if(ctryObj != NULL) {
78 jobject vrntObj = (*env)->NewStringUTF(env, variant);
79 if (vrntObj != NULL) {
80 localeObj = JNFNewObject(env, jm_localeCons,langObj, ctryObj,
81 vrntObj);
82 (*env)->DeleteLocalRef(env, vrntObj);
83 }
84 (*env)->DeleteLocalRef(env, ctryObj);
85 }
86 (*env)->DeleteLocalRef(env, langObj);
87 }
88 // Clean up and return.
89 free(language);
90 return localeObj;
91 }
92
93 static id inputMethodController = nil;
94
95 static void initializeInputMethodController() {
96 static BOOL checkedJRSInputMethodController = NO;
97 if (!checkedJRSInputMethodController && (inputMethodController == nil)) {
98 id jrsInputMethodController = objc_lookUpClass("JRSInputMethodController");
99 if (jrsInputMethodController != nil) {
100 inputMethodController = [jrsInputMethodController performSelector:@selector(controller)];
101 }
102 checkedJRSInputMethodController = YES;
103 }
104 }
105
106
107 @interface CInputMethod : NSObject {}
108 @end
109
110 @implementation CInputMethod
111
112 + (void) setKeyboardLayout:(NSString *)theLocale
113 {
114 AWT_ASSERT_APPKIT_THREAD;
115 if (!inputMethodController) return;
116
117 [inputMethodController performSelector:@selector(setCurrentInputMethodForLocale) withObject:theLocale];
118 }
119
120 + (void) _nativeNotifyPeerWithView:(AWTView *)view inputMethod:(JNFJObjectWrapper *) inputMethod {
121 AWT_ASSERT_APPKIT_THREAD;
122
123 if (!view) return;
124 if (!inputMethod) return;
125
126 [view setInputMethod:[inputMethod jObject]];
127 }
128
129 + (void) _nativeEndComposition:(AWTView *)view {
130 if (view == nil) return;
131
132 [view abandonInput];
133 }
134
135
136 @end
137
138 /*
139 * Class: sun_lwawt_macosx_CInputMethod
140 * Method: nativeInit
141 * Signature: ();
142 */
143 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeInit
144 (JNIEnv *env, jclass klass)
145 {
146 initializeInputMethodController();
147 }
148
149 /*
150 * Class: sun_lwawt_macosx_CInputMethod
151 * Method: nativeGetCurrentInputMethodInfo
152 * Signature: ()Ljava/lang/String;
153 */
154 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeGetCurrentInputMethodInfo
155 (JNIEnv *env, jclass klass)
156 {
157 if (!inputMethodController) return NULL;
158 jobject returnValue = 0;
159 __block NSString *keyboardInfo = NULL;
160 JNF_COCOA_ENTER(env);
161
162 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
163 keyboardInfo = [inputMethodController performSelector:@selector(currentInputMethodName)];
164 [keyboardInfo retain];
165 }];
166
167 if (keyboardInfo == nil) return NULL;
168 returnValue = JNFNSToJavaString(env, keyboardInfo);
169 [keyboardInfo release];
170
171 JNF_COCOA_EXIT(env);
172 return returnValue;
173 }
174
175 /*
176 * Class: sun_lwawt_macosx_CInputMethod
177 * Method: nativeActivate
178 * Signature: (JLsun/lwawt/macosx/CInputMethod;)V
179 */
180 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeNotifyPeer
181 (JNIEnv *env, jobject this, jlong nativePeer, jobject inputMethod)
182 {
183 JNF_COCOA_ENTER(env);
184 AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
185 JNFJObjectWrapper *inputMethodWrapper = [[JNFJObjectWrapper alloc] initWithJObject:inputMethod withEnv:env];
186 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
187 [CInputMethod _nativeNotifyPeerWithView:view inputMethod:inputMethodWrapper];
188 }];
189
190 JNF_COCOA_EXIT(env);
191
192 }
193
194 /*
195 * Class: sun_lwawt_macosx_CInputMethod
196 * Method: nativeEndComposition
197 * Signature: (J)V
198 */
199 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
200 (JNIEnv *env, jobject this, jlong nativePeer)
201 {
202 JNF_COCOA_ENTER(env);
203 AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
204
205 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
206 [CInputMethod _nativeEndComposition:view];
207 }];
208
209 JNF_COCOA_EXIT(env);
210 }
211
212 /*
213 * Class: sun_lwawt_macosx_CInputMethod
214 * Method: getNativeLocale
215 * Signature: ()Ljava/util/Locale;
216 */
217 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_getNativeLocale
218 (JNIEnv *env, jobject this)
219 {
220 if (!inputMethodController) return NULL;
221 jobject returnValue = 0;
222 __block NSString *isoAbbreviation;
223 JNF_COCOA_ENTER(env);
224
225 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
226 isoAbbreviation = (NSString *) [inputMethodController performSelector:@selector(currentInputMethodLocale)];
227 [isoAbbreviation retain];
228 }];
229
230 if (isoAbbreviation == nil) return NULL;
231
232 static NSString *sLastKeyboardStr = nil;
233 static jobject sLastKeyboardLocaleObj = NULL;
234
235 if (![isoAbbreviation isEqualTo:sLastKeyboardStr]) {
236 [sLastKeyboardStr release];
237 sLastKeyboardStr = [isoAbbreviation retain];
238 jobject localObj = CreateLocaleObjectFromNSString(env, isoAbbreviation);
239 [isoAbbreviation release];
240
241 if (sLastKeyboardLocaleObj) {
242 JNFDeleteGlobalRef(env, sLastKeyboardLocaleObj);
243 sLastKeyboardLocaleObj = NULL;
244 }
245 if (localObj != NULL) {
246 sLastKeyboardLocaleObj = JNFNewGlobalRef(env, localObj);
247 (*env)->DeleteLocalRef(env, localObj);
248 }
249 }
250
251 returnValue = sLastKeyboardLocaleObj;
252
253 JNF_COCOA_EXIT(env);
254 return returnValue;
255 }
256
257
258 /*
259 * Class: sun_lwawt_macosx_CInputMethod
260 * Method: setNativeLocale
261 * Signature: (Ljava/lang/String;Z)Z
262 */
263 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CInputMethod_setNativeLocale
264 (JNIEnv *env, jobject this, jstring locale, jboolean isActivating)
265 {
266 JNF_COCOA_ENTER(env);
267 NSString *localeStr = JNFJavaToNSString(env, locale);
268 [localeStr retain];
269
270 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
271 [CInputMethod setKeyboardLayout:localeStr];
272 }];
273
274 [localeStr release];
275 JNF_COCOA_EXIT(env);
276 return JNI_TRUE;
277 }
278
279 /*
280 * Class: sun_lwawt_macosx_CInputMethodDescriptor
281 * Method: nativeInit
282 * Signature: ();
283 */
284 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeInit
285 (JNIEnv *env, jclass klass)
286 {
287 initializeInputMethodController();
288 }
289
290 /*
291 * Class: sun_lwawt_macosx_CInputMethodDescriptor
292 * Method: nativeGetAvailableLocales
293 * Signature: ()[Ljava/util/Locale;
294 */
295 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeGetAvailableLocales
296 (JNIEnv *env, jclass klass)
297 {
298 if (!inputMethodController) return NULL;
299 jobject returnValue = 0;
300
301 __block NSArray *selectableArray = nil;
302 JNF_COCOA_ENTER(env);
303
304 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
305 selectableArray = (NSArray *)[inputMethodController performSelector:@selector(availableInputMethodLocales)];
306 [selectableArray retain];
307 }];
308
309 if (selectableArray == nil) return NULL;
310
311 // Create an ArrayList to return back to the caller.
312 returnValue = JNFNewObject(env, jm_arrayListCons);
313
314 for(NSString *locale in selectableArray) {
315 jobject localeObj = CreateLocaleObjectFromNSString(env, locale);
316 if (localeObj == NULL) {
317 break;
318 }
319
320 if (JNFCallBooleanMethod(env, returnValue, jm_listContains, localeObj) == JNI_FALSE) {
321 JNFCallBooleanMethod(env, returnValue, jm_listAdd, localeObj);
322 }
323
324 (*env)->DeleteLocalRef(env, localeObj);
325 }
326 [selectableArray release];
327 JNF_COCOA_EXIT(env);
328 return returnValue;
329 }
330
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import <Cocoa/Cocoa.h>
27 #include <objc/objc-runtime.h>
28
29 #import "sun_lwawt_macosx_CInputMethod.h"
30 #import "sun_lwawt_macosx_CInputMethodDescriptor.h"
31 #import "ThreadUtilities.h"
32 #import "AWTView.h"
33 #import "JNIUtilities.h"
34
35 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
36
37 #define JAVA_LIST @"JAVA_LIST"
38 #define CURRENT_KB_DESCRIPTION @"CURRENT_KB_DESCRIPTION"
39
40 //
41 // NOTE: This returns a JNI Local Ref. Any code that calls must call DeleteLocalRef with the return value.
42 //
43 static jobject CreateLocaleObjectFromNSString(JNIEnv *env, NSString *name)
44 {
45 DECLARE_CLASS_RETURN(jc_localeClass, "java/util/Locale", NULL);
46 DECLARE_METHOD_RETURN(jm_localeCons, jc_localeClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", NULL);
47 // Break apart the string into its components.
48 // First, duplicate the NSString into a C string, since we're going to modify it.
49 char * language = strdup([name UTF8String]);
50 char * country;
51 char * variant;
52
53 // Convert _ to NULL -- this gives us three null terminated strings in place.
54 for (country = language; *country != '_' && *country != '\0'; country++);
55 if (*country == '_') {
56 *country++ = '\0';
57 for (variant = country; *variant != '_' && *variant != '\0'; variant++);
58 if (*variant == '_') {
59 *variant++ = '\0';
60 }
61 } else {
62 variant = country;
63 }
64
65 // Create the java.util.Locale object
66 jobject localeObj = NULL;
67 jobject langObj = (*env)->NewStringUTF(env, language);
68 if (langObj != NULL) {
69 jobject ctryObj = (*env)->NewStringUTF(env, country);
70 if(ctryObj != NULL) {
71 jobject vrntObj = (*env)->NewStringUTF(env, variant);
72 if (vrntObj != NULL) {
73 localeObj = (*env)->NewObject(env, jc_localeClass, jm_localeCons,langObj, ctryObj,
74 vrntObj);
75 CHECK_EXCEPTION();
76 (*env)->DeleteLocalRef(env, vrntObj);
77 }
78 (*env)->DeleteLocalRef(env, ctryObj);
79 }
80 (*env)->DeleteLocalRef(env, langObj);
81 }
82 // Clean up and return.
83 free(language);
84 return localeObj;
85 }
86
87 static id inputMethodController = nil;
88
89 static void initializeInputMethodController() {
90 static BOOL checkedJRSInputMethodController = NO;
91 if (!checkedJRSInputMethodController && (inputMethodController == nil)) {
92 id jrsInputMethodController = objc_lookUpClass("JRSInputMethodController");
93 if (jrsInputMethodController != nil) {
94 inputMethodController = [jrsInputMethodController performSelector:@selector(controller)];
95 }
96 checkedJRSInputMethodController = YES;
97 }
98 }
99
100
101 @interface CInputMethod : NSObject {}
102 @end
103
104 @implementation CInputMethod
105
106 + (void) setKeyboardLayout:(NSString *)theLocale
107 {
108 AWT_ASSERT_APPKIT_THREAD;
109 if (!inputMethodController) return;
110
111 [inputMethodController performSelector:@selector(setCurrentInputMethodForLocale) withObject:theLocale];
112 }
113
114 + (void) _nativeNotifyPeerWithView:(AWTView *)view inputMethod:(jobject) inputMethod {
115 AWT_ASSERT_APPKIT_THREAD;
116
117 if (!view) return;
118 if (!inputMethod) return;
119
120 [view setInputMethod:inputMethod]; // inputMethod is a GlobalRef
121 }
122
123 + (void) _nativeEndComposition:(AWTView *)view {
124 if (view == nil) return;
125
126 [view abandonInput];
127 }
128
129
130 @end
131
132 /*
133 * Class: sun_lwawt_macosx_CInputMethod
134 * Method: nativeInit
135 * Signature: ();
136 */
137 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeInit
138 (JNIEnv *env, jclass klass)
139 {
140 initializeInputMethodController();
141 }
142
143 /*
144 * Class: sun_lwawt_macosx_CInputMethod
145 * Method: nativeGetCurrentInputMethodInfo
146 * Signature: ()Ljava/lang/String;
147 */
148 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeGetCurrentInputMethodInfo
149 (JNIEnv *env, jclass klass)
150 {
151 if (!inputMethodController) return NULL;
152 jobject returnValue = 0;
153 __block NSString *keyboardInfo = NULL;
154 JNI_COCOA_ENTER(env);
155
156 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
157 keyboardInfo = [inputMethodController performSelector:@selector(currentInputMethodName)];
158 [keyboardInfo retain];
159 }];
160
161 if (keyboardInfo == nil) return NULL;
162 returnValue = NSStringToJavaString(env, keyboardInfo);
163 [keyboardInfo release];
164
165 JNI_COCOA_EXIT(env);
166 return returnValue;
167 }
168
169 /*
170 * Class: sun_lwawt_macosx_CInputMethod
171 * Method: nativeActivate
172 * Signature: (JLsun/lwawt/macosx/CInputMethod;)V
173 */
174 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeNotifyPeer
175 (JNIEnv *env, jobject this, jlong nativePeer, jobject inputMethod)
176 {
177 JNI_COCOA_ENTER(env);
178 AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
179 jobject inputMethodRef = (*env)->NewGlobalRef(env, inputMethod);
180 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
181 [CInputMethod _nativeNotifyPeerWithView:view inputMethod:inputMethodRef];
182 }];
183
184 JNI_COCOA_EXIT(env);
185
186 }
187
188 /*
189 * Class: sun_lwawt_macosx_CInputMethod
190 * Method: nativeEndComposition
191 * Signature: (J)V
192 */
193 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethod_nativeEndComposition
194 (JNIEnv *env, jobject this, jlong nativePeer)
195 {
196 JNI_COCOA_ENTER(env);
197 AWTView *view = (AWTView *)jlong_to_ptr(nativePeer);
198
199 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
200 [CInputMethod _nativeEndComposition:view];
201 }];
202
203 JNI_COCOA_EXIT(env);
204 }
205
206 /*
207 * Class: sun_lwawt_macosx_CInputMethod
208 * Method: getNativeLocale
209 * Signature: ()Ljava/util/Locale;
210 */
211 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethod_getNativeLocale
212 (JNIEnv *env, jobject this)
213 {
214 if (!inputMethodController) return NULL;
215 jobject returnValue = 0;
216 __block NSString *isoAbbreviation;
217 JNI_COCOA_ENTER(env);
218
219 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
220 isoAbbreviation = (NSString *) [inputMethodController performSelector:@selector(currentInputMethodLocale)];
221 [isoAbbreviation retain];
222 }];
223
224 if (isoAbbreviation == nil) return NULL;
225
226 static NSString *sLastKeyboardStr = nil;
227 static jobject sLastKeyboardLocaleObj = NULL;
228
229 if (![isoAbbreviation isEqualTo:sLastKeyboardStr]) {
230 [sLastKeyboardStr release];
231 sLastKeyboardStr = [isoAbbreviation retain];
232 jobject localObj = CreateLocaleObjectFromNSString(env, isoAbbreviation);
233 [isoAbbreviation release];
234
235 if (sLastKeyboardLocaleObj) {
236 (*env)->DeleteGlobalRef(env, sLastKeyboardLocaleObj);
237 sLastKeyboardLocaleObj = NULL;
238 }
239 if (localObj != NULL) {
240 sLastKeyboardLocaleObj = (*env)->NewGlobalRef(env, localObj);
241 (*env)->DeleteLocalRef(env, localObj);
242 }
243 }
244
245 returnValue = sLastKeyboardLocaleObj;
246
247 JNI_COCOA_EXIT(env);
248 return returnValue;
249 }
250
251
252 /*
253 * Class: sun_lwawt_macosx_CInputMethod
254 * Method: setNativeLocale
255 * Signature: (Ljava/lang/String;Z)Z
256 */
257 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CInputMethod_setNativeLocale
258 (JNIEnv *env, jobject this, jstring locale, jboolean isActivating)
259 {
260 JNI_COCOA_ENTER(env);
261 NSString *localeStr = JavaStringToNSString(env, locale);
262 [localeStr retain];
263
264 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
265 [CInputMethod setKeyboardLayout:localeStr];
266 }];
267
268 [localeStr release];
269 JNI_COCOA_EXIT(env);
270 return JNI_TRUE;
271 }
272
273 /*
274 * Class: sun_lwawt_macosx_CInputMethodDescriptor
275 * Method: nativeInit
276 * Signature: ();
277 */
278 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeInit
279 (JNIEnv *env, jclass klass)
280 {
281 initializeInputMethodController();
282 }
283
284 /*
285 * Class: sun_lwawt_macosx_CInputMethodDescriptor
286 * Method: nativeGetAvailableLocales
287 * Signature: ()[Ljava/util/Locale;
288 */
289 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CInputMethodDescriptor_nativeGetAvailableLocales
290 (JNIEnv *env, jclass klass)
291 {
292 DECLARE_CLASS_RETURN(jc_arrayListClass, "java/util/ArrayList", NULL);
293 DECLARE_METHOD_RETURN(jm_arrayListCons, jc_arrayListClass, "<init>", "()V", NULL);
294 DECLARE_METHOD_RETURN(jm_listAdd, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z", NULL);
295 DECLARE_METHOD_RETURN(jm_listContains, jc_arrayListClass, "contains", "(Ljava/lang/Object;)Z", NULL);
296
297 if (!inputMethodController) return NULL;
298 jobject returnValue = 0;
299
300 __block NSArray *selectableArray = nil;
301 JNI_COCOA_ENTER(env);
302
303 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
304 selectableArray = (NSArray *)[inputMethodController performSelector:@selector(availableInputMethodLocales)];
305 [selectableArray retain];
306 }];
307
308 if (selectableArray == nil) return NULL;
309
310 // Create an ArrayList to return back to the caller.
311 returnValue = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons);
312 CHECK_EXCEPTION_NULL_RETURN(returnValue, NULL);
313
314 for(NSString *locale in selectableArray) {
315 jobject localeObj = CreateLocaleObjectFromNSString(env, locale);
316 if (localeObj == NULL) {
317 break;
318 }
319
320 if ((*env)->CallBooleanMethod(env, returnValue, jm_listContains, localeObj) == JNI_FALSE) {
321 if ((*env)->ExceptionOccurred(env)) (*env)->ExceptionClear(env);
322 (*env)->CallBooleanMethod(env, returnValue, jm_listAdd, localeObj);
323 }
324 if ((*env)->ExceptionOccurred(env)) (*env)->ExceptionClear(env);
325
326 (*env)->DeleteLocalRef(env, localeObj);
327 }
328 [selectableArray release];
329 JNI_COCOA_EXIT(env);
330 return returnValue;
331 }
332
|