blob: 838f991f84ec116fc93bd16c13b393deab62d9d3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#ifdef HEADLESS
27 #error This file should not be included in headless library
28#endif
29
30#if MOTIF_VERSION!=2
31 #error This file should only be compiled with motif 2.1
32#endif
33
34#include "awt_p.h"
35#include "java_awt_Component.h"
36#include "java_awt_AWTEvent.h"
37#include "sun_awt_motif_MComponentPeer.h"
38#include "sun_awt_motif_MChoicePeer.h"
39
40#include "awt_Component.h"
41#include "canvas.h"
42
43#include "multi_font.h"
44
45#include <jni.h>
46#include <jni_util.h>
47#include <Xm/ComboBox.h>
48
49#define MAX_VISIBLE 10
50
51extern struct ComponentIDs componentIDs;
52extern struct ContainerIDs containerIDs;
53extern struct MComponentPeerIDs mComponentPeerIDs;
54
55extern AwtGraphicsConfigDataPtr
56 copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
57
58/*
59 setSelection
60 Set the selected text on the XmTextField of the XmComboBox.
61*/
62static void
63setSelection(JNIEnv *env,
64 jobject this,
65 Widget comboBox,
66 jint index)
67{
68 jstring item = NULL;
69 jobject target;
70 Widget text=NULL;
71
72 AWT_LOCK();
73 /* Get the java Choice component. */
74 target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
75 if (target == NULL) {
76 JNU_ThrowNullPointerException(env, "NullPointerException");
77 AWT_UNLOCK();
78 return;
79 }
80 /* Get the XmTextField widget in the XmComboBox. */
81 text = XtNameToWidget(comboBox, "*Text");
82 /* Get the selected Unicode string from the java Choice component. */
83 item = (jstring) JNU_CallMethodByName(env, NULL,
84 target, "getItem", "(I)Ljava/lang/String;", index).l;
85 if ((*env)->ExceptionOccurred(env)) {
86 (*env)->ExceptionDescribe(env);
87 (*env)->ExceptionClear(env);
88 }
89 if (!JNU_IsNull(env, item)) {
90 /* Convert the Unicode string to a multibyte string. */
91 char *temp = (char *)JNU_GetStringPlatformChars(env, item, NULL);
92 /* Assign the multibyte string to the XmTextField of the XmComboBox. */
93 XmTextSetString(text, temp);
94 JNU_ReleaseStringPlatformChars(env, item, (const char *)temp);
95 }
96 AWT_UNLOCK();
97}
98
99extern Boolean skipNextNotifyWhileGrabbed;
100extern Boolean skipNextFocusIn;
101
102static void
103GrabShellPopup(Widget grab_shell,
104 jobject this,
105 XmAnyCallbackStruct * call_data)
106{
107 skipNextNotifyWhileGrabbed = True;
108}
109static void
110GrabShellPopdown(Widget grab_shell,
111 jobject this,
112 XmAnyCallbackStruct * call_data)
113{
114 skipNextNotifyWhileGrabbed = True;
115 skipNextFocusIn = True;
116}
117
118static void
119Choice_callback(Widget list,
120 jobject this,
121 XmAnyCallbackStruct * call_data)
122{
123 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
124 XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
125 struct ChoiceData *cdata;
126
127
128 AWT_LOCK();
129 /* Get the Choice data. */
130 cdata = (struct ChoiceData *)
131 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
132 if (cdata == NULL) {
133 JNU_ThrowNullPointerException(env, "NullPointerException");
134 AWT_UNLOCK();
135 return;
136 }
137 setSelection(env, this, cdata->comp.widget, cbs->item_position - 1);
138 /* Get the Choice data. */
139 JNU_CallMethodByName(env, NULL,
140 this, "action", "(I)V", cbs->item_position - 1);
141 if ((*env)->ExceptionOccurred(env)) {
142 (*env)->ExceptionDescribe(env);
143 (*env)->ExceptionClear(env);
144 }
145 AWT_UNLOCK();
146}
147
148static void
149addItems(JNIEnv *env, jobject this,
150 jstring *items, int32_t nItems, jint index)
151{
152 struct ChoiceData *cdata;
153 int32_t i;
154 Widget list;
155 XmString mfstr = NULL;
156 XmFontList fontlist = NULL;
157 jobject font = awtJNI_GetFont(env, this);
158 Boolean IsMultiFont = awtJNI_IsMultiFont(env, font);
159
160 if ((items == NULL) || (nItems == 0)) {
161 return;
162 }
163
164 AWT_LOCK();
165
166 cdata = (struct ChoiceData *)
167 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
168
169 if (cdata == NULL) {
170 JNU_ThrowNullPointerException(env, "NullPointerException");
171 AWT_UNLOCK();
172 return;
173 }
174
175 for (i = 0; i < nItems; ++i) {
176 char *temp = (char *)JNU_GetStringPlatformChars(env, items[i], NULL);
177 mfstr = XmStringCreateLocalized(temp);
178 JNU_ReleaseStringPlatformChars(env, items[i], (const char *)temp);
179 XmComboBoxAddItem(cdata->comp.widget, mfstr, index + i + 1, FALSE);
180
181 if (mfstr != NULL) {
182 XmStringFree(mfstr);
183 mfstr = NULL;
184 }
185 }
186
187 cdata->n_items += nItems;
188
189 list = XtNameToWidget(cdata->comp.widget, "*List");
190 XtVaSetValues(list,
191 XmNvisibleItemCount, min(MAX_VISIBLE, cdata->n_items),
192 NULL);
193 AWT_UNLOCK();
194}
195
196/*
197 * Class: sun_awt_motif_MChoicePeer
198 * Method: create
199 * Signature: (Lsun/awt/motif/MComponentPeer;)V
200 */
201JNIEXPORT void JNICALL
202Java_sun_awt_motif_MChoicePeer_create(JNIEnv * env, jobject this,
203 jobject parent)
204{
205 jobject globalRef = awtJNI_CreateAndSetGlobalRef(env, this);
206
207 struct ComponentData *wdata; /* parent's peer data */
208 struct ChoiceData *cdata; /* our own peer data */
209 Widget list, text, list_shell; /* components of drop dowwn list widget */
210
211 AwtGraphicsConfigDataPtr adata;
212 Pixel fg, bg; /* colors inherited from parent */
213 Dimension width = 0, height = 0;
214 jclass clsDimension;
215 jobject dimension;
216
217#undef MAX_ARGC
218#define MAX_ARGC 30
219 Arg args[MAX_ARGC];
220 int32_t argc;
221
222 AWT_LOCK();
223
224 if (JNU_IsNull(env, parent)) {
225 JNU_ThrowNullPointerException(env, "NullPointerException");
226 return;
227 }
228
229 /* get parent's peer data */
230 wdata = (struct ComponentData *)JNU_GetLongFieldAsPtr(env,
231 parent, mComponentPeerIDs.pData);
232 if (wdata == NULL) {
233 JNU_ThrowNullPointerException(env, "NullPointerException");
234 AWT_UNLOCK();
235 return;
236 }
237
238 /* create our own peer data */
239 cdata = ZALLOC(ChoiceData);
240 if (cdata == NULL) {
241 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
242 AWT_UNLOCK();
243 return;
244 }
245 JNU_SetLongFieldFromPtr(env, this, mComponentPeerIDs.pData, cdata);
246
247 /* get desired size */
248 clsDimension = (*env)->FindClass(env, "java/awt/Dimension");
249 DASSERT(clsDimension != NULL);
250
251 dimension = JNU_CallMethodByName(env, NULL,
252 this, "getPreferredSize", "()Ljava/awt/Dimension;").l;
253 width = (Dimension)((*env)->GetIntField(env, dimension,
254 (*env)->GetFieldID(env, clsDimension,
255 "width" , "I")));
256 height = (Dimension)((*env)->GetIntField(env, dimension,
257 (*env)->GetFieldID(env, clsDimension,
258 "height", "I")));
259
260 /* Inherit visual/colors from parent component */
261 XtVaGetValues(wdata->widget, XmNbackground, &bg, NULL);
262 XtVaGetValues(wdata->widget, XmNforeground, &fg, NULL);
263 adata = copyGraphicsConfigToPeer(env, this);
264
265 argc = 0;
266 XtSetArg(args[argc], XmNuserData, (XtPointer)globalRef); ++argc;
267 XtSetArg(args[argc], XmNx, 0); ++argc;
268 XtSetArg(args[argc], XmNy, 0); ++argc;
269 XtSetArg(args[argc], XmNmarginHeight, 2); ++argc;
270 XtSetArg(args[argc], XmNmarginWidth, 1); ++argc;
271 XtSetArg(args[argc], XmNvisibleItemCount, 0); ++argc;
272 XtSetArg(args[argc], XmNancestorSensitive, True); ++argc;
273 /* Don't ding on key press */
274 XtSetArg(args[argc], XmNverifyBell, False); ++argc;
275 XtSetArg(args[argc], XmNvisual, adata->awt_visInfo.visual); ++argc;
276 XtSetArg(args[argc], XmNscreen,
277 ScreenOfDisplay(awt_display, adata->awt_visInfo.screen)); ++argc;
278 XtSetArg(args[argc], XmNbackground, bg); ++argc;
279 XtSetArg(args[argc], XmNforeground, fg); ++argc;
280
281 DASSERT(!(argc > MAX_ARGC));
282 cdata->comp.widget = XmCreateDropDownList(wdata->widget,
283 "combobox", args, argc);
284 cdata->n_items = 0;
285
286 list = XtNameToWidget(cdata->comp.widget, "*List");
287 text = XtNameToWidget(cdata->comp.widget, "*Text");
288 list_shell = XtNameToWidget(cdata->comp.widget, "*GrabShell");
289 XtAddCallback(list_shell,
290 XmNpopupCallback,
291 (XtCallbackProc)GrabShellPopup,
292 globalRef);
293 XtAddCallback(list_shell,
294 XmNpopdownCallback,
295 (XtCallbackProc)GrabShellPopdown,
296 globalRef);
297
298 /*
299 * Bug 4477410: Setting the width of the XmComboBox made the XmTextField
300 * too small, cutting off the dropdown list knob on the right side. Set
301 * the width of the TextField because it is the widget actually seen.
302 */
303 /* Set the width and height of the TextField widget. */
304 XtVaSetValues(text,
305 XmNwidth, width,
306 XmNheight, height,
307 NULL);
308
309 XtAddCallback(list,
310 XmNbrowseSelectionCallback,
311 (XtCallbackProc)Choice_callback,
312 (XtPointer)globalRef);
313
314 XtAddEventHandler(text, FocusChangeMask, True,
315 awt_canvas_event_handler, globalRef);
316
317 awt_addWidget(text, cdata->comp.widget, globalRef,
318 java_awt_AWTEvent_KEY_EVENT_MASK
319 | java_awt_AWTEvent_MOUSE_EVENT_MASK
320 | java_awt_AWTEvent_MOUSE_MOTION_EVENT_MASK);
321
322 XtSetMappedWhenManaged(cdata->comp.widget, False);
323 XtManageChild(cdata->comp.widget);
324
325 AWT_UNLOCK();
326}
327
328/*
329 * Class: sun_awt_motif_MChoicePeer
330 * Method: pSelect
331 * Signature: (I)V
332 */
333JNIEXPORT void JNICALL
334Java_sun_awt_motif_MChoicePeer_pSelect(JNIEnv *env, jobject this,
335 jint index, jboolean init)
336{
337 struct ChoiceData *cdata;
338 Widget list;
339
340 AWT_LOCK();
341
342 cdata = (struct ChoiceData *)JNU_GetLongFieldAsPtr(env,
343 this, mComponentPeerIDs.pData);
344 if (cdata == NULL) {
345 JNU_ThrowNullPointerException(env, "NullPointerException");
346 AWT_UNLOCK();
347 return;
348 }
349
350 list = XtNameToWidget(cdata->comp.widget, "*List");
351
352 XmListDeselectAllItems(list);
353 XmListSelectPos(list, index + 1, False);
354 setSelection(env, this, cdata->comp.widget, index);
355 XmComboBoxUpdate(cdata->comp.widget);
356
357 AWT_UNLOCK();
358}
359
360/*
361 * Class: sun_awt_motif_MChoicePeer
362 * Method: setFont
363 * Signature: (Ljava/awt/Font;)V
364 */
365JNIEXPORT void JNICALL
366Java_sun_awt_motif_MChoicePeer_setFont(JNIEnv *env, jobject this,
367 jobject f)
368{
369 struct ChoiceData *cdata;
370 struct FontData *fdata;
371 XmFontList fontlist;
372 Widget list;
373 Widget text;
374 char *err;
375 XmFontListEntry fontentry;
376 Position x=0, y=0;
377
378 if (JNU_IsNull(env, f)) {
379 JNU_ThrowNullPointerException(env, "NullPointerException");
380 return;
381 }
382 AWT_LOCK();
383
384 fdata = awtJNI_GetFontData(env, f, &err);
385 if (fdata == NULL) {
386 JNU_ThrowInternalError(env, err);
387 AWT_UNLOCK();
388 return;
389 }
390
391 cdata = (struct ChoiceData *)JNU_GetLongFieldAsPtr(env,
392 this, mComponentPeerIDs.pData);
393 if (cdata == NULL || cdata->comp.widget == NULL) {
394 JNU_ThrowNullPointerException(env, "NullPointerException");
395 AWT_UNLOCK();
396 return;
397 }
398
399 /* Make a fontset and set it. */
400 if (awtJNI_IsMultiFont(env, f)) {
401 if (fdata->xfs == NULL) {
402 fdata->xfs = awtJNI_MakeFontSet(env, f);
403 }
404 if (fdata->xfs != NULL) {
405 fontentry = XmFontListEntryCreate("labelFont",
406 XmFONT_IS_FONTSET,
407 (XtPointer) (fdata->xfs));
408 fontlist = XmFontListAppendEntry(NULL, fontentry);
409 /*
410 * Some versions of motif have a bug in
411 * XmFontListEntryFree() which causes it to free more than it
412 * should. Use XtFree() instead. See O'Reilly's
413 * Motif Reference Manual for more information.
414 */
415 XmFontListEntryFree(&fontentry);
416 } else {
417 fontlist = XmFontListCreate(fdata->xfont, "labelFont");
418 }
419 } else {
420 fontlist = XmFontListCreate(fdata->xfont, "labelFont");
421 }
422 XtVaSetValues(cdata->comp.widget,
423 XmNfontList, fontlist,
424 NULL);
425 list = XtNameToWidget(cdata->comp.widget, "*List");
426 XtVaSetValues(list,
427 XmNfontList, fontlist,
428 NULL);
429
430 text = XtNameToWidget(cdata->comp.widget, "*Text");
431 XtVaSetValues(text,
432 XmNfontList, fontlist,
433 NULL);
434 XmFontListFree(fontlist);
435 XtVaGetValues(cdata->comp.widget,
436 XmNx, &x,
437 XmNy, &y,
438 NULL);
439 Java_sun_awt_motif_MChoicePeer_pReshape(env, this, x, y, 0, 0);
440 AWT_UNLOCK();
441}
442
443
444/*
445 * Class: sun_awt_motif_MChoicePeer
446 * Method: freeNativeData
447 * Signature: ()V
448 */
449JNIEXPORT void JNICALL
450Java_sun_awt_motif_MChoicePeer_freeNativeData(JNIEnv *env, jobject this)
451{
452 /*
453 * Fix for bug 4326619 - not necessary for Motif 2.1
454 */
455}
456
457
458/*
459 * Class: sun_awt_motif_MChoicePeer
460 * Method: setBackground
461 * Signature: (Ljava/awt/Color;)V
462 */
463JNIEXPORT void JNICALL
464Java_sun_awt_motif_MChoicePeer_setBackground(JNIEnv *env, jobject this,
465 jobject c)
466{
467 struct ChoiceData *cdata;
468 Pixel bg;
469 Pixel fg;
470 int32_t i;
471
472 if (JNU_IsNull(env, c)) {
473 JNU_ThrowNullPointerException(env, "NullPointerException: null color");
474 return;
475 }
476 AWT_LOCK();
477
478 cdata = (struct ChoiceData *)
479 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
480 if (cdata == NULL || cdata->comp.widget == NULL) {
481 JNU_ThrowNullPointerException(env, "NullPointerException");
482 AWT_UNLOCK();
483 return;
484 }
485 /* Get background color */
486 bg = awtJNI_GetColor(env, c);
487
488 /*
489 XmChangeColor(), in addtion to changing the background and
490 selection colors, also changes the foreground color to be
491 what it thinks should be. However, we want to use the color
492 that gets set by setForeground() instead. We therefore need to
493 save the current foreground color here, and then set it again
494 after the XmChangeColor() occurs.
495 */
496 XtVaGetValues(cdata->comp.widget, XmNforeground, &fg, NULL);
497
498 /* Set color */
499 XmChangeColor(cdata->comp.widget, bg);
500 XtVaSetValues(cdata->comp.widget, XmNforeground, fg, NULL);
501
502 AWT_FLUSH_UNLOCK();
503}
504
505/*
506 * Class: sun_awt_motif_MChoicePeer
507 * Method: setForeground
508 * Signature: (Ljava/awt/Color;)V
509 */
510JNIEXPORT void JNICALL
511Java_sun_awt_motif_MChoicePeer_setForeground(JNIEnv *env, jobject this,
512 jobject c)
513{
514 struct ChoiceData *cdata;
515 Pixel color;
516 int32_t i;
517
518 if (JNU_IsNull(env, c)) {
519 JNU_ThrowNullPointerException(env, "NullPointerException: null color");
520 return;
521 }
522 AWT_LOCK();
523
524 cdata = (struct ChoiceData *)
525 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
526 if (cdata == NULL || cdata->comp.widget == NULL) {
527 JNU_ThrowNullPointerException(env, "NullPointerException");
528 AWT_UNLOCK();
529 return;
530 }
531 color = awtJNI_GetColor(env, c);
532
533 XtVaSetValues(cdata->comp.widget, XmNforeground, color, NULL);
534
535 AWT_FLUSH_UNLOCK();
536}
537
538/*
539 * Class: sun_awt_motif_MChoicePeer
540 * Method: pReshape
541 * Signature: (IIII)V
542 */
543JNIEXPORT void JNICALL
544Java_sun_awt_motif_MChoicePeer_pReshape(JNIEnv *env, jobject this,
545 jint x, jint y, jint w, jint h)
546{
547 struct ChoiceData *cdata;
548 Widget list;
549 Dimension width = 0, height = 0;
550 jclass clsDimension;
551 jobject dimension;
552 jobject target;
553 Widget text=NULL;
554
555 AWT_LOCK();
556
557 cdata = (struct ChoiceData *)
558 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
559 if (cdata == NULL || cdata->comp.widget == NULL) {
560 JNU_ThrowNullPointerException(env, "NullPointerException");
561 AWT_UNLOCK();
562 return;
563 }
564
565 if (w == 0) {
566 /* Set the width and height of the TextField widget to the
567 * PreferredSize, based on the font size.
568 */
569 clsDimension = (*env)->FindClass(env, "java/awt/Dimension");
570 DASSERT(clsDimension != NULL);
571 dimension = JNU_CallMethodByName(env, NULL,
572 this, "getPreferredSize", "()Ljava/awt/Dimension;").l;
573 width = (Dimension)((*env)->GetIntField(env, dimension,
574 (*env)->GetFieldID(env, clsDimension,
575 "width" , "I")));
576 height = (Dimension)((*env)->GetIntField(env, dimension,
577 (*env)->GetFieldID(env, clsDimension,
578 "height", "I")));
579 } else {
580 /* Set the width and height of the TextField widget to the
581 * given values. BorderLayout passes these values, for example.
582 */
583 width = w;
584 height = h;
585 }
586 text = XtNameToWidget(cdata->comp.widget, "*Text");
587 /*
588 * Bug 4477410: Setting the width of the XmComboBox made the XmTextField
589 * too small, cutting off the dropdown list knob on the right side. Set
590 * the width of the TextField because it is the widget actually seen.
591 */
592 XtVaSetValues(text,
593 XmNwidth, width,
594 XmNheight, height,
595 NULL);
596
597 awt_util_reshape(cdata->comp.widget, x, y, width, height);
598
599 list = XtNameToWidget(cdata->comp.widget, "*List");
600
601 XtVaSetValues(list, XmNwidth, width, NULL);
602
603 /* Set the width and height of the Choice component. */
604 target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
605 if (target == NULL) {
606 JNU_ThrowNullPointerException(env, "NullPointerException");
607 AWT_UNLOCK();
608 return;
609 }
610 (*env)->SetIntField(env, target, componentIDs.width, (jint)width);
611 (*env)->SetIntField(env, target, componentIDs.height, (jint)height);
612
613 AWT_FLUSH_UNLOCK();
614}
615
616
617/*
618 * Class: sun_awt_motif_MChoicePeer
619 * Method: addItem
620 * Signature: (Ljava/lang/String;I)V
621 */
622JNIEXPORT void JNICALL
623Java_sun_awt_motif_MChoicePeer_addItem(JNIEnv *env, jobject this,
624 jstring item, jint index)
625{
626 if (JNU_IsNull(env, item)) {
627 JNU_ThrowNullPointerException(env, "NullPointerException");
628 return;
629 }
630 addItems(env, this, &item, 1, index);
631}
632
633
634/*
635 * Class: sun_awt_motif_MChoicePeer
636 * Method: appendItems
637 * Signature: ([Ljava/lang/String;)V
638 */
639JNIEXPORT void JNICALL
640Java_sun_awt_motif_MChoicePeer_appendItems(JNIEnv *env, jobject this,
641 jarray items)
642{
643 struct ChoiceData *cdata = NULL;
644 jstring *strItems = NULL;
645 int32_t nItems, i;
646
647 if (JNU_IsNull(env, items)) {
648 return;
649 }
650 nItems = (*env)->GetArrayLength(env, items);
651 if (nItems == 0) {
652 return;
653 }
654
655 AWT_LOCK();
656
657 cdata = (struct ChoiceData *)JNU_GetLongFieldAsPtr(env,
658 this, mComponentPeerIDs.pData);
659 if (cdata == NULL) {
660 JNU_ThrowNullPointerException(env, "NullPointerException");
661 goto cleanup;
662 }
663
664 strItems = (jstring *)malloc(sizeof(jstring) * nItems);
665 if (strItems == NULL) {
666 JNU_ThrowNullPointerException(env, "NullPointerException");
667 goto cleanup;
668 }
669
670 for (i = 0; i < nItems; ++i) {
671 strItems[i] = (jstring)(*env)->GetObjectArrayElement(env,
672 items, (jsize)i);
673 if (JNU_IsNull(env, strItems[i])) {
674 JNU_ThrowNullPointerException(env, "NullPointerException");
675 goto cleanup;
676 }
677 }
678
679 addItems(env, this, strItems, nItems, (jint)cdata->n_items);
680
681 cleanup:
682 if (strItems != NULL) {
683 free(strItems);
684 }
685 AWT_UNLOCK();
686}
687
688
689/*
690 * Class: sun_awt_motif_MChoicePeer
691 * Method: remove
692 * Signature: (I)V
693 */
694JNIEXPORT void JNICALL
695Java_sun_awt_motif_MChoicePeer_remove(JNIEnv *env, jobject this,
696 jint index)
697{
698 struct ChoiceData *cdata;
699 Widget list;
700 Widget text=NULL;
701
702 AWT_LOCK();
703
704 cdata = (struct ChoiceData *)
705 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
706 if (cdata == NULL || cdata->comp.widget == NULL) {
707 JNU_ThrowNullPointerException(env, "NullPointerException");
708 AWT_UNLOCK();
709 return;
710 }
711
712 XmComboBoxDeletePos(cdata->comp.widget, index + 1);
713 --(cdata->n_items);
714
715 list = XtNameToWidget(cdata->comp.widget, "*List");
716 XtVaSetValues(list, XmNvisibleItemCount, min(MAX_VISIBLE, cdata->n_items), NULL);
717
718 if (cdata->n_items == 0) {
719 /* No item is selected, so clear the TextField. */
720 text = XtNameToWidget(cdata->comp.widget, "*Text");
721 XtVaSetValues(text, XmNvalue, "", NULL);
722 }
723
724 AWT_UNLOCK();
725}
726
727/*
728 * Class: sun_awt_motif_MChoicePeer
729 * Method: removeAll
730 * Signature: ()V
731 */
732JNIEXPORT void JNICALL
733Java_sun_awt_motif_MChoicePeer_removeAll(JNIEnv *env, jobject this)
734{
735 struct ChoiceData *cdata;
736 int32_t i;
737 Widget text=NULL;
738 Widget list;
739
740 AWT_LOCK();
741
742 cdata = (struct ChoiceData *)
743 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
744 if (cdata == NULL || cdata->comp.widget == NULL) {
745 JNU_ThrowNullPointerException(env, "NullPointerException");
746 AWT_UNLOCK();
747 return;
748 }
749
750 for (i = cdata->n_items - 1; i >= 0; --i) {
751 XmComboBoxDeletePos(cdata->comp.widget, i);
752 }
753 cdata->n_items = 0;
754
755 /* No item is selected, so clear the TextField. */
756 text = XtNameToWidget(cdata->comp.widget, "*Text");
757 XtVaSetValues(text, XmNvalue, "", NULL);
758
759 /* should set XmNvisibleItemCount to 1 as 0 is invalid value */
760 list = XtNameToWidget(cdata->comp.widget, "*List");
761 XtVaSetValues(list, XmNvisibleItemCount, 1, NULL);
762
763 AWT_UNLOCK();
764}