jdk/src/solaris/native/sun/awt/awt_Choice12.c
changeset 1211 b659a7cee935
parent 1210 7798f9e88bf9
parent 1203 3e5496df0d2b
child 1212 d718a4419361
equal deleted inserted replaced
1210:7798f9e88bf9 1211:b659a7cee935
     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 }