blob: 57f9e6d029e856cc510f91d2273d9672efca70be [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2001 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#include "awt_p.h"
31#include "java_awt_Component.h"
32#include "sun_awt_motif_MComponentPeer.h"
33#include "sun_awt_motif_MChoicePeer.h"
34
35#include "awt_Component.h"
36#include "awt_MToolkit.h"
37
38#include "multi_font.h"
39#include <jni.h>
40#include <jni_util.h>
41#include <Xm/CascadeBG.h>
42
43extern struct ComponentIDs componentIDs;
44extern struct ContainerIDs containerIDs;
45extern struct MComponentPeerIDs mComponentPeerIDs;
46extern AwtGraphicsConfigDataPtr
47 copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
48
49static void geometry_hook(Widget wid, Widget hooked_widget, XtGeometryHookData call_data) {
50 XtWidgetGeometry *request;
51 JNIEnv *env;
52 struct ChoiceData *cdata;
53 struct WidgetInfo *winfo = NULL;
54
55 jobject target;
56 jobject parent;
57 jint y, height;
58
59 if ((call_data->widget == hooked_widget) &&
60 (call_data->type == XtHpostGeometry) &&
61 (call_data->result == XtGeometryYes)) {
62
63 request = call_data->request;
64
65 env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
66 DASSERT(env != NULL);
67
68 winfo=findWidgetInfo(hooked_widget);
69
70 if (winfo != NULL && XmIsRowColumn(hooked_widget)) {
71 target = (*env)->GetObjectField(env, (jobject)winfo->peer, mComponentPeerIDs.target);
72 cdata = (struct ChoiceData *) JNU_GetLongFieldAsPtr(env, (jobject)winfo->peer, mComponentPeerIDs.pData);
73 DASSERT(target != NULL);
74 DASSERT(cdata != NULL && cdata->comp.widget != NULL)
75 if (request->request_mode & CWHeight) {
76 height = (*env)->GetIntField(env, target, componentIDs.height);
77 if (request->height > 0 && request->height != height) {
78 parent = (*env)->CallObjectMethod(env, target, componentIDs.getParent);
79 if ((parent != NULL) && ((*env)->GetObjectField(env, parent, containerIDs.layoutMgr) != NULL)) {
80 y = cdata->bounds_y;
81 if (request->height < cdata->bounds_height) {
82 y += (cdata->bounds_height - request->height) / 2;
83 }
84 XtVaSetValues(hooked_widget, XmNy, y, NULL);
85 (*env)->SetIntField(env, target, componentIDs.y, y);
86 }
87 if (parent != NULL) {
88 (*env)->DeleteLocalRef(env, parent);
89 }
90 }
91 (*env)->SetIntField(env, target, componentIDs.height, request->height);
92 }
93 if (request->request_mode & CWWidth) {
94 (*env)->SetIntField(env, target, componentIDs.width, request->width);
95 }
96 (*env)->DeleteLocalRef(env, target);
97 }
98 }
99}
100
101static void
102Choice_callback(Widget menu_item,
103 jobject this,
104 XmAnyCallbackStruct * cbs)
105{
106 intptr_t index;
107 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
108
109 XtVaGetValues(menu_item, XmNuserData, &index, NULL);
110 /* index stored in user-data is 1-based instead of 0-based because */
111 /* of a bug in XmNuserData */
112 index--;
113
114 JNU_CallMethodByName(env, NULL, this, "action", "(I)V", (jint)index);
115 if ((*env)->ExceptionOccurred(env)) {
116 (*env)->ExceptionDescribe(env);
117 (*env)->ExceptionClear(env);
118 }
119}
120
121static void addItems
122 (JNIEnv *env, jobject this, jstring *items, jsize nItems, jint index)
123{
124 char *citem = NULL;
125 struct ChoiceData *odata;
126 Widget bw;
127#define MAX_ARGC 10
128 Arg args[MAX_ARGC];
129 Cardinal argc, argc1;
130 jsize i;
131 Pixel bg;
132 Pixel fg;
133 short cols;
134 int32_t sheight;
135 Dimension height;
136 Widget *firstNewItem = NULL;
137
138 XmString mfstr = NULL;
139 XmFontList fontlist = NULL;
140 jobject font = awtJNI_GetFont(env, this);
141 Boolean IsMultiFont = awtJNI_IsMultiFont(env, font);
142
143 if ((items == NULL) || (nItems == 0)) {
144 return;
145 }
146
147 AWT_LOCK();
148
149 odata = (struct ChoiceData *)
150 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
151
152 if (odata == NULL) {
153 JNU_ThrowNullPointerException(env, "NullPointerException");
154 AWT_UNLOCK();
155
156 return;
157 }
158 if (odata->maxitems == 0 || (index + nItems) > odata->maxitems) {
159 odata->maxitems = index + nItems + 20;
160 if (odata->n_items > 0) {
161 /* grow the list of items */
162 odata->items = (Widget *)
163 realloc((void *) (odata->items)
164 ,sizeof(Widget) * odata->maxitems);
165 } else {
166 odata->items = (Widget *) malloc(sizeof(Widget) * odata->maxitems);
167 }
168 if (odata->items == NULL) {
169 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
170 AWT_UNLOCK();
171 return;
172 }
173 }
174 XtVaGetValues(odata->comp.widget, XmNbackground, &bg, NULL);
175 XtVaGetValues(odata->comp.widget, XmNforeground, &fg, NULL);
176
177 argc = 0;
178 XtSetArg(args[argc], XmNbackground, bg);
179 argc++;
180 XtSetArg(args[argc], XmNforeground, fg);
181 argc++;
182
183 firstNewItem = &(odata->items[index]);
184 for (i = 0; i < nItems; i++) {
185 argc1 = argc;
186 if (IsMultiFont) {
187 mfstr = awtJNI_MakeMultiFontString(env, items[i], font);
188 fontlist = awtJNI_GetFontList(env, font);
189 /* XXX: XmNuserData doesn't seem to work when passing in zero */
190 /* so we increment the index before passing it in. */
191 XtSetArg(args[argc1], XmNuserData, (XtPointer)((intptr_t)(index + i + 1)));
192 argc1++;
193 XtSetArg(args[argc1], XmNfontList, fontlist);
194 argc1++;
195 XtSetArg(args[argc1], XmNlabelString, mfstr);
196 argc1++;
197
198 DASSERT(!(argc1 > MAX_ARGC));
199
200 bw = XmCreatePushButton(odata->menu, "", args, argc1);
201
202 /* Free resurces */
203 if ( fontlist != NULL )
204 {
205 XmFontListFree(fontlist);
206 fontlist = NULL;
207 }
208 if (mfstr != NULL) {
209 XmStringFree(mfstr);
210 mfstr = NULL;
211 }
212 } else {
213 citem = (char *) JNU_GetStringPlatformChars(env, items[i], NULL);
214 /* XXX: XmNuserData doesn't seem to work when passing in zero */
215 /* so we increment the index before passing it in. */
216 XtSetArg(args[argc1], XmNuserData, (XtPointer)((intptr_t)(index + i + 1)));
217 argc1++;
218 DASSERT(!(argc1> MAX_ARGC));
219 bw = XmCreatePushButton(odata->menu, citem, args, argc1);
220 JNU_ReleaseStringPlatformChars(env, items[i], (const char *) citem);
221 citem = NULL;
222 }
223
224 XtAddCallback(bw,
225 XmNactivateCallback,
226 (XtCallbackProc) Choice_callback,
227 (XtPointer) JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.jniGlobalRef));
228 odata->items[index + i] = bw;
229 odata->n_items++;
230 }
231
232 XtManageChildren(firstNewItem, nItems);
233
234 sheight = DisplayHeight(awt_display, DefaultScreen(awt_display));
235
236 XtVaGetValues(odata->menu, XmNheight, &height, NULL);
237
238 while ( height > sheight ) {
239 cols = ++odata->n_columns;
240 XtVaSetValues(odata->menu, XmNnumColumns, cols, NULL);
241 XtVaGetValues(odata->menu, XmNheight, &height, NULL);
242 }
243
244 AWT_UNLOCK();
245}
246
247/*
248 * Class: sun_awt_motif_MChoicePeer
249 * Method: create
250 * Signature: (Lsun/awt/motif/MComponentPeer;)V
251 */
252JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_create
253 (JNIEnv * env, jobject this, jobject parent)
254{
255 struct ChoiceData *odata;
256 struct ComponentData *wdata;
257#undef MAX_ARGC
258#define MAX_ARGC 30
259 Arg args[MAX_ARGC];
260 Cardinal argc;
261 Pixel bg;
262 Pixel fg;
263 Widget label;
264 Widget button;
265 Widget hookobj;
266 jobject globalRef = awtJNI_CreateAndSetGlobalRef(env, this);
267 AwtGraphicsConfigDataPtr adata;
268 jobject target;
269 Dimension width = 0, height = 0;
270 jclass clsDimension;
271 jobject dimension;
272 jobject peer;
273
274 AWT_LOCK();
275
276 if (JNU_IsNull(env, parent)) {
277 JNU_ThrowNullPointerException(env, "NullPointerException");
278 return;
279 }
280
281 adata = copyGraphicsConfigToPeer(env, this);
282
283 wdata = (struct ComponentData *)
284 JNU_GetLongFieldAsPtr(env,parent,mComponentPeerIDs.pData);
285
286 if (wdata == NULL) {
287 JNU_ThrowNullPointerException(env, "NullPointerException");
288 AWT_UNLOCK();
289
290 return;
291 }
292
293 odata = ZALLOC(ChoiceData);
294 if (odata == NULL) {
295 JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
296 AWT_UNLOCK();
297 return;
298 }
299 JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,odata);
300
301 odata->items = NULL;
302 odata->maxitems = 0;
303 odata->n_items = 0;
304 odata->n_columns = 1;
305
306 XtVaGetValues(wdata->widget, XmNbackground, &bg, NULL);
307 XtVaGetValues(wdata->widget, XmNforeground, &fg, NULL);
308
309 argc = 0;
310 XtSetArg(args[argc], XmNx, 0);
311 argc++;
312 XtSetArg(args[argc], XmNy, 0);
313 argc++;
314 XtSetArg(args[argc], XmNvisual, adata->awt_visInfo.visual);
315 argc++;
316 XtSetArg(args[argc], XmNbackground, bg);
317 argc++;
318 XtSetArg(args[argc], XmNforeground, fg);
319 argc++;
320
321 XtSetArg(args[argc], XmNorientation, XmVERTICAL);
322 argc++;
323 XtSetArg(args[argc], XmNpacking, XmPACK_COLUMN);
324 argc++;
325 XtSetArg(args[argc], XmNnumColumns, (short)1);
326 argc++;
327 /* Fix for 4303064 by ibd@sparc.spb.su: pop-up shells will have
328 * ancestor_sensitive False if the parent was insensitive when the shell
329 * was created. Since XtSetSensitive on the parent will not modify the
330 * resource of the pop-up child, clients are advised to include a resource
331 * specification of the form '*TransientShell.ancestorSensitive: True' in
332 * the application defaults resource file or to otherwise ensure that the
333 * parent is sensitive when creating pop-up shells.
334 */
335 XtSetArg(args[argc], XmNancestorSensitive, True);
336 argc++;
337
338 DASSERT(!(argc > MAX_ARGC));
339 odata->menu = XmCreatePulldownMenu(wdata->widget, "pulldown", args, argc);
340
341
342 target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
343 clsDimension = (*env)->FindClass(env, "java/awt/Dimension");
344 dimension = JNU_CallMethodByName(env,
345 NULL,
346 this,
347 "getPreferredSize",
348 "()Ljava/awt/Dimension;").l;
349 DASSERT(clsDimension != NULL);
350 width = (Dimension)((*env)->GetIntField(env, dimension, (*env)->GetFieldID(env, clsDimension, "width" , "I")));
351 height = (Dimension)((*env)->GetIntField(env, dimension, (*env)->GetFieldID(env, clsDimension, "height", "I")));
352
353 argc = 0;
354 XtSetArg(args[argc], XmNx, 0);
355 argc++;
356 XtSetArg(args[argc], XmNy, 0);
357 argc++;
358 XtSetArg(args[argc], XmNwidth, width);
359 argc++;
360 XtSetArg(args[argc], XmNheight, height);
361 argc++;
362 XtSetArg(args[argc], XmNmarginHeight, 0);
363 argc++;
364 XtSetArg(args[argc], XmNmarginWidth, 0);
365 argc++;
366 XtSetArg(args[argc], XmNrecomputeSize, False);
367 argc++;
368 XtSetArg(args[argc], XmNresizeHeight, False);
369 argc++;
370 XtSetArg(args[argc], XmNresizeWidth, False);
371 argc++;
372 XtSetArg(args[argc], XmNspacing, False);
373 argc++;
374 XtSetArg(args[argc], XmNborderWidth, 0);
375 argc++;
376 XtSetArg(args[argc], XmNnavigationType, XmTAB_GROUP);
377 argc++;
378 XtSetArg(args[argc], XmNtraversalOn, True);
379 argc++;
380 XtSetArg(args[argc], XmNorientation, XmVERTICAL);
381 argc++;
382 XtSetArg(args[argc], XmNadjustMargin, False);
383 argc++;
384 XtSetArg(args[argc], XmNbackground, bg);
385 argc++;
386 XtSetArg(args[argc], XmNforeground, fg);
387 argc++;
388 XtSetArg(args[argc], XmNsubMenuId, odata->menu);
389 argc++;
390 XtSetArg (args[argc], XmNscreen,
391 ScreenOfDisplay(awt_display, adata->awt_visInfo.screen));
392 argc++;
393
394 DASSERT(!(argc > MAX_ARGC));
395 odata->comp.widget = XmCreateOptionMenu(wdata->widget, "", args, argc);
396
397 hookobj = XtHooksOfDisplay(XtDisplayOfObject(odata->comp.widget));
398 XtAddCallback(hookobj,
399 XtNgeometryHook,
400 (XtCallbackProc) geometry_hook,
401 (XtPointer) odata->comp.widget);
402
403 label = XmOptionLabelGadget(odata->comp.widget);
404 if (label != NULL) {
405 XtUnmanageChild(label);
406 }
407 XtSetMappedWhenManaged(odata->comp.widget, False);
408 XtManageChild(odata->comp.widget);
409
410 AWT_UNLOCK();
411}
412
413/*
414 * Class: sun_awt_motif_MChoicePeer
415 * Method: addItem
416 * Signature: (Ljava/lang/String;I)V
417 */
418JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_addItem
419 (JNIEnv *env, jobject this, jstring item, jint index)
420{
421 if (JNU_IsNull(env, item)) {
422 JNU_ThrowNullPointerException(env, "NullPointerException");
423 return;
424 }
425 addItems(env, this, &item, 1, index);
426}
427
428/*
429 * Class: sun_awt_motif_MChoicePeer
430 * Method: pSelect
431 * Signature: (I)V
432 */
433JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_pSelect
434 (JNIEnv *env, jobject this, jint index, jboolean init)
435{
436 struct ChoiceData *odata;
437
438 AWT_LOCK();
439
440 odata = (struct ChoiceData *)
441 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
442
443 if (odata == NULL) {
444 JNU_ThrowNullPointerException(env, "NullPointerException");
445 AWT_UNLOCK();
446 return;
447 }
448 if (index > odata->n_items || index < 0) {
449 JNU_ThrowIllegalArgumentException(env, "IllegalArgumentException");
450 AWT_UNLOCK();
451 return;
452 }
453 XtVaSetValues(odata->comp.widget,
454 XmNmenuHistory, odata->items[index],
455 NULL);
456 AWT_UNLOCK();
457}
458
459/*
460 * Class: sun_awt_motif_MChoicePeer
461 * Method: setFont
462 * Signature: (Ljava/awt/Font;)V
463 */
464JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_setFont
465 (JNIEnv *env, jobject this, jobject f)
466{
467 struct ChoiceData *cdata;
468 struct FontData *fdata;
469 XmFontList fontlist;
470 char *err;
471
472 if (JNU_IsNull(env, f)) {
473 JNU_ThrowNullPointerException(env, "NullPointerException");
474 return;
475 }
476 AWT_LOCK();
477
478 fdata = awtJNI_GetFontData(env, f, &err);
479 if (fdata == NULL) {
480 JNU_ThrowInternalError(env, err);
481 AWT_UNLOCK();
482 return;
483 }
484 cdata = (struct ChoiceData *)
485 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
486 if (cdata == NULL || cdata->comp.widget == NULL) {
487 JNU_ThrowNullPointerException(env, "NullPointerException");
488 AWT_UNLOCK();
489 return;
490 }
491 if (awtJNI_IsMultiFont(env, f)) {
492 fontlist = awtJNI_GetFontList(env, f);
493 } else {
494 fontlist = XmFontListCreate(fdata->xfont, "labelFont");
495 }
496
497 if (fontlist != NULL) {
498 jint i;
499
500 XtVaSetValues(cdata->comp.widget,
501 XmNfontList, fontlist,
502 NULL);
503 XtVaSetValues(cdata->menu,
504 XmNfontList, fontlist,
505 NULL);
506 for (i = 0; i < cdata->n_items; i++) {
507 XtVaSetValues(cdata->items[i],
508 XmNfontList, fontlist,
509 NULL);
510 }
511
512 XmFontListFree(fontlist);
513 } else {
514 JNU_ThrowNullPointerException(env, "NullPointerException");
515 }
516 AWT_UNLOCK();
517}
518
519/* Fix for bug 4326619 */
520/*
521 * Class: sun_awt_motif_MChoicePeer
522 * Method: freeNativeData
523 * Signature: ()V
524 */
525JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_freeNativeData
526 (JNIEnv *env, jobject this)
527{
528 struct ChoiceData *cdata;
529
530 AWT_LOCK();
531
532 cdata = (struct ChoiceData *)
533 JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
534
535 cdata->n_items = 0;
536 free((void *)cdata->items);
537 cdata->items = NULL;
538 AWT_UNLOCK();
539}
540
541/*
542 * Class: sun_awt_motif_MChoicePeer
543 * Method: setBackground
544 * Signature: (Ljava/awt/Color;)V
545 */
546JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_setBackground
547 (JNIEnv *env, jobject this, jobject c)
548{
549 struct ChoiceData *bdata;
550 Pixel bg;
551 Pixel fg;
552 WidgetList children;
553 Cardinal numChildren;
554 int32_t i;
555
556 if (JNU_IsNull(env, c)) {
557 JNU_ThrowNullPointerException(env, "NullPointerException: null color");
558 return;
559 }
560 AWT_LOCK();
561
562 bdata = (struct ChoiceData *)
563 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
564 if (bdata == NULL || bdata->comp.widget == NULL) {
565 JNU_ThrowNullPointerException(env, "NullPointerException");
566 AWT_UNLOCK();
567 return;
568 }
569 /* Get background color */
570 bg = awtJNI_GetColor(env, c);
571
572 /*
573 XmChangeColor(), in addtion to changing the background and
574 selection colors, also changes the foreground color to be
575 what it thinks should be. However, we want to use the color
576 that gets set by setForeground() instead. We therefore need to
577 save the current foreground color here, and then set it again
578 after the XmChangeColor() occurs.
579 */
580 XtVaGetValues(bdata->comp.widget, XmNforeground, &fg, NULL);
581
582 /* Set color */
583 XmChangeColor(bdata->comp.widget, bg);
584 XtVaSetValues(bdata->comp.widget, XmNforeground, fg, NULL);
585
586 /*
587 * The following recursion fixes a bug in Motif 2.1 that caused
588 * black colored choice buttons (change has no effect on Motif 1.2).
589 */
590 XtVaGetValues(bdata->comp.widget,
591 XmNchildren, &children,
592 XmNnumChildren, &numChildren,
593 NULL);
594 for (i = 0; i < numChildren; i++) {
595 XmChangeColor(children[i], bg);
596 XtVaSetValues(children[i], XmNforeground, fg, NULL);
597 }
598
599
600 XmChangeColor(bdata->menu, bg);
601 XtVaSetValues(bdata->menu, XmNforeground, fg, NULL);
602
603 for (i = 0; i < bdata->n_items; i++) {
604 XmChangeColor(bdata->items[i], bg);
605 XtVaSetValues(bdata->items[i], XmNforeground, fg, NULL);
606 }
607 AWT_FLUSH_UNLOCK();
608}
609
610/*
611 * Class: sun_awt_motif_MChoicePeer
612 * Method: setForeground
613 * Signature: (Ljava/awt/Color;)V
614 */
615JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_setForeground
616 (JNIEnv *env, jobject this, jobject c)
617{
618 struct ChoiceData *bdata;
619 Pixel color;
620 int32_t i;
621
622 if (JNU_IsNull(env, c)) {
623 JNU_ThrowNullPointerException(env, "NullPointerException: null color");
624 return;
625 }
626 AWT_LOCK();
627
628 bdata = (struct ChoiceData *)
629 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
630 if (bdata == NULL || bdata->comp.widget == NULL) {
631 JNU_ThrowNullPointerException(env, "NullPointerException");
632 AWT_UNLOCK();
633 return;
634 }
635 color = awtJNI_GetColor(env, c);
636
637 XtVaSetValues(bdata->comp.widget, XmNforeground, color, NULL);
638
639 XtVaSetValues(bdata->menu, XmNforeground, color, NULL);
640 for (i = 0; i < bdata->n_items; i++) {
641 XtVaSetValues(bdata->items[i], XmNforeground, color, NULL);
642 }
643
644 AWT_FLUSH_UNLOCK();
645}
646
647/*
648 * Class: sun_awt_motif_MChoicePeer
649 * Method: pReshape
650 * Signature: (IIII)V
651 */
652JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_pReshape
653 (JNIEnv *env, jobject this, jint x, jint y, jint w, jint h)
654{
655 struct ChoiceData *cdata;
656 Widget button;
657 jobject target;
658 Dimension width=0, height=0;
659 Position new_y = 0;
660
661 AWT_LOCK();
662
663 cdata = (struct ChoiceData *)
664 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
665 if (cdata == NULL || cdata->comp.widget == NULL) {
666 JNU_ThrowNullPointerException(env, "NullPointerException");
667 AWT_UNLOCK();
668 return;
669 }
670
671 button = XmOptionButtonGadget(cdata->comp.widget);
672 cdata->bounds_y = y;
673 cdata->bounds_height = h;
674 awt_util_reshape(cdata->comp.widget, x, y, w, h);
675 awt_util_reshape(button, x, y, w, h);
676
677 /* Bug 4255631 Solaris: Size returned by Choice.getSize() does not match
678 * actual size
679 */
680 XtVaGetValues(cdata->comp.widget, XmNy, &new_y, NULL);
681 XtVaGetValues(button, XmNwidth, &width, XmNheight, &height , NULL);
682 awt_util_reshape(cdata->comp.widget, x, new_y, width, height);
683
684 AWT_FLUSH_UNLOCK();
685}
686
687/*
688 * Class: sun_awt_motif_MChoicePeer
689 * Method: remove
690 * Signature: (I)V
691 */
692JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_remove
693 (JNIEnv *env, jobject this, jint index)
694{
695 struct ChoiceData *cdata;
696 Widget selected;
697 jint i;
698 short cols;
699 int32_t sheight;
700 Dimension height;
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 if (index < 0 || index > cdata->n_items) {
712 JNU_ThrowIllegalArgumentException(env, "IllegalArgumentException");
713 AWT_UNLOCK();
714 return;
715 }
716 XtUnmanageChild(cdata->items[index]);
717 awt_util_consumeAllXEvents(cdata->items[index]);
718 awt_util_cleanupBeforeDestroyWidget(cdata->items[index]);
719 XtDestroyWidget(cdata->items[index]);
720 for (i = index; i < cdata->n_items-1; i++) {
721 cdata->items[i] = cdata->items[i + 1];
722 /* need to reset stored index value, (adding 1 to disambiguate it */
723 /* from an arg list terminator) */
724 /* bug fix 4079027 robi.khan@eng */
725 XtVaSetValues(cdata->items[i], XmNuserData, (XtPointer)((intptr_t)(i+1)), NULL);
726 }
727 cdata->items[cdata->n_items-1] = NULL;
728 cdata->n_items--;
729
730 XtVaGetValues(cdata->menu, XmNheight, &height, NULL);
731
732 sheight = DisplayHeight(awt_display, DefaultScreen(awt_display));
733 cols = cdata->n_columns;
734
735 if (cols >1) {
736 /* first try to remove a column */
737 cols = --cdata->n_columns;
738 XtVaSetValues(cdata->menu, XmNnumColumns, cols, NULL);
739
740 /* then see if it fits, if not add it back */
741 XtVaGetValues(cdata->menu, XmNheight, &height, NULL);
742 if ( height > sheight ) {
743 cols = ++cdata->n_columns;
744 XtVaSetValues(cdata->menu, XmNnumColumns, cols, NULL);
745 }
746 }
747
748 AWT_UNLOCK();
749}
750
751/*
752 * Class: sun_awt_motif_MChoicePeer
753 * Method: removeAll
754 * Signature: ()V
755 */
756JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_removeAll
757 (JNIEnv *env, jobject this)
758{
759 struct ChoiceData *cdata;
760 Widget selected;
761 jint i;
762
763 AWT_LOCK();
764
765 cdata = (struct ChoiceData *)
766 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
767 if (cdata == NULL || cdata->comp.widget == NULL) {
768 JNU_ThrowNullPointerException(env, "NullPointerException");
769 AWT_UNLOCK();
770 return;
771 }
772
773 XtUnmanageChildren(cdata->items, cdata->n_items);
774
775 for (i = cdata->n_items-1; i >= 0; i--) {
776 awt_util_consumeAllXEvents(cdata->items[i]);
777 awt_util_cleanupBeforeDestroyWidget(cdata->items[i]);
778 XtDestroyWidget(cdata->items[i]);
779 cdata->items[i] = NULL;
780 }
781
782 cdata->n_items = 0;
783
784 if (cdata->n_columns > 1) {
785 cdata->n_columns = 1;
786 XtVaSetValues(cdata->menu, XmNnumColumns, cdata->n_columns, NULL);
787 }
788
789 AWT_UNLOCK();
790}
791
792/*
793 * Class: sun_awt_motif_MChoicePeer
794 * Method: appendItems
795 * Signature: ([Ljava/lang/String;)V
796 */
797JNIEXPORT void JNICALL Java_sun_awt_motif_MChoicePeer_appendItems
798 (JNIEnv *env, jobject this, jarray items)
799{
800 struct ChoiceData *odata = NULL;
801 jstring *strItems = NULL;
802 jsize nItems, i; // MP
803
804 if (JNU_IsNull(env, items)) {
805 return;
806 }
807 nItems = (*env)->GetArrayLength(env, items);
808 if (nItems == 0) {
809 return;
810 }
811
812 AWT_LOCK();
813
814 odata = (struct ChoiceData *)
815 JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
816
817 if (odata == NULL) {
818 JNU_ThrowNullPointerException(env, "NullPointerException");
819 goto cleanup;
820 }
821
822 strItems = (jstring *) malloc(sizeof(jstring) * nItems);
823 if (strItems == NULL) {
824 JNU_ThrowNullPointerException(env, "NullPointerException");
825 goto cleanup;
826 }
827
828 for (i = 0; i < nItems; i++) {
829 strItems[i] = (jstring)(*env)->GetObjectArrayElement(env, items, i);
830 if (JNU_IsNull(env, strItems[i])) {
831 JNU_ThrowNullPointerException(env, "NullPointerException");
832 goto cleanup;
833 }
834 }
835
836 addItems(env, this, strItems, nItems, odata->n_items);
837
838cleanup:
839 if (strItems != NULL) {
840 free(strItems);
841 }
842 AWT_UNLOCK();
843}