jdk/src/solaris/native/sun/awt/awt_PopupMenu.c
changeset 1211 b659a7cee935
parent 1210 7798f9e88bf9
parent 1203 3e5496df0d2b
child 1212 d718a4419361
--- a/jdk/src/solaris/native/sun/awt/awt_PopupMenu.c	Fri Sep 12 14:35:51 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,491 +0,0 @@
-/*
- * Copyright 1996-2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-#ifdef HEADLESS
-    #error This file should not be included in headless library
-#endif
-
-#include "awt_p.h"
-#include <Xm/Separator.h>
-#include <Xm/MenuShell.h>
-#include <Xm/RowColumn.h>
-#include "color.h"
-#include "java_awt_PopupMenu.h"
-#include "java_awt_Component.h"
-#include "java_awt_Event.h"
-#include "sun_awt_motif_MPopupMenuPeer.h"
-#include "sun_awt_motif_MComponentPeer.h"
-
-#include "awt_PopupMenu.h"
-#include "awt_MenuItem.h"
-#include "awt_Component.h"
-#include "awt_MenuComponent.h"
-#include "awt_Menu.h"
-#include "awt_Event.h"
-
-#include "multi_font.h"
-#include <jni.h>
-#include <jni_util.h>
-
-extern struct MMenuItemPeerIDs mMenuItemPeerIDs;
-extern struct MComponentPeerIDs mComponentPeerIDs;
-extern struct MenuComponentIDs menuComponentIDs;
-extern struct MenuItemIDs menuItemIDs;
-extern struct MenuIDs menuIDs;
-extern AwtGraphicsConfigDataPtr
-getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject parentPeer);
-extern Boolean keyboardGrabbed;
-Boolean poppingDown = False;
-
-struct MPopupMenuPeerIDs mPopupMenuPeerIDs;
-
-static Widget activePopup;
-
-void removePopupMenus() {
-    if (activePopup != NULL &&
-        XtIsManaged(activePopup))
-    {
-            XtUnmanageChild(activePopup);
-            activePopup = NULL;
-    }
-}
-
-Boolean awtMenuIsActive() {
-    return ((activePopup != NULL) || (awt_util_focusIsOnMenu(awt_display)));
-}
-
-struct ClientDataStruct {
-    struct ComponentData *wdata;
-    jobject mMenuItemPeerIDs;
-};
-
-/*
- * Class:     sun_awt_motif_MPopupMenuPeer
- * Method:    initIDs
- * Signature: ()V
- */
-
-/* This function gets called from the static initializer for
-   MPopupMenuPeer.java to initialize the methodIDs for methods that may
-   be accessed from C */
-
-JNIEXPORT void JNICALL Java_sun_awt_motif_MPopupMenuPeer_initIDs
-  (JNIEnv *env, jclass cls)
-{
-    mPopupMenuPeerIDs.destroyNativeWidgetAfterGettingTreeLock =
-        (*env)->GetMethodID(env, cls,
-                            "destroyNativeWidgetAfterGettingTreeLock", "()V");
-}
-
-extern Boolean skipNextNotifyWhileGrabbed;
-
-static void
-Popup_popUpCB(Widget w, XtPointer client_data, XtPointer calldata)
-{
-    skipNextNotifyWhileGrabbed = True;
-}
-/*
- * client_data is MPopupMenuPeer instance
- */
-static void
-Popup_popdownCB(Widget w, XtPointer client_data, XtPointer calldata)
-{
-    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    jobject target = NULL;
-
-    /*
-     * Fix for 4394847. Due to the race keyboard remains grabbed after menu
-     * was disposed. Clear the grab status here instead of processOneEvent.
-     */
-    poppingDown = True;
-    keyboardGrabbed = False;
-    skipNextNotifyWhileGrabbed = True;
-
-    XtRemoveCallback(w, XtNpopdownCallback,
-                     Popup_popdownCB, (XtPointer) client_data);
-
-    (*env)->CallVoidMethod(env, (jobject) client_data,
-        mPopupMenuPeerIDs.destroyNativeWidgetAfterGettingTreeLock);
-
-    if ((*env)->ExceptionOccurred(env)) {
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-    }
-}
-
-/*
- * Class:     sun_awt_motif_MPopupMenuPeer
- * Method:    createMenu
- * Signature: (Lsun/awt/motif/MComponentPeer;)V
- */
-JNIEXPORT void JNICALL Java_sun_awt_motif_MPopupMenuPeer_createMenu
-  (JNIEnv *env, jobject this, jobject parent)
-{
-    struct ComponentData *wdata;
-    struct MenuData *mdata;
-    struct FontData *fdata;
-    char *ctitle = NULL;
-    int32_t argc;
-#define MAX_ARGC 10
-    Arg args[MAX_ARGC];
-    Pixel bg;
-    Pixel fg;
-    XmFontList fontlist = NULL;
-    XmString mfstr = NULL;
-    jobject font;
-    jobject target;
-    jobject targetFont;
-    jobject label;
-    jboolean IsMultiFont;
-    jboolean tearOff;
-    jobject globalRef = (*env)->NewGlobalRef(env, this);
-    AwtGraphicsConfigDataPtr adata;
-
-    JNU_SetLongFieldFromPtr(env, this,
-                            mMenuItemPeerIDs.jniGlobalRef, globalRef);
-
-
-    AWT_LOCK();
-
-    if (JNU_IsNull(env, parent)) {
-        JNU_ThrowNullPointerException(env, "NullPointerException");
-        AWT_UNLOCK();
-        return;
-    }
-    target =
-      (*env)->GetObjectField(env, this, mMenuItemPeerIDs.target);
-    wdata = (struct ComponentData *)
-      JNU_GetLongFieldAsPtr(env, parent, mComponentPeerIDs.pData);
-
-    if (wdata == NULL || JNU_IsNull(env, target)) {
-        JNU_ThrowNullPointerException(env, "NullPointerException");
-        AWT_UNLOCK();
-        return;
-    }
-    mdata = ZALLOC(MenuData);
-    if (mdata == NULL) {
-        JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
-        AWT_UNLOCK();
-        return;
-    }
-    JNU_SetLongFieldFromPtr(env, this, mMenuItemPeerIDs.pData, mdata);
-
-    adata = getGraphicsConfigFromComponentPeer(env, parent);
-
-    /*
-     * Why are these different?
-     */
-    font = JNU_CallMethodByName(env, NULL, target, "getFont_NoClientCode",
-                                "()Ljava/awt/Font;").l;
-    targetFont =
-      (*env)->GetObjectField(env, target, menuComponentIDs.font);
-    if (!JNU_IsNull(env, targetFont) &&
-        (fdata = awtJNI_GetFontData(env, targetFont, NULL)) != NULL) {
-        IsMultiFont = awtJNI_IsMultiFont(env, targetFont);
-    } else {
-        IsMultiFont = awtJNI_IsMultiFont(env, font);
-    }
-
-    label = (*env)->GetObjectField(env, target, menuItemIDs.label);
-    if (JNU_IsNull(env, label)) {
-        mfstr = XmStringCreateLocalized("");
-        ctitle = "";
-    } else {
-        if (IsMultiFont) {
-            mfstr = awtJNI_MakeMultiFontString(env, label, font);
-        } else {
-            ctitle = (char *) JNU_GetStringPlatformChars(env, label, NULL);
-        }
-    }
-
-    XtVaGetValues(wdata->widget, XmNbackground, &bg, NULL);
-    XtVaGetValues(wdata->widget, XmNforeground, &fg, NULL);
-
-    argc = 0;
-    XtSetArg(args[argc], XmNbackground, bg);
-    argc++;
-    XtSetArg(args[argc], XmNforeground, fg);
-    argc++;
-    tearOff = (*env)->GetBooleanField(env, target, menuIDs.tearOff);
-    if (tearOff) {
-        XtSetArg(args[argc], XmNtearOffModel, XmTEAR_OFF_ENABLED);
-        argc++;
-    }
-    if (!JNU_IsNull(env, targetFont)
-        && (fdata = awtJNI_GetFontData(env, targetFont, NULL)) != NULL) {
-        if (IsMultiFont) {
-            fontlist = awtJNI_GetFontList(env, targetFont);
-        } else {
-            fontlist = XmFontListCreate(fdata->xfont, "labelFont");
-        }
-
-        XtSetArg(args[argc], XmNfontList, fontlist);
-        argc++;
-    } else {
-        if (IsMultiFont) {
-            fontlist = awtJNI_GetFontList(env, font);
-            XtSetArg(args[argc], XmNfontList, fontlist);
-            argc++;
-        }
-    }
-
-    XtSetArg(args[argc], XmNvisual, adata->awt_visInfo.visual);
-    argc++;
-    XtSetArg (args[argc], XmNscreen,
-              ScreenOfDisplay(awt_display,
-                              adata->awt_visInfo.screen));
-    argc++;
-
-    if (IsMultiFont) {
-        DASSERT(!(argc > MAX_ARGC));
-        mdata->itemData.comp.widget = XmCreatePopupMenu(wdata->widget,
-                                                        "",
-                                                        args,
-                                                        argc);
-    } else {
-        DASSERT(!(argc > MAX_ARGC));
-        mdata->itemData.comp.widget = XmCreatePopupMenu(wdata->widget,
-                                                        ctitle,
-                                                        args,
-                                                        argc);
-    }
-    awt_addMenuWidget(mdata->itemData.comp.widget);
-
-    /*
-     * Fix for bug 4180147 -
-     * screen can be frozen when interacting with MB3 using AWT on Motif
-     */
-    XtUngrabButton(wdata->widget, AnyButton, AnyModifier);
-    XtUngrabPointer(wdata->widget, CurrentTime);
-
-    /* fix for bug #4169155: Popup menus get a leading separator on Motif
-       system.
-       Additional check that title string is not empty*/
-    if (!JNU_IsNull(env, label) &&
-        (*env)->GetStringUTFLength( env, label) != (jsize)0 ) {
-        if (IsMultiFont) {
-            XtVaCreateManagedWidget("",
-                                    xmLabelWidgetClass,
-                                    mdata->itemData.comp.widget,
-                                    XmNfontList, fontlist,
-                                    XmNlabelString, mfstr,
-                                    XmNbackground, bg,
-                                    XmNforeground, fg,
-                                    XmNhighlightColor, fg,
-                                    NULL);
-            XmStringFree(mfstr);
-        } else {
-            XmString xmstr = XmStringCreateLocalized(ctitle);
-
-            XtVaCreateManagedWidget(ctitle,
-                                    xmLabelWidgetClass,
-                                    mdata->itemData.comp.widget,
-                                    XmNlabelString, xmstr,
-                                    XmNbackground, bg,
-                                    XmNforeground, fg,
-                                    XmNhighlightColor, fg,
-                                    NULL);
-            XmStringFree(xmstr);
-            JNU_ReleaseStringPlatformChars(env, label, (const char *) ctitle);
-        }
-        /* Create separator */
-        XtVaCreateManagedWidget("",
-                                xmSeparatorWidgetClass,
-                                mdata->itemData.comp.widget,
-                                XmNbackground, bg,
-                                XmNforeground, fg,
-                                NULL);
-    }
-    if (tearOff) {
-        Widget tearOffWidget = XmGetTearOffControl(mdata->itemData.comp.widget);
-
-        XtVaSetValues(tearOffWidget,
-                      XmNbackground, bg,
-                      XmNforeground, fg,
-                      XmNhighlightColor, fg,
-                      NULL);
-    }
-    mdata->comp.widget = mdata->itemData.comp.widget;
-
-    if (!JNU_IsNull(env, targetFont)) {
-        XmFontListFree(fontlist);
-    }
-    XtSetSensitive(mdata->comp.widget,
-      ((*env)->GetBooleanField(env, target, menuItemIDs.enabled) ?
-       True : False));
-
-    AWT_UNLOCK();
-}
-
-/*
- * Class:     sun_awt_motif_MPopupMenuPeer
- * Method:    pShow
- * Signature: (Ljava/awt/Event;IILsun/awt/motif/MComponentPeer;)V
- */
-JNIEXPORT void JNICALL Java_sun_awt_motif_MPopupMenuPeer_pShow
-  (JNIEnv *env, jobject this, jobject event, jint x, jint y, jobject origin)
-{
-    struct MenuData *mdata;
-    struct ComponentData *wdata;
-    XButtonEvent *bevent;
-    XButtonEvent *newEvent = NULL;
-    void *data;
-
-    AWT_LOCK();
-
-    mdata = (struct MenuData *)
-      JNU_GetLongFieldAsPtr(env, this, mMenuItemPeerIDs.pData);
-    if (mdata == NULL || JNU_IsNull(env, event)) {
-        JNU_ThrowNullPointerException(env, "NullPointerException");
-        AWT_UNLOCK();
-        return;
-    }
-
-    wdata = (struct ComponentData *)
-        JNU_GetLongFieldAsPtr(env, origin, mComponentPeerIDs.pData);
-
-    if ( wdata == NULL || wdata->widget == NULL ) { /* 425598 */
-        JNU_ThrowNullPointerException(env, "NullPointerException"); /* 425598 */
-        AWT_UNLOCK(); /* 425598 */
-        return; /* 425598 */
-    } /* 425598 */
-
-    if (!XtIsRealized(wdata->widget)) {
-        JNU_ThrowInternalError(env, "widget not visible on screen");
-        AWT_UNLOCK();
-        return;
-    }
-
-    /*
-     * Fix for BugTraq ID 4186663 - Pural PopupMenus appear at the same time.
-     * If another popup is currently visible hide it.
-     */
-    if (activePopup != NULL &&
-        activePopup != mdata->comp.widget &&
-        XtIsObject(activePopup) &&
-        XtIsManaged(activePopup)) {
-            removePopupMenus();
-    }
-
-    /* If the raw x event is not available, then we must use an unfortunate
-     * round-trip call to XTranslateCoordiates to get the root coordinates.
-     */
-    data = JNU_GetLongFieldAsPtr(env, event, eventIDs.data);
-    if (data == NULL || ((XEvent *) data)->type != ButtonPress) {
-        int32_t rx, ry;
-        Window root, win;
-
-        root = RootWindowOfScreen(XtScreen(wdata->widget));
-        XTranslateCoordinates(awt_display,
-                              XtWindow(wdata->widget),
-                              root,
-                              (int32_t) x, (int32_t) y,
-                              &rx, &ry,
-                              &win);
-        /*
-                printf("translated coords %d,%d to root %d,%d\n", x, y, rx, ry);
-        */
-
-        newEvent = (XButtonEvent *) malloc(sizeof(XButtonEvent));
-        newEvent->type = ButtonPress;
-        newEvent->display = awt_display;
-        newEvent->window = XtWindow(wdata->widget);
-        newEvent->time = awt_util_getCurrentServerTime();
-        newEvent->x = (int32_t) x;
-        newEvent->y = (int32_t) y;
-        newEvent->x_root = rx;
-        newEvent->y_root = ry;
-        bevent = newEvent;
-
-    } else {
-        bevent = (XButtonEvent *) data;
-    }
-
-    XtAddCallback(XtParent(mdata->comp.widget), XtNpopdownCallback,
-                  Popup_popdownCB,
-                  (XtPointer)
-                  JNU_GetLongFieldAsPtr(env, this,
-                                        mMenuItemPeerIDs.jniGlobalRef));
-
-    XtAddCallback(XtParent(mdata->comp.widget), XtNpopupCallback,
-                  Popup_popUpCB,
-                  (XtPointer)
-                  JNU_GetLongFieldAsPtr(env, this,
-                                        mMenuItemPeerIDs.jniGlobalRef));
-
-
-    XmMenuPosition(mdata->comp.widget, bevent);
-    XtManageChild(mdata->comp.widget);
-
-    /*
-     * Fix for BugTraq ID 4186663 - Pural PopupMenus appear at the same time.
-     * Store the pointer to the currently showing popup.
-     */
-    activePopup = mdata->comp.widget;
-
-    if (newEvent) {
-        free((void *) newEvent);
-    }
-    AWT_UNLOCK();
-}
-
-/*
- * Class:     sun_awt_motif_MPopupMenuPeer
- * Method:    pDispose
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_awt_motif_MPopupMenuPeer_pDispose
-  (JNIEnv *env, jobject this)
-{
-    struct MenuData *mdata;
-
-    AWT_LOCK();
-
-    mdata = (struct MenuData *)
-      JNU_GetLongFieldAsPtr(env, this, mMenuItemPeerIDs.pData);
-
-    if (mdata == NULL) {
-        AWT_UNLOCK();
-        return;
-    }
-    /*
-     * Fix for BugTraq ID 4186663 - Pural PopupMenus appear at the same time.
-     * Clear the pointer to the currently showing popup.
-     */
-    if (activePopup == mdata->comp.widget) {
-        activePopup = NULL;
-    }
-    awt_delMenuWidget(mdata->itemData.comp.widget);
-    XtUnmanageChild(mdata->comp.widget);
-    awt_util_consumeAllXEvents(mdata->comp.widget);
-    XtDestroyWidget(mdata->comp.widget);
-    free((void *) mdata);
-    (*env)->SetLongField(env, this, mMenuItemPeerIDs.pData, (jlong)0);
-
-    awtJNI_DeleteGlobalMenuRef(env, this);
-
-    poppingDown = False;
-    AWT_UNLOCK();
-}