1 /* |
|
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 |
|
43 extern struct ComponentIDs componentIDs; |
|
44 extern struct ContainerIDs containerIDs; |
|
45 extern struct MComponentPeerIDs mComponentPeerIDs; |
|
46 extern AwtGraphicsConfigDataPtr |
|
47 copyGraphicsConfigToPeer(JNIEnv *env, jobject this); |
|
48 |
|
49 static 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 |
|
101 static void |
|
102 Choice_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 |
|
121 static 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 */ |
|
252 JNIEXPORT 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 */ |
|
418 JNIEXPORT 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 */ |
|
433 JNIEXPORT 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 */ |
|
464 JNIEXPORT 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 */ |
|
525 JNIEXPORT 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 */ |
|
546 JNIEXPORT 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 */ |
|
615 JNIEXPORT 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 */ |
|
652 JNIEXPORT 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 */ |
|
692 JNIEXPORT 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 */ |
|
756 JNIEXPORT 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 */ |
|
797 JNIEXPORT 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 |
|
838 cleanup: |
|
839 if (strItems != NULL) { |
|
840 free(strItems); |
|
841 } |
|
842 AWT_UNLOCK(); |
|
843 } |
|