jdk/src/solaris/native/sun/awt/awt_TopLevel.c
changeset 1192 715cf9378c53
parent 1051 90cf935adb35
parent 1191 f142c1da78c2
child 1193 41afb8ee8f45
equal deleted inserted replaced
1051:90cf935adb35 1192:715cf9378c53
     1 /*
       
     2  * Copyright 1999-2007 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 
       
    32 #include <X11/Shell.h>
       
    33 #include <Xm/VendorS.h>
       
    34 #include <Xm/Form.h>
       
    35 #include <Xm/DialogS.h>
       
    36 #include <Xm/AtomMgr.h>
       
    37 #include <Xm/Protocols.h>
       
    38 #include <Xm/MenuShell.h>
       
    39 #include <Xm/MwmUtil.h>
       
    40 #include "VDrawingArea.h"
       
    41 
       
    42 #ifdef DEBUG
       
    43 #  include <X11/Xmu/Editres.h>
       
    44 #endif
       
    45 
       
    46 #include <jni.h>
       
    47 #include <jni_util.h>
       
    48 
       
    49 /* JNI headers */
       
    50 #include "java_awt_Color.h"
       
    51 #include "java_awt_Component.h"
       
    52 #include "java_awt_Dialog.h"
       
    53 #include "java_awt_Font.h"
       
    54 #include "java_awt_Frame.h"
       
    55 #include "java_awt_Image.h"
       
    56 #include "java_awt_Insets.h"
       
    57 #include "java_awt_Insets.h"
       
    58 #include "java_awt_MenuBar.h"
       
    59 #include "java_awt_Window.h"
       
    60 #include "java_awt_event_FocusEvent.h"
       
    61 #include "java_awt_TrayIcon.h"
       
    62 #include "sun_awt_EmbeddedFrame.h"
       
    63 #include "sun_awt_motif_MComponentPeer.h"
       
    64 #include "sun_awt_motif_MDialogPeer.h"
       
    65 #include "sun_awt_motif_MEmbeddedFramePeer.h"
       
    66 #include "sun_awt_motif_MFramePeer.h"
       
    67 #include "sun_awt_motif_MMenuBarPeer.h"
       
    68 #include "sun_awt_motif_MWindowPeer.h"
       
    69 
       
    70 /* JNI field and method ids */
       
    71 #include "awt_Component.h"
       
    72 #include "awt_GraphicsEnv.h"
       
    73 #include "awt_Insets.h"
       
    74 #include "awt_MenuBar.h"
       
    75 #include "awt_Window.h"
       
    76 #include "awt_KeyboardFocusManager.h"
       
    77 #include "awt_MToolkit.h"
       
    78 #include "awt_Plugin.h"
       
    79 
       
    80 #include "color.h"
       
    81 #include "canvas.h"
       
    82 #include "awt_util.h"
       
    83 #include "img_util.h"
       
    84 #include "awt_wm.h"
       
    85 #include "awt_util.h"
       
    86 #include "awt_xembed.h"
       
    87 
       
    88 
       
    89 #ifdef __linux__
       
    90 void adjustStatusWindow(Widget shell);
       
    91 #endif
       
    92 /* For the moment only InputMethodWindow is taking advantage of
       
    93 ** the posibility for different decor styles
       
    94 ** values could be passed are the MWM_DECOR defines
       
    95 ** for the moment we are full on or full off.
       
    96 */
       
    97 #define AWT_NO_DECOR    0x0
       
    98 #define AWT_FULL_DECOR  MWM_DECOR_ALL
       
    99 
       
   100 static void reshape(JNIEnv *env, jobject this, struct FrameData *wdata,
       
   101                     jint x, jint y, jint w, jint h, Boolean setXY);
       
   102 Widget findTopLevelByShell(Widget widget);
       
   103 
       
   104 extern EmbeddedFrame *theEmbeddedFrameList;
       
   105 extern struct ComponentIDs componentIDs;
       
   106 extern struct MMenuBarPeerIDs mMenuBarPeerIDs;
       
   107 extern struct MComponentPeerIDs mComponentPeerIDs;
       
   108 struct WindowIDs windowIDs;
       
   109 struct MWindowPeerIDs mWindowPeerIDs;
       
   110 extern struct InsetsIDs insetsIDs;
       
   111 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
       
   112 extern struct KeyboardFocusManagerIDs keyboardFocusManagerIDs;
       
   113 extern struct X11GraphicsDeviceIDs x11GraphicsDeviceIDs;
       
   114 
       
   115 #ifndef NOMODALFIX
       
   116 extern Boolean awt_isModal();
       
   117 extern Boolean awt_isWidgetModal(Widget w);
       
   118 extern void awt_shellPoppedUp(Widget shell, XtPointer c, XtPointer d);
       
   119 extern void awt_shellPoppedDown(Widget shell, XtPointer c, XtPointer d);
       
   120 #endif //NOMODALFIX
       
   121 
       
   122 static jclass inputMethodWindowClass = NULL;
       
   123 
       
   124 static int32_t globalTopGuess    = 0;
       
   125 static int32_t globalLeftGuess   = 0;
       
   126 static int32_t globalBottomGuess = 0;
       
   127 static int32_t globalRightGuess  = 0;
       
   128 
       
   129 
       
   130 // Atom used for otlogenniy top-level disposal
       
   131 static Atom _XA_JAVA_DISPOSE_PROPERTY_ATOM = 0;
       
   132 
       
   133 /*
       
   134  * Fix for bug 4141361
       
   135  *
       
   136  * We keep a linked list of the FrameData information for
       
   137  * every top level window.
       
   138  */
       
   139 struct FrameDataList {
       
   140     struct FrameData* wdata;
       
   141     struct FrameDataList* next;
       
   142 };
       
   143 
       
   144 static struct FrameDataList* allTopLevel = NULL;
       
   145 
       
   146 extern void checkNewXineramaScreen(JNIEnv* env, jobject peer,
       
   147                                    struct FrameData* wdata,
       
   148                                    int32_t newX, int32_t newY,
       
   149                                    int32_t newWidth, int32_t newHeight);
       
   150 
       
   151 // Returns false if this Window is non-focusable
       
   152 // or its nearest decorated parent is non-focusable.
       
   153 Boolean isFocusableWindowByPeer(JNIEnv * env, jobject peer) {
       
   154     jobject target, decoratedParent;
       
   155     struct FrameData *wdata;
       
   156     Boolean focusable;
       
   157 
       
   158     wdata = (struct FrameData *)JNU_GetLongFieldAsPtr(env, peer, mComponentPeerIDs.pData);
       
   159     DASSERT(wdata != NULL);
       
   160 
       
   161     target = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target);
       
   162     DASSERT(target != NULL);
       
   163 
       
   164     decoratedParent = getOwningFrameOrDialog(target, env);
       
   165     (*env)->DeleteLocalRef(env, target);
       
   166 
       
   167     if (decoratedParent == NULL) {
       
   168         return wdata->isFocusableWindow;
       
   169     } else {
       
   170         jobject parentPeer = (*env)->GetObjectField(env, decoratedParent, componentIDs.peer);
       
   171         DASSERT(parentPeer != NULL);
       
   172         focusable = wdata->isFocusableWindow && isFocusableWindowByPeer(env, parentPeer);
       
   173 
       
   174         (*env)->DeleteLocalRef(env, decoratedParent);
       
   175         (*env)->DeleteLocalRef(env, parentPeer);
       
   176     }
       
   177     return focusable;
       
   178 }
       
   179 
       
   180 // Returns false if this shell's Java Window is non-focusable
       
   181 // or its nearest decorated parent is non-focusable.
       
   182 // Returns true otherwise or if any of parameters is NULL
       
   183 Boolean isFocusableWindowByShell(JNIEnv* env, Widget shell) {
       
   184     Widget toplevel;
       
   185     jobject peer;
       
   186     Boolean focusable;
       
   187 
       
   188     DASSERT(shell != NULL && XtIsShell(shell));
       
   189     if (shell == NULL) return True;
       
   190     if (!XtIsShell(shell)) return True;
       
   191 
       
   192     toplevel = findTopLevelByShell(shell);
       
   193     if (toplevel == NULL) {
       
   194         return True;
       
   195     }
       
   196     peer = findPeer(&toplevel);
       
   197     DASSERT(peer != NULL);
       
   198 
       
   199     if (env == NULL) {
       
   200         env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   201     }
       
   202     return isFocusableWindowByPeer(env, peer);
       
   203 }
       
   204 
       
   205 
       
   206 // Returns Shell widget - the parent of this child
       
   207 Widget getShellWidget(Widget child) {
       
   208 
       
   209     while (child != NULL && !XtIsShell(child)) {
       
   210         child = XtParent(child);
       
   211     }
       
   212     return child;
       
   213 }
       
   214 
       
   215 // Returns false if the parent shell of this widget is non-focusable Java Window.
       
   216 // Returns false otherwise.
       
   217 // Doesn't accept NULL parameters.
       
   218 Boolean isFocusableComponentTopLevelByWidget(JNIEnv * env, Widget child) {
       
   219     Widget shell = NULL;
       
   220     shell = getShellWidget(child);
       
   221     DASSERT(shell);
       
   222     return isFocusableWindowByShell(env, shell);
       
   223 }
       
   224 
       
   225 
       
   226 /*
       
   227  * Add a new element into the top level window list
       
   228  */
       
   229 void addTopLevel(struct FrameData* wdata) {
       
   230     struct FrameDataList* newNode;
       
   231     newNode = (struct FrameDataList*)
       
   232         malloc(sizeof(struct FrameDataList));
       
   233     newNode->wdata = wdata;
       
   234     newNode->next = allTopLevel;
       
   235     allTopLevel = newNode;
       
   236 }
       
   237 
       
   238 /*
       
   239  * Remove an element from the top level window list
       
   240  * (recursive)
       
   241  */
       
   242 Boolean removeTopLevelR(struct FrameDataList** ptr,
       
   243     struct FrameData* wdata) {
       
   244     struct FrameDataList* node = *ptr;
       
   245     if (node == NULL) {
       
   246         return False;
       
   247     }
       
   248     if (node->wdata == wdata) {
       
   249         *ptr = node->next;
       
   250         free(node);
       
   251         return True;
       
   252     }
       
   253     return removeTopLevelR(&(node->next), wdata);
       
   254 }
       
   255 
       
   256 Boolean removeTopLevel(struct FrameData* wdata) {
       
   257     return removeTopLevelR(&allTopLevel, wdata);
       
   258 }
       
   259 
       
   260 /*
       
   261  * Return the Widget ID of the top level window underneath the
       
   262  * mouse pointer.
       
   263  */
       
   264 Widget awt_GetWidgetAtPointer() {
       
   265     struct FrameDataList* ptr = allTopLevel;
       
   266     Window rootWindow, childWindow, mainWindow;
       
   267     int32_t xw, yw, xr, yr;
       
   268     uint32_t keys;
       
   269     while (ptr != NULL) {
       
   270         mainWindow = XtWindow(ptr->wdata->mainWindow);
       
   271         XQueryPointer(awt_display, mainWindow,
       
   272             &rootWindow, &childWindow, &xr, &yr, &xw, &yw, &keys);
       
   273         if (childWindow != None) {
       
   274             return ptr->wdata->winData.comp.widget;
       
   275         }
       
   276         ptr = ptr->next;
       
   277     }
       
   278     return NULL;
       
   279 }
       
   280 
       
   281 Widget findFocusProxy(Widget widget) {
       
   282   struct FrameDataList* ptr = allTopLevel;
       
   283   for (ptr = allTopLevel; ptr != NULL; ptr = ptr->next) {
       
   284     if (ptr->wdata->winData.comp.widget == widget) {
       
   285       return ptr->wdata->focusProxy;
       
   286     }
       
   287   }
       
   288   return NULL;
       
   289 }
       
   290 
       
   291 Widget findTopLevelByShell(Widget widget) {
       
   292   struct FrameDataList* ptr;
       
   293   for (ptr = allTopLevel; ptr != NULL; ptr = ptr->next) {
       
   294       if (ptr->wdata->winData.shell == widget) {
       
   295           return ptr->wdata->winData.comp.widget;
       
   296       }
       
   297   }
       
   298   return NULL;
       
   299 }
       
   300 
       
   301 void
       
   302 awt_Frame_guessInsets(struct FrameData *wdata)
       
   303 {
       
   304     if (wdata->decor == AWT_NO_DECOR ) {
       
   305         wdata->top    = wdata->topGuess    = 0;
       
   306         wdata->left   = wdata->leftGuess   = 0;
       
   307         wdata->bottom = wdata->bottomGuess = 0;
       
   308         wdata->right  = wdata->rightGuess  = 0;
       
   309         return;
       
   310     }
       
   311 
       
   312     if (globalTopGuess == 0) {
       
   313         char *insets_env;
       
   314 
       
   315         if (wdata->top >= 0) {
       
   316             /* insets were set on wdata by System Properties */
       
   317             globalTopGuess    = wdata->top;
       
   318             globalLeftGuess   = wdata->left;
       
   319             globalBottomGuess = wdata->bottom;
       
   320             globalRightGuess  = wdata->right;
       
   321         }
       
   322         else switch (awt_wm_getRunningWM()) {
       
   323         case ENLIGHTEN_WM:
       
   324             globalTopGuess    = 19;
       
   325             globalLeftGuess   =  4;
       
   326             globalBottomGuess =  4;
       
   327             globalRightGuess  =  4;
       
   328             break;
       
   329 
       
   330         case CDE_WM:
       
   331             globalTopGuess    = 28;
       
   332             globalLeftGuess   =  6;
       
   333             globalBottomGuess =  6;
       
   334             globalRightGuess  =  6;
       
   335             break;
       
   336 
       
   337         case MOTIF_WM:
       
   338         case OPENLOOK_WM:
       
   339         default:
       
   340             globalTopGuess    = 25;
       
   341             globalLeftGuess   =  5;
       
   342             globalBottomGuess =  5;
       
   343             globalRightGuess  =  5;
       
   344             break;
       
   345         }
       
   346 
       
   347         if ((insets_env = getenv("AWT_INSETS")) != NULL) {
       
   348             int guess = atoi(insets_env);
       
   349             globalTopGuess    = (guess & 0xff00) >> 8;
       
   350             globalLeftGuess   = guess & 0x00ff;
       
   351             globalBottomGuess = wdata->leftGuess;
       
   352             globalRightGuess  = wdata->leftGuess;
       
   353         }
       
   354 
       
   355         /* don't allow bizarly large insets */
       
   356         if ((globalTopGuess > 64) || (globalTopGuess < 0))
       
   357             globalTopGuess = 28;
       
   358         if ((globalLeftGuess > 32) || (globalLeftGuess < 0))
       
   359             globalLeftGuess = 6;
       
   360         if ((globalBottomGuess > 32) || (globalBottomGuess < 0))
       
   361             globalBottomGuess = 6;
       
   362         if ((globalRightGuess > 32) || (globalRightGuess < 0))
       
   363             globalRightGuess = 6;
       
   364     }
       
   365 
       
   366     wdata->top    = wdata->topGuess    = globalTopGuess;
       
   367     wdata->left   = wdata->leftGuess   = globalLeftGuess;
       
   368     wdata->bottom = wdata->bottomGuess = globalBottomGuess;
       
   369     wdata->right  = wdata->rightGuess  = globalRightGuess;
       
   370 }
       
   371 
       
   372 /*
       
   373  * To keep input method windows floating, maintain a list of all
       
   374  * input method windows here.  When some top level window gets
       
   375  * activated, moved, or resized, these input method windows need
       
   376  * to be brought on top.
       
   377  */
       
   378 static struct FrameDataList* allInputMethodWindow = NULL;
       
   379 
       
   380 /*
       
   381  * Add a new element into the input method window list
       
   382  */
       
   383 void addInputMethodWindow(struct FrameData* wdata) {
       
   384     struct FrameDataList* newNode;
       
   385     newNode = (struct FrameDataList*)
       
   386         malloc(sizeof(struct FrameDataList));
       
   387     newNode->wdata = wdata;
       
   388     newNode->next = allInputMethodWindow;
       
   389     allInputMethodWindow = newNode;
       
   390 }
       
   391 
       
   392 /*
       
   393  * Remove an element from the top level window list
       
   394  * (recursive)
       
   395  */
       
   396 Boolean removeInputMethodWindowR(struct FrameDataList** ptr,
       
   397     struct FrameData* wdata) {
       
   398     struct FrameDataList* node = *ptr;
       
   399     if (node == NULL) {
       
   400         return False;
       
   401     }
       
   402     if (node->wdata == wdata) {
       
   403         *ptr = node->next;
       
   404         free(node);
       
   405         return True;
       
   406     }
       
   407     return removeInputMethodWindowR(&(node->next), wdata);
       
   408 }
       
   409 
       
   410 Boolean removeInputMethodWindow(struct FrameData* wdata) {
       
   411     return removeInputMethodWindowR(&allInputMethodWindow, wdata);
       
   412 }
       
   413 
       
   414 /*
       
   415  * Raise input method windows
       
   416  */
       
   417 void raiseInputMethodWindow(struct FrameData* wdata) {
       
   418     struct FrameDataList* node = allInputMethodWindow;
       
   419 
       
   420     if (wdata->isInputMethodWindow) {
       
   421         return;
       
   422     }
       
   423 
       
   424     while (node != NULL) {
       
   425         XRaiseWindow(awt_display, XtWindow(node->wdata->winData.shell));
       
   426         node = node->next;
       
   427     }
       
   428 }
       
   429 
       
   430 /* fieldIDs for Frame fields that may be accessed from C */
       
   431 static struct FrameIDs {
       
   432     jfieldID resizable;
       
   433     jfieldID state;
       
   434 } frameIDs;
       
   435 
       
   436 /*
       
   437  * Class:     java_awt_Frame
       
   438  * Method:    initIDs
       
   439  * Signature: ()V
       
   440  */
       
   441 
       
   442 /* This function gets called from the static initializer for Frame.java
       
   443    to initialize the fieldIDs for fields that may be accessed from C */
       
   444 JNIEXPORT void JNICALL
       
   445 Java_java_awt_Frame_initIDs
       
   446   (JNIEnv *env, jclass cls)
       
   447 {
       
   448     frameIDs.resizable = (*env)->GetFieldID(env, cls, "resizable", "Z");
       
   449     frameIDs.state = (*env)->GetFieldID(env, cls, "state", "I");
       
   450 }
       
   451 
       
   452 /* ******* */
       
   453 /* Dialogs */
       
   454 /* ******* */
       
   455 /* No longer have a need for unique fields for query */
       
   456 static struct DialogIDs {
       
   457     jfieldID modal;
       
   458     jfieldID resizable;
       
   459 } dialogIDs;
       
   460 
       
   461 JNIEXPORT void JNICALL
       
   462 Java_java_awt_Dialog_initIDs
       
   463   (JNIEnv *env, jclass cls)
       
   464 {
       
   465 #if 0
       
   466     dialogIDs.modal = (*env)->GetFieldID(env, cls, "modal", "Z");
       
   467     dialogIDs.resizable = (*env)->GetFieldID(env, cls, "resizable", "Z");
       
   468 #endif
       
   469 }
       
   470 
       
   471 /* ******* */
       
   472 /* Windows */
       
   473 /* ******* */
       
   474 
       
   475 JNIEXPORT void JNICALL
       
   476 Java_java_awt_Window_initIDs
       
   477   (JNIEnv *env, jclass cls)
       
   478 {
       
   479     windowIDs.warningString = (*env)->GetFieldID(env, cls, "warningString",
       
   480                                                  "Ljava/lang/String;");
       
   481     windowIDs.resetGCMID = (*env)->GetMethodID(env, cls, "resetGC",
       
   482                                                  "()V");
       
   483 
       
   484     windowIDs.locationByPlatform = (*env)->GetFieldID(env, cls, "locationByPlatform",
       
   485                                                         "Z");
       
   486     windowIDs.isAutoRequestFocus = (*env)->GetFieldID(env, cls, "autoRequestFocus", "Z");
       
   487 
       
   488     DASSERT(windowIDs.resetGCMID);
       
   489 }
       
   490 
       
   491 /*
       
   492  * Class:     sun_motif_awt_WindowAttributes
       
   493  * Method:    initIDs
       
   494  * Signature: ()V
       
   495  */
       
   496 
       
   497 static struct MWindowAttributeIDs {
       
   498     jfieldID nativeDecor;
       
   499     jfieldID initialFocus;
       
   500     jfieldID isResizable;
       
   501     jfieldID initialState;
       
   502     jfieldID visibilityState;
       
   503     jfieldID decorations;
       
   504 } mWindowAttributeIDs;
       
   505 
       
   506 JNIEXPORT void JNICALL
       
   507 Java_sun_awt_motif_MWindowAttributes_initIDs
       
   508   (JNIEnv *env, jclass cls)
       
   509 {
       
   510     mWindowAttributeIDs.nativeDecor =
       
   511         (*env)->GetFieldID(env, cls, "nativeDecor", "Z");
       
   512     mWindowAttributeIDs.initialFocus =
       
   513         (*env)->GetFieldID(env, cls, "initialFocus", "Z");
       
   514     mWindowAttributeIDs.isResizable =
       
   515         (*env)->GetFieldID(env, cls, "isResizable", "Z");
       
   516     mWindowAttributeIDs.initialState =
       
   517         (*env)->GetFieldID(env, cls, "initialState", "I");
       
   518     mWindowAttributeIDs.visibilityState =
       
   519         (*env)->GetFieldID(env, cls, "visibilityState", "I");
       
   520     mWindowAttributeIDs.decorations =
       
   521         (*env)->GetFieldID(env, cls, "decorations", "I");
       
   522 }
       
   523 
       
   524 /*
       
   525  * Class:     sun_awt_motif_MWindowPeer
       
   526  * Method:    initIDs
       
   527  * Signature: ()V
       
   528  */
       
   529 
       
   530 /* This function gets called from the static initializer for MWindowPeer.java
       
   531    to initialize the fieldIDs for fields that may be accessed from C */
       
   532 
       
   533 JNIEXPORT void JNICALL
       
   534 Java_sun_awt_motif_MWindowPeer_initIDs
       
   535   (JNIEnv *env, jclass cls)
       
   536 {
       
   537     mWindowPeerIDs.insets =
       
   538         (*env)->GetFieldID(env, cls, "insets", "Ljava/awt/Insets;");
       
   539     mWindowPeerIDs.winAttr =
       
   540         (*env)->GetFieldID( env,
       
   541                             cls,
       
   542                             "winAttr",
       
   543                             "Lsun/awt/motif/MWindowAttributes;"
       
   544                           );
       
   545     mWindowPeerIDs.iconWidth =
       
   546         (*env)->GetFieldID(env, cls, "iconWidth", "I");
       
   547     mWindowPeerIDs.iconHeight =
       
   548         (*env)->GetFieldID(env, cls, "iconHeight", "I");
       
   549     mWindowPeerIDs.handleWindowFocusOut =
       
   550         (*env)->GetMethodID(env,
       
   551                             cls,
       
   552                             "handleWindowFocusOut",
       
   553                             "(Ljava/awt/Window;)V");
       
   554     mWindowPeerIDs.handleWindowFocusIn =
       
   555         (*env)->GetMethodID(env,
       
   556                             cls,
       
   557                             "handleWindowFocusIn",
       
   558                             "()V");
       
   559     mWindowPeerIDs.handleIconify =
       
   560         (*env)->GetMethodID(env,
       
   561                             cls,
       
   562                             "handleIconify",
       
   563                             "()V");
       
   564     mWindowPeerIDs.handleDeiconify =
       
   565         (*env)->GetMethodID(env,
       
   566                             cls,
       
   567                             "handleDeiconify",
       
   568                             "()V");
       
   569     mWindowPeerIDs.handleStateChange =
       
   570         (*env)->GetMethodID(env,
       
   571                             cls,
       
   572                             "handleStateChange",
       
   573                             "(II)V");
       
   574 
       
   575     mWindowPeerIDs.draggedToScreenMID = (*env)->GetMethodID(env, cls,
       
   576                                                            "draggedToNewScreen",
       
   577                                                            "(I)V");
       
   578     DASSERT(mWindowPeerIDs.draggedToScreenMID);
       
   579 }
       
   580 
       
   581 /*
       
   582  * Class:     sun_awt_motif_MWindowPeer
       
   583  * Method:    wrapInSequenced
       
   584  * Signature: (Ljava/awt/AWTEvent;)Ljava/awt/SequencedEvent;
       
   585  */
       
   586 
       
   587 /* This method gets called from MWindowPeer to wrap a FocusEvent in
       
   588    a SequencedEvent. We have to do this in native code, because we
       
   589    don't want to make SequencedEvent a public class. */
       
   590 
       
   591 JNIEXPORT jobject JNICALL
       
   592 Java_sun_awt_motif_MWindowPeer_wrapInSequenced
       
   593   (JNIEnv *env, jobject this, jobject awtevent)
       
   594 {
       
   595   jobject global = awt_canvas_wrapInSequenced(awtevent);
       
   596   jobject local = (*env)->NewLocalRef(env, global);
       
   597   (*env)->DeleteGlobalRef(env, global);
       
   598   return local;
       
   599 }
       
   600 
       
   601 extern jobject findTopLevelOpposite();
       
   602 
       
   603 /*
       
   604  * Class:     sun_awt_motif_MWindowPeer
       
   605  * Method:    findOpposite
       
   606  * Signature: (Ljava/awt/AWTEvent;)Ljava/awt/Window;
       
   607  */
       
   608 
       
   609 JNIEXPORT jobject JNICALL
       
   610 Java_sun_awt_motif_MWindowPeer_findOpposite
       
   611     (JNIEnv *env, jobject this, jint eventType)
       
   612 {
       
   613 #ifdef HEADLESS
       
   614     return NULL;
       
   615 #else
       
   616     if ((*env)->EnsureLocalCapacity(env, 1) < 0) {
       
   617         return NULL;
       
   618     }
       
   619 
       
   620     return findTopLevelOpposite(env, eventType);
       
   621 #endif
       
   622 }
       
   623 
       
   624 /* changeInsets() sets target's insets equal to X/Motif values. */
       
   625 
       
   626 static void
       
   627 awtJNI_ChangeInsets(JNIEnv * env, jobject this, struct FrameData *wdata)
       
   628 {
       
   629     jobject insets;
       
   630 
       
   631     if ((*env)->EnsureLocalCapacity(env, 1) < 0)
       
   632         return;
       
   633 
       
   634     insets = (*env)->GetObjectField(env, this, mWindowPeerIDs.insets);
       
   635 
       
   636     if (JNU_IsNull(env, insets)) {
       
   637         return;
       
   638     }
       
   639 
       
   640     (*env)->SetIntField(env, insets, insetsIDs.top, wdata->top);
       
   641     (*env)->SetIntField(env, insets, insetsIDs.left, wdata->left);
       
   642     (*env)->SetIntField(env, insets, insetsIDs.bottom, wdata->bottom);
       
   643     (*env)->SetIntField(env, insets, insetsIDs.right, wdata->right);
       
   644 
       
   645     /* Fix for 4106068: don't do it, rely on the window */
       
   646     /*   manager maximizing policy instead              */
       
   647 #if 0
       
   648     /* when the insets get set, make sure we set the proper */
       
   649     /* max window size (since it's dependent on inset size) */
       
   650     if (wdata->isResizable) {
       
   651         int32_t screenWidth = XWidthOfScreen( XDefaultScreenOfDisplay(awt_display));
       
   652         int32_t screenHeight= XHeightOfScreen(XDefaultScreenOfDisplay(awt_display));
       
   653         XtVaSetValues(wdata->winData.shell,
       
   654                 XmNmaxWidth, screenWidth - (wdata->left + wdata->right),
       
   655                 XmNmaxHeight, screenHeight - (wdata->top + wdata->bottom),
       
   656                 NULL);
       
   657     }
       
   658 #endif
       
   659     (*env)->DeleteLocalRef(env, insets);
       
   660 }
       
   661 
       
   662 
       
   663 /* setMbAndWwHeightAndOffsets() attempts to establish the heights
       
   664    of frame's menu bar and warning window (if present in frame).
       
   665    setMbAndWwHeightAndOffsets() also adjusts appropriately the
       
   666    X/Motif offsets and calls changeInsets() to set target insets.
       
   667    A warning window, if present, is established during ...create().
       
   668    wdata->warningWindow is set there, wdata->wwHeight is set here.
       
   669    Routine pSetMenuBar() sets value of the wdata->menuBar field.
       
   670    This routine reads that value. If it is not null, a menubar
       
   671    has been added.  In this case, calculate the current height
       
   672    of the menu bar.  This may be a partial (incomplete) menubar
       
   673    because ths routine may be called before the X/Motif menubar
       
   674    is completely realized. In this case, the menubar height may
       
   675    be adjusted incrementally.  This routine may be called from
       
   676    ...pSetMenuBar(), innerCanvasEH(), and ...pReshape(). It is
       
   677    designed to (eventually) obtain the correct menubar height.
       
   678    On the other hand, if wdata->menuBar is NULL and the stored
       
   679    menubar height is not zero, then we subtract off the height. */
       
   680 
       
   681 static void
       
   682 awtJNI_setMbAndWwHeightAndOffsets(JNIEnv * env,
       
   683                                   jobject this,
       
   684                                   struct FrameData *wdata )
       
   685 {
       
   686     Dimension   warningHeight,  /* Motif warning window height  */
       
   687                 labelHeight;    /* Motif warning label's height */
       
   688 
       
   689     WidgetList  warningChildrenWL; /* warning children widgets  */
       
   690 
       
   691     Dimension   menuBarWidth,   /* Motif menubar width          */
       
   692                 menuBarHeight,  /* Motif menubar height         */
       
   693                 menuBarBorderSize, /* Motif menubar border size */
       
   694                 marginHeight,   /* Motif menubar margin height  */
       
   695                 menuHeight,     /* Motif menubar's menu height  */
       
   696                 menuBorderSize, /* Motif menu border size       */
       
   697                 actualHeight;   /* height: menu+margins+borders */
       
   698 
       
   699     WidgetList  menuBarChildrenWL; /* menubar children widgets  */
       
   700     Cardinal    numberChildren; /* number of menubar children   */
       
   701 
       
   702 #ifdef _pauly_debug
       
   703     fprintf(stdout," ++ setMenuBar\n");
       
   704     fflush(stdout);
       
   705 #endif /* _pauly_debug */
       
   706 
       
   707     /* If warning window height not yet known, try to get it now.
       
   708        It will be added to top or bottom (iff NETSCAPE) offset. */
       
   709     if  (wdata->warningWindow != NULL) {
       
   710         XtVaGetValues(wdata->warningWindow,
       
   711                       XmNheight, &warningHeight,
       
   712                       XmNchildren, &warningChildrenWL,
       
   713                       XmNnumChildren, &numberChildren,
       
   714                       NULL);
       
   715 
       
   716         /* We may be doing this before warning window is realized ! So,
       
   717            check for a child label in the warning. If its height is not
       
   718            yet accounted for in the warning height, then use it here.   */
       
   719         if  (numberChildren != 0) {
       
   720             XtVaGetValues(warningChildrenWL[0],
       
   721                           XmNheight, &labelHeight,
       
   722                           NULL);
       
   723 #ifdef _pauly_debug
       
   724             fprintf(stdout,"    setMenuBar.... warning label found with height: %d\n", labelHeight);
       
   725             fflush(stdout);
       
   726 #endif /* _pauly_debug */
       
   727             if  (warningHeight < labelHeight) {
       
   728 #ifdef _pauly_debug
       
   729     fprintf(stdout,"    setMenuBar.... !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
       
   730     fflush(stdout);
       
   731 #endif /* _pauly_debug */
       
   732                 warningHeight = labelHeight;
       
   733             }
       
   734         }
       
   735 
       
   736         if  (wdata->wwHeight < warningHeight) {
       
   737 #ifdef _pauly_debug
       
   738             fprintf(stdout, "    setMenuBar.... adding warning height: %d\n", warningHeight);
       
   739             fflush(stdout);
       
   740 #endif /* _pauly_debug */
       
   741 #ifdef NETSCAPE
       
   742             wdata->bottom += (warningHeight - wdata->wwHeight);
       
   743 #else
       
   744             wdata->top += (warningHeight - wdata->wwHeight);
       
   745 #endif /* NETSCAPE */
       
   746             awtJNI_ChangeInsets(env, this, wdata);
       
   747             wdata->wwHeight = warningHeight;
       
   748         }
       
   749     }
       
   750 
       
   751     /* Now we adjust offsets for an added or removed menu bar   */
       
   752     if  (wdata->menuBar != NULL) {
       
   753 #ifdef _pauly_debug
       
   754         fprintf(stdout,"    setMenuBar.  menu bar: %x\n", wdata->menuBar);
       
   755         fflush(stdout);
       
   756 #endif /* _pauly_debug */
       
   757         XtVaGetValues(wdata->menuBar,
       
   758                       XmNwidth, &menuBarWidth,
       
   759                       XmNheight, &menuBarHeight,
       
   760                       XmNchildren, &menuBarChildrenWL,
       
   761                       XmNnumChildren, &numberChildren,
       
   762                       XmNborderWidth, &menuBarBorderSize,
       
   763                       XmNmarginHeight, &marginHeight,
       
   764                       NULL);
       
   765 
       
   766         /* We may be doing this before menu bar is realized ! Hence,
       
   767            check for a menu in the menu bar. If its height is not yet
       
   768            accounted for in the menu bar height, then add it in here.   */
       
   769         if  (numberChildren != 0) {
       
   770             XtVaGetValues(menuBarChildrenWL[0],
       
   771                           XmNheight, &menuHeight,
       
   772                           XmNborderWidth, &menuBorderSize,
       
   773                           NULL);
       
   774 #ifdef _pauly_debug
       
   775             fprintf(stdout,"    setMenuBar.... menu found with height: %d, border: %d, margin: %d, bar border: %d\n", menuHeight, menuBorderSize, marginHeight, menuBarBorderSize);
       
   776             fflush(stdout);
       
   777 #endif /* _pauly_debug */
       
   778             /* Calculate real height of menu bar by adding height of its
       
   779                child menu and borders, margins, and the menu bar borders*/
       
   780             actualHeight = menuHeight + (2 * menuBorderSize) +
       
   781                            (2 * marginHeight) + (2 * menuBarBorderSize);
       
   782 #ifdef __linux__
       
   783 #ifdef _pauly_debug
       
   784             fprintf(stdout,"  actual height: %d mb height %d\n", actualHeight, menuBarHeight);
       
   785             fflush(stdout);
       
   786 #endif /* _pauly_debug */
       
   787 #endif
       
   788             if  (menuBarHeight < actualHeight) {
       
   789 #ifdef _pauly_debug
       
   790 fprintf(stdout,"    setMenuBar.... ****************************************\n");
       
   791 fflush(stdout);
       
   792 #endif /* _pauly_debug */
       
   793                 menuBarHeight = actualHeight;
       
   794             }
       
   795         }
       
   796 
       
   797         if  (wdata->mbHeight < menuBarHeight) {
       
   798             /* Adjust the (partially) added menu bar height, top offset.*/
       
   799 #ifdef _pauly_debug
       
   800             fprintf(stdout, "    setMenuBar.... added menuBar height: %d\n", menuBarHeight);
       
   801             fflush(stdout);
       
   802 #endif /* _pauly_debug */
       
   803             wdata->top += (menuBarHeight - wdata->mbHeight);
       
   804             awtJNI_ChangeInsets(env, this, wdata);
       
   805             wdata->mbHeight = menuBarHeight;
       
   806         }
       
   807     } else if  ((wdata->menuBar == NULL) && (wdata->mbHeight > 0)) {
       
   808         /* A menu bar has been removed; subtract height from top offset.*/
       
   809         wdata->top -= wdata->mbHeight;
       
   810 #ifdef _pauly_debug
       
   811         fprintf(stdout, "    setMenuBar.... removed menuBar height: %d\n", wdata->mbHeight);
       
   812         fflush(stdout);
       
   813 #endif /* _pauly_debug */
       
   814         awtJNI_ChangeInsets(env, this, wdata);
       
   815         wdata->mbHeight = 0;
       
   816     }
       
   817 }
       
   818 
       
   819 
       
   820 /* outerCanvasResizeCB() is Motif resize callback for outer/child canvas.
       
   821    It reads width, height of Motif widget, sets java target accordingly,
       
   822    and then calls handleResize() to affect any changes.
       
   823    This call is only done for a shell resize or inner/parent resize;
       
   824    i.e., it may not be done for a ...pReshape() to avoid doing a loop.
       
   825 
       
   826    client_data is MWindowPeer instance
       
   827 */
       
   828 static void
       
   829 outerCanvasResizeCB(Widget wd, XtPointer client_data, XtPointer call_data)
       
   830 {
       
   831     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   832     jobject target;
       
   833     struct FrameData *wdata;
       
   834     Position    screenX;        /* x position of the canvas, screen */
       
   835     Position    screenY;        /* y position of the canvas, screen */
       
   836     Dimension   width;          /* width of the canvas, target  */
       
   837     Dimension   height;         /* height of the canvas, target */
       
   838     jint        oldWidth;
       
   839     jint        oldHeight;
       
   840 
       
   841 #ifdef _pauly_debug
       
   842     fprintf(stdout," ++ WindowResize.\n");
       
   843     fflush(stdout);
       
   844 #endif /* _pauly_debug */
       
   845 
       
   846     wdata = (struct FrameData *)
       
   847         JNU_GetLongFieldAsPtr(env, (jobject) client_data,
       
   848                               mComponentPeerIDs.pData);
       
   849     if (wdata == NULL) {
       
   850         return;
       
   851     }
       
   852 
       
   853     if ((*env)->EnsureLocalCapacity(env, 1) < 0)
       
   854         return;
       
   855 
       
   856     target = (*env)->GetObjectField(env, (jobject) client_data,
       
   857                                     mComponentPeerIDs.target);
       
   858     XtVaGetValues(wd,
       
   859                   XmNwidth, &width,
       
   860                   XmNheight, &height,
       
   861                   NULL);
       
   862 #ifdef _pauly_debug
       
   863     fprintf(stdout,"    outerCanvasResizeCB.  width: %d, height: %d\n", width, height);
       
   864     fflush(stdout);
       
   865 #endif /* _pauly_debug */
       
   866 
       
   867 
       
   868     XtTranslateCoords(wd, 0, 0, &screenX, &screenY);
       
   869 
       
   870     if  ((wdata->shellResized) || (wdata->canvasResized)) {
       
   871 #ifdef _pauly_debug
       
   872         fprintf(stdout,"    outerCanvasResizeCB\n");
       
   873         fflush(stdout);
       
   874 #endif /* _pauly_debug */
       
   875         wdata->shellResized = False;
       
   876         wdata->canvasResized = False;
       
   877         /*
       
   878         ** if you are not yet reparented, don't compute the size based on the
       
   879         ** widgets, as the window manager shell containg the insets is not yet
       
   880         ** there.  Use the size the application has set.
       
   881         ** If not reparented, we got here because the application set the size,
       
   882         ** so just send them Component.RESIZED event with the size they set.
       
   883         **
       
   884         ** If the reparenting causes a resize ( only when inset guess is wrong )        ** the new size will be sent in a Component.RESIZED event at that time.
       
   885         */
       
   886         if (wdata->reparented)
       
   887         {
       
   888             (*env)->SetIntField(env, target, componentIDs.x, (jint) screenX);
       
   889             (*env)->SetIntField(env, target, componentIDs.y, (jint) screenY);
       
   890         }
       
   891 
       
   892     oldWidth = (*env)->GetIntField(env, target, componentIDs.width);
       
   893     oldHeight = (*env)->GetIntField(env, target, componentIDs.height);
       
   894 
       
   895     if (oldWidth != width || oldHeight != height || wdata->need_reshape)
       
   896     {
       
   897         wdata->need_reshape = False;
       
   898         (*env)->SetIntField(env, target, componentIDs.width, (jint)width);
       
   899         (*env)->SetIntField(env, target, componentIDs.height,
       
   900                 (jint)height);
       
   901 
       
   902         /* only do this for Windows, not Canvases, btw */
       
   903         checkNewXineramaScreen(env, client_data, wdata, screenX, screenY, width, height);
       
   904 
       
   905         JNU_CallMethodByName(env, NULL, (jobject) client_data,
       
   906                  "handleResize", "(II)V", width, height);
       
   907         if  ((*env)->ExceptionOccurred(env)) {
       
   908             (*env)->ExceptionDescribe(env);
       
   909         (*env)->ExceptionClear(env);
       
   910         }
       
   911     }
       
   912     }
       
   913 
       
   914     (*env)->DeleteLocalRef(env, target);
       
   915 
       
   916 #ifdef _pauly_debug
       
   917     fprintf(stdout,"    WindowResize. Done.\n");
       
   918     fflush(stdout);
       
   919 #endif /* _pauly_debug */
       
   920 
       
   921 } /* outerCanvasResizeCB() */
       
   922 
       
   923 static void reconfigureOuterCanvas ( JNIEnv *env, jobject target,
       
   924                                      jobject this, struct FrameData *wdata )
       
   925 {
       
   926     Dimension   innerDAWidth,   /* width of inner Motif canvas  */
       
   927                 innerDAHeight,  /* height of inner Motif canvas */
       
   928                 outerDAWidth,   /* width of outer Motif canvas  */
       
   929                 outerDAHeight;  /* height of outer Motif canvas */
       
   930     int32_t     targetWidth,    /* java target object's width   */
       
   931                 targetHeight;   /* java target's object height  */
       
   932     Dimension   width;          /* width of the canvas, target  */
       
   933     Dimension   height;         /* height of the canvas, target */
       
   934 
       
   935 
       
   936     Position    innerX,         /* x loc. of inner Motif canvas */
       
   937                 innerY,         /* y loc. of inner Motif canvas */
       
   938                 x, y;
       
   939 
       
   940     /* canvasW is (visible) inner/parent drawing area (canvas) widget   */
       
   941     XtVaGetValues(XtParent(wdata->winData.comp.widget),
       
   942                   XmNwidth, &innerDAWidth,
       
   943                   XmNheight, &innerDAHeight,
       
   944                   XmNx, &innerX,
       
   945                   XmNy, &innerY,
       
   946                   NULL);
       
   947 
       
   948     /* This resize may be due to the insertion or removal of a menu bar.
       
   949        If so, we appropriately adjust the top offset in wdata, insets.  */
       
   950     awtJNI_setMbAndWwHeightAndOffsets(env, this, wdata);
       
   951 
       
   952     outerDAWidth = innerDAWidth + wdata->left + wdata->right;
       
   953     outerDAHeight = innerDAHeight + wdata->top + wdata->bottom;
       
   954 
       
   955     /* If it's a menu bar reset, do not do resize of outer/child canvas.
       
   956        (Another thread problem; we arrest this now before damage done.) */
       
   957     if  (wdata->menuBarReset)
       
   958     {
       
   959         targetWidth = (*env)->GetIntField(env, target, componentIDs.width);
       
   960         targetHeight = (*env)->GetIntField(env, target, componentIDs.height);
       
   961         if  ((outerDAWidth != targetWidth) || (outerDAHeight != targetHeight))
       
   962         {
       
   963             return;
       
   964         }
       
   965     }
       
   966 
       
   967     wdata->canvasResized = True;
       
   968 
       
   969     /* The outer/child drawing area (canvas) needs to be configured too.
       
   970        If its size changes, its resize callback will thereby be invoked.*/
       
   971     x = -wdata->left;
       
   972     y = -wdata->top;
       
   973     width = innerDAWidth + wdata->left + wdata->right;
       
   974     height = innerDAHeight + wdata->top + wdata->bottom;
       
   975 
       
   976     XtConfigureWidget(wdata->winData.comp.widget, x, y, width, height, 0 );
       
   977 }
       
   978 
       
   979 
       
   980 
       
   981 /* innerCanvasEH() is event handler for inner/parent canvas. It handles
       
   982    map and configure notify events. It reads width and height, adjusts
       
   983    for menubar insertion / removal and configures outer/child canvas.   */
       
   984 
       
   985 static void
       
   986 innerCanvasEH(Widget canvasW, XtPointer client_data, XEvent *event,
       
   987               Boolean* continueToDispatch)
       
   988 {
       
   989     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   990     jobject     this = (jobject) client_data;
       
   991     jobject     target;
       
   992     struct FrameData *wdata;
       
   993 
       
   994 
       
   995     wdata = (struct FrameData *)
       
   996         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   997     if  (wdata == NULL) {
       
   998         return;
       
   999     }
       
  1000 
       
  1001     if  ((*env)->EnsureLocalCapacity(env, 1) < 0)
       
  1002         return;
       
  1003 
       
  1004     target = (*env)->GetObjectField(env, (jobject) client_data,
       
  1005                                     mComponentPeerIDs.target);
       
  1006 
       
  1007     /* While inside ...pSetMenuBar(), don't react to incomplete resizing
       
  1008        events supplied by Xt toolkit. Wait for completion of the routine. */
       
  1009 
       
  1010 
       
  1011     /* For a map or resize, we need to check for the addition or deletion
       
  1012        of a menu bar to the form which is the of this drawing area (canvas).
       
  1013        We also must then configure the outer/child canvas appropriately.  */
       
  1014 
       
  1015     if  ( (event->xany.type == MapNotify) ||
       
  1016           (event->xany.type == ConfigureNotify) )
       
  1017     {
       
  1018         reconfigureOuterCanvas( env, target, this, wdata );
       
  1019     }
       
  1020 
       
  1021     (*env)->DeleteLocalRef(env, target);
       
  1022 
       
  1023 }
       
  1024 
       
  1025 /* syncTopLevelPos() is necessary to insure that the window manager has in
       
  1026  * fact moved us to our final position relative to the reParented WM window.
       
  1027  * We have noted a timing window which our shell has not been moved so we
       
  1028  * screw up the insets thinking they are 0,0.  Wait (for a limited period of
       
  1029  * time to let the WM hava a chance to move us
       
  1030  */
       
  1031 void syncTopLevelPos( Display *d, Window w, XWindowAttributes *winAttr )
       
  1032 {
       
  1033     int32_t i = 0;
       
  1034     memset(winAttr, 0, sizeof(*winAttr));
       
  1035 
       
  1036     do {
       
  1037         if (!XGetWindowAttributes(d, w, winAttr)) {
       
  1038             memset(winAttr, 0, sizeof(*winAttr));
       
  1039             break;
       
  1040         }
       
  1041         /* Sometimes we get here before the WM has updated the
       
  1042         ** window data struct with the correct position.  Loop
       
  1043         ** until we get a non-zero position.
       
  1044         */
       
  1045         if ((winAttr->x != 0) || (winAttr->y != 0)) {
       
  1046             break;
       
  1047         }
       
  1048         else {
       
  1049             /* What we really want here is to sync with the WM,
       
  1050             ** but there's no explicit way to do this, so we
       
  1051             ** call XSync for a delay.
       
  1052             */
       
  1053             XSync(d, False);
       
  1054         }
       
  1055     } while (i++ < 50);
       
  1056 }
       
  1057 
       
  1058 typedef struct FocusOutInfo_str {
       
  1059     XEvent * eventOut;
       
  1060     Window inWin;
       
  1061     Window inChild;
       
  1062     Widget defChild;
       
  1063     jobject childComp;
       
  1064 } FocusOutInfo_t;
       
  1065 
       
  1066 #define IsCanvasTypeWidget(w) \
       
  1067         (XtIsSubclass(w, xmDrawingAreaWidgetClass) ||\
       
  1068         XtIsSubclass(w, vDrawingAreaClass))
       
  1069 
       
  1070 int isTopLevelPartWidget(Widget w) {
       
  1071     if (XtIsShell(w)) {
       
  1072         return TRUE;
       
  1073     }
       
  1074     if (XtIsSubclass(w, xmFormWidgetClass)) {
       
  1075         return TRUE;
       
  1076     }
       
  1077     if (IsCanvasTypeWidget(w)) {
       
  1078         Widget w1 = XtParent(w);
       
  1079         if (w1 != NULL) {
       
  1080             if (XtIsSubclass(w1, xmFormWidgetClass)) {
       
  1081                 return TRUE;
       
  1082             }
       
  1083             if (IsCanvasTypeWidget(w1)) {
       
  1084                 Widget w2 = XtParent(w1);
       
  1085                 if (w2 != NULL) {
       
  1086                     if (XtIsSubclass(w2, xmFormWidgetClass)) {
       
  1087                         return TRUE;
       
  1088                     }
       
  1089                 }
       
  1090             }
       
  1091 
       
  1092         }
       
  1093     }
       
  1094     return FALSE;
       
  1095 }
       
  1096 
       
  1097 void
       
  1098 shellFocusEH(Widget w, XtPointer data, XEvent *event, Boolean *continueToDispatch)
       
  1099 {
       
  1100     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  1101     jobject     this = (jobject) data;
       
  1102     jobject     target;
       
  1103     struct FrameData *wdata;
       
  1104 
       
  1105     /* Any event handlers which take peer instance pointers as
       
  1106      * client_data should check to ensure the widget has not been
       
  1107      * marked as destroyed as a result of a dispose() call on the peer
       
  1108      * (which can result in the peer instance pointer already haven
       
  1109      * been gc'd by the time this event is processed)
       
  1110      */
       
  1111     if (w->core.being_destroyed) {
       
  1112         return;
       
  1113     }
       
  1114 
       
  1115     wdata = (struct FrameData *)
       
  1116         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  1117     if (wdata == NULL) {
       
  1118         return;
       
  1119     }
       
  1120 
       
  1121     switch (event->xany.type) {
       
  1122       case FocusOut:
       
  1123           // Will be handled by proxy automaticall since he is focus owner
       
  1124         break;
       
  1125       case FocusIn:
       
  1126         // Forward focus event to the proxy
       
  1127         XSetInputFocus(awt_display, XtWindow(wdata->focusProxy), RevertToParent, CurrentTime);
       
  1128         break;
       
  1129     }
       
  1130 }
       
  1131 
       
  1132 /**
       
  1133  * Fix for Alt-Tab problem.
       
  1134  * See coments on use semantics below.
       
  1135  */
       
  1136 Boolean skipNextNotifyWhileGrabbed = False;
       
  1137 Boolean skipNextFocusIn = False;
       
  1138 
       
  1139 Boolean focusOnMapNotify = False;
       
  1140 
       
  1141 /* shellEH() is event handler for the Motif shell widget. It handles
       
  1142    focus change, map notify, configure notify events for the shell.
       
  1143    Please see internal comments pertaining to these specific events.
       
  1144 
       
  1145    data is MWindowPeer instance pointer
       
  1146 */
       
  1147 void
       
  1148 shellEH(Widget w, XtPointer data, XEvent *event, Boolean *continueToDispatch)
       
  1149 {
       
  1150     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  1151     jobject     this = (jobject) data;
       
  1152     jobject     target;
       
  1153     struct FrameData *wdata;
       
  1154     int32_t     setTargetX,
       
  1155                 setTargetY,
       
  1156                 getTargetX,
       
  1157                 getTargetY;
       
  1158     /* Changed long to int for 64-bit */
       
  1159     int32_t     wwHeight;       /* height of any warning window present */
       
  1160     int32_t     topAdjust;      /* adjust top offset for menu, warning  */
       
  1161     jclass      clazz;
       
  1162     int32_t     x, y;
       
  1163     int32_t     width, height;
       
  1164     enum wmgr_t runningWM;
       
  1165     jobject   winAttrObj;
       
  1166     static jobject windowClass = NULL;
       
  1167     /* Any event handlers which take peer instance pointers as
       
  1168      * client_data should check to ensure the widget has not been
       
  1169      * marked as destroyed as a result of a dispose() call on the peer
       
  1170      * (which can result in the peer instance pointer already haven
       
  1171      * been gc'd by the time this event is processed)
       
  1172      */
       
  1173     if (w->core.being_destroyed) {
       
  1174         return;
       
  1175     }
       
  1176 
       
  1177     wdata = (struct FrameData *)
       
  1178         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  1179     if (wdata == NULL) {
       
  1180         return;
       
  1181     }
       
  1182 
       
  1183     switch (event->xany.type) {
       
  1184 
       
  1185     case FocusOut: {
       
  1186         int32_t res = 0;
       
  1187         int revert_to = 0;
       
  1188         Widget defChild = NULL;
       
  1189         Window focusOwner = None;
       
  1190         jobject oppositeWindow = NULL;
       
  1191         Widget oppositeShell = NULL;
       
  1192         XEvent inEvent;
       
  1193         Widget shell = NULL;
       
  1194 #ifdef DEBUG_FOCUS
       
  1195         fprintf(stderr, "Focusout on proxy; window = %x, mode %d, detail %d\n",
       
  1196                 event->xfocus.window, event->xfocus.mode, event->xfocus.detail);
       
  1197 #endif
       
  1198         shell = wdata->winData.shell;
       
  1199 
       
  1200         if ((*env)->EnsureLocalCapacity(env, 3) < 0) {
       
  1201             break;
       
  1202         }
       
  1203 
       
  1204         /**
       
  1205          * Fix for Alt-Tab problem. We should process NotifyWhileGrabbed events
       
  1206          * only if they are due to the switch between top-levels.
       
  1207          * skipNextNotifyWhileGrabbed is set from Menu and PopupMenu code
       
  1208          * to prevent generation of focus events when user interact with these
       
  1209          * widget.
       
  1210          */
       
  1211         if (event->xfocus.mode == NotifyWhileGrabbed) {
       
  1212             if (skipNextNotifyWhileGrabbed) {
       
  1213                 skipNextNotifyWhileGrabbed = False;
       
  1214                 break;
       
  1215             }
       
  1216         } else if (event->xfocus.mode != NotifyNormal) break;
       
  1217 
       
  1218         /**
       
  1219          * Fix for Alt-Tab problem.
       
  1220          * skipNextFocusIn is set in Choice code to avoid processing of
       
  1221          * next focus-in or focus-out generated by Choice as it is a fake
       
  1222          * event.
       
  1223          */
       
  1224         if (skipNextFocusIn && event->xfocus.detail == NotifyPointer) {
       
  1225             break;
       
  1226         }
       
  1227 
       
  1228         XGetInputFocus( awt_display, &focusOwner, &revert_to);
       
  1229 
       
  1230         if (focusOwner != None) {
       
  1231             Widget inWidget = NULL;
       
  1232             jobject wpeer = NULL;
       
  1233             inWidget = XtWindowToWidget(awt_display, focusOwner);
       
  1234             if (inWidget != NULL && inWidget != shell) {
       
  1235                 oppositeShell = getShellWidget(inWidget);
       
  1236                 wpeer = findPeer(&inWidget);
       
  1237                 if (wpeer == NULL) {
       
  1238                     inWidget = findTopLevelByShell(inWidget);
       
  1239                     if (inWidget != NULL) {
       
  1240                         wpeer = findPeer(&inWidget);
       
  1241                     }
       
  1242                 }
       
  1243                 if (wpeer != NULL) {
       
  1244                     jobject peerComp =
       
  1245                         (*env)->GetObjectField(env,
       
  1246                                                wpeer,
       
  1247                                                mComponentPeerIDs.target);
       
  1248                     if (peerComp != NULL) {
       
  1249                         // Check that peerComp is top-level
       
  1250 
       
  1251                         // load class
       
  1252                         if (windowClass == NULL) {
       
  1253                             jobject localWindowClass = (*env)->FindClass(env, "java/awt/Window");
       
  1254                             windowClass = (*env)->NewGlobalRef(env, localWindowClass);
       
  1255                             (*env)->DeleteLocalRef(env, localWindowClass);
       
  1256                         }
       
  1257                         if ((*env)->IsInstanceOf(env, peerComp, windowClass)) {
       
  1258                             oppositeWindow = peerComp;
       
  1259                         } else { // Opposite object is not Window - there is no opposite window.
       
  1260                             (*env)->DeleteLocalRef(env, peerComp);
       
  1261                             peerComp = NULL;
       
  1262                             oppositeShell = NULL;
       
  1263                         }
       
  1264                     }
       
  1265                 }
       
  1266             }
       
  1267         } else {
       
  1268             // If there is no opposite shell but we have active popup - this popup is actually
       
  1269             // the oppposite. This should mean that this focus out is due to popup - and thus
       
  1270             // should be skipped. Fix for 4478780.
       
  1271             if (skipNextNotifyWhileGrabbed) {
       
  1272                 break;
       
  1273             }
       
  1274         }
       
  1275 
       
  1276         // If current window is not focusable and opposite window is not focusable - do nothing
       
  1277         // If current window is focusable and opposite is not - do not clear focus variables like
       
  1278         // focus didn't leave this window(but it will in terms of X). When we later switch to either
       
  1279         // - back to this window: variables are already here
       
  1280         // - another focusable window: variables point to focusable window and "focus lost" events
       
  1281         //   will be generated for it
       
  1282         // - non-java window: variables point to focusable window and "focus lost" events
       
  1283         //   will be generated for it, not for non-focusable.
       
  1284         // If current window is non-focusable and opposite is focusable then do not generate anything
       
  1285         // as if we didn't leave previous focusable window so Java events will generated for it.
       
  1286         //
       
  1287         // Fix for 6547951.
       
  1288         // Also do cleaning when switching to non-java window (opposite is null).
       
  1289         if (isFocusableWindowByShell(env, shell) && shell != oppositeShell &&
       
  1290             ((oppositeShell != NULL && isFocusableWindowByShell(env, oppositeShell)) ||
       
  1291              oppositeShell == NULL))
       
  1292         {
       
  1293             // The necessary FOCUS_LOST event will be generated by DKFM.
       
  1294             // So we need to process focus list like we received FocusOut
       
  1295             // for the desired component - shell's current focus widget
       
  1296             defChild = XmGetFocusWidget(shell);
       
  1297             if (defChild != NULL) {
       
  1298                 jobject peer = findPeer(&defChild);
       
  1299                 if (peer == NULL) {
       
  1300                     defChild = findTopLevelByShell(defChild);
       
  1301                     if (defChild != NULL) {
       
  1302                         peer = findPeer(&defChild);
       
  1303                     }
       
  1304                 }
       
  1305                 if (peer != NULL) {
       
  1306                     jobject comp = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target);
       
  1307                     if (focusList != NULL) {
       
  1308                         jobject last = (*env)->NewLocalRef(env, focusList->requestor);
       
  1309                         if ((*env)->IsSameObject(env, comp, last)) {
       
  1310                             FocusListElt * temp = focusList;
       
  1311                             forGained = focusList->requestor;
       
  1312                             focusList = focusList->next;
       
  1313                             free(temp);
       
  1314                             if (focusList == NULL) {
       
  1315                                 focusListEnd = NULL;
       
  1316                             }
       
  1317                         }
       
  1318                         if (!JNU_IsNull(env, last)) {
       
  1319                             (*env)->DeleteLocalRef(env, last);
       
  1320                         }
       
  1321                     }
       
  1322                     (*env)->DeleteLocalRef(env, comp);
       
  1323                 }
       
  1324             }
       
  1325             target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  1326             processTree(defChild, findWindowsProxy(target, env), False);
       
  1327             XtSetKeyboardFocus(shell, NULL);
       
  1328             (*env)->DeleteLocalRef(env, target);
       
  1329         }
       
  1330 #ifndef NOMODALFIX
       
  1331         if (!awt_isModal() || awt_isWidgetModal(shell)) {
       
  1332 #endif //NOMODALFIX
       
  1333             if ( oppositeShell != NULL
       
  1334                  && isFocusableWindowByShell(env, oppositeShell)
       
  1335                  && isFocusableWindowByShell(env, shell)
       
  1336                  || (oppositeShell == NULL))
       
  1337             {
       
  1338                 /*
       
  1339                  * Fix for 5095117.
       
  1340                  * Check if current native focused window is the same as source.
       
  1341                  * Sometimes it is not - we must not however clean reference to
       
  1342                  * actual native focused window.
       
  1343                  */
       
  1344                 jobject currentFocusedWindow = awt_canvas_getFocusedWindowPeer();
       
  1345                 if ((*env)->IsSameObject(env, this, currentFocusedWindow)) {
       
  1346                     awt_canvas_setFocusedWindowPeer(NULL);
       
  1347                 }
       
  1348                 (*env)->DeleteLocalRef(env, currentFocusedWindow);
       
  1349 
       
  1350                 JNU_CallMethodByName(env, NULL, this, "handleWindowFocusOut", "(Ljava/awt/Window;)V",
       
  1351                                      oppositeWindow);
       
  1352                 if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
       
  1353                     (*env)->ExceptionDescribe(env);
       
  1354                     (*env)->ExceptionClear(env);
       
  1355                 }
       
  1356             }
       
  1357 #ifndef NOMODALFIX
       
  1358         }
       
  1359 #endif //NOMODALFIX
       
  1360         if (oppositeWindow != NULL) {
       
  1361             (*env)->DeleteLocalRef(env, oppositeWindow);
       
  1362         }
       
  1363 
       
  1364         break;
       
  1365     } /* FocusOut */
       
  1366 
       
  1367     case FocusIn: {
       
  1368         Widget shell = wdata->winData.shell;
       
  1369 #ifdef DEBUG_FOCUS
       
  1370         fprintf(stderr, "FocusIn on proxy; window = %x, mode %d, detail %d\n", event->xfocus.window,
       
  1371                 event->xfocus.mode, event->xfocus.detail);
       
  1372 #endif
       
  1373         if (/*  event->xfocus.mode == NotifyNormal */ 1) {
       
  1374 
       
  1375             /**
       
  1376              * Fix for Alt-Tab problem. We should process NotifyWhileGrabbed events to detect
       
  1377              * switch between top-levels using alt-tab, but avoid processing these type of event
       
  1378              * when they are originated from other sources.
       
  1379              */
       
  1380             if (event->xfocus.mode == NotifyWhileGrabbed) {
       
  1381                 /**
       
  1382                  * skipNextNotifyWhileGrabbed is set from Menu and PopupMenu code to
       
  1383                  * skip next focus-in event with NotifyWhileGrabbed as it is generated
       
  1384                  * in result of closing of the Menu's shell.
       
  1385                  * Event will also have NotifyInferior if uses clicked on menu bar in the
       
  1386                  * space where there is not menu items.
       
  1387                  */
       
  1388                 if (skipNextNotifyWhileGrabbed || event->xfocus.detail == NotifyInferior) {
       
  1389                     skipNextNotifyWhileGrabbed = False;
       
  1390                     break;
       
  1391                 }
       
  1392             } else if (event->xfocus.mode != NotifyNormal)  {
       
  1393                 break;
       
  1394             }
       
  1395 
       
  1396             /**
       
  1397              * Fix for Alt-Tab problem.
       
  1398              * skipNextFocusIn is set from Choice code to avoid processing next focus-in
       
  1399              * as it is a fake event.
       
  1400              */
       
  1401             if (skipNextFocusIn == True) {
       
  1402                 /**
       
  1403                  * There could be the set of fake events, the last one
       
  1404                  * will have detail == NotifyPointer
       
  1405                  */
       
  1406                 if (event->xfocus.detail != NotifyPointer) {
       
  1407                     skipNextFocusIn = False;
       
  1408                 }
       
  1409                 break;
       
  1410             }
       
  1411 #ifndef NOMODALFIX
       
  1412             if (!awt_isModal() || awt_isWidgetModal(shell)) {
       
  1413 #endif //NOMODALFIX
       
  1414                 if (isFocusableWindowByShell(env, shell)) {
       
  1415                     jobject currentFocusedWindow = awt_canvas_getFocusedWindowPeer();
       
  1416                     // Check if focus variables already point to this window. If so,
       
  1417                     // it means there were transfer to non-focusable window and now we
       
  1418                     // are back to origianl focusable window. No need to generate Java events
       
  1419                     // in this case.
       
  1420                     if (!(*env)->IsSameObject(env, this, currentFocusedWindow)) {
       
  1421                         awt_canvas_setFocusedWindowPeer(this);
       
  1422                         awt_canvas_setFocusOwnerPeer(this);
       
  1423 
       
  1424                         /*
       
  1425                          * Fix for 6465038.
       
  1426                          * Restore focus on the toplevel widget if it's broken.
       
  1427                          */
       
  1428                         Widget widgetToFocus = getFocusWidget(findTopLevelByShell(shell));
       
  1429                         Widget currentOwner = XmGetFocusWidget(shell);
       
  1430 
       
  1431                         if (widgetToFocus != currentOwner) {
       
  1432 #ifdef DEBUG_FOCUS
       
  1433                             fprintf(stderr, "Wrong Xm focus; resetting Xm focus from %x to toplevel %x...\n",
       
  1434                                     currentOwner != NULL ? XtWindow(currentOwner) : 0,
       
  1435                                     widgetToFocus != NULL ? XtWindow(widgetToFocus) : 0);
       
  1436 #endif
       
  1437                             if ( !XmProcessTraversal(widgetToFocus, XmTRAVERSE_CURRENT) ) {
       
  1438                                 XtSetKeyboardFocus(shell, widgetToFocus);
       
  1439                             }
       
  1440 #ifdef DEBUG_FOCUS
       
  1441                             Widget _w = XmGetFocusWidget(shell);
       
  1442                             fprintf(stderr, "                ...focus resulted on window %x\n", _w != NULL ? XtWindow(_w) : 0);
       
  1443 #endif
       
  1444                         }
       
  1445 
       
  1446                         JNU_CallMethodByName(env, NULL, this, "handleWindowFocusIn", "()V");
       
  1447                         if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
       
  1448                             (*env)->ExceptionDescribe(env);
       
  1449                             (*env)->ExceptionClear(env);
       
  1450                         }
       
  1451                     }
       
  1452                     (*env)->DeleteLocalRef(env, currentFocusedWindow);
       
  1453                 }
       
  1454 #ifndef NOMODALFIX
       
  1455             }
       
  1456 #endif //NOMODALFIX
       
  1457         }
       
  1458         raiseInputMethodWindow(wdata);
       
  1459         break;
       
  1460     } /* FocusIn */
       
  1461 
       
  1462     case VisibilityNotify: {
       
  1463        winAttrObj = (*env)->GetObjectField(env, this, mWindowPeerIDs.winAttr);
       
  1464        (*env)->SetIntField(env, winAttrObj,
       
  1465                            mWindowAttributeIDs.visibilityState,
       
  1466                            event->xvisibility.state);
       
  1467         if (event->xvisibility.state == VisibilityUnobscured) {
       
  1468             raiseInputMethodWindow(wdata);
       
  1469         }
       
  1470         break;
       
  1471     } /* VisibilityNotify */
       
  1472 
       
  1473     case MapNotify: {
       
  1474         /* Your body seems to unfade */
       
  1475         if (wdata->initialFocus == False) {
       
  1476             XtVaSetValues(wdata->winData.shell, XmNinput, True, NULL);
       
  1477 
       
  1478             // We have to to evidently move the window to the front here.
       
  1479             Window shellWindow;
       
  1480             if ((shellWindow = XtWindow(wdata->winData.shell)) != None) {
       
  1481                 XRaiseWindow(awt_display, shellWindow);
       
  1482             }
       
  1483         }
       
  1484         if (awt_wm_isStateNetHidden(XtWindow(wdata->winData.shell))) {
       
  1485             focusOnMapNotify = True;
       
  1486         }
       
  1487         /*
       
  1488          * TODO: perhaps we need this putback only for simple Window.
       
  1489          * For Frame/Dialog XmNinput==True would be enough. The native
       
  1490          * system will focus it itself.
       
  1491          */
       
  1492         if (wdata->isFocusableWindow && focusOnMapNotify) {
       
  1493             XEvent ev;
       
  1494             memset(&ev, 0, sizeof(ev));
       
  1495 
       
  1496             ev.type = FocusIn;
       
  1497             ev.xany.send_event = True;
       
  1498             ev.xany.display = awt_display;
       
  1499             ev.xfocus.mode = NotifyNormal;
       
  1500             ev.xfocus.detail = NotifyNonlinear;
       
  1501             ev.xfocus.window = XtWindow(wdata->winData.shell);
       
  1502             awt_put_back_event(env, &ev);
       
  1503         }
       
  1504         focusOnMapNotify = False;
       
  1505 
       
  1506         break;
       
  1507     }
       
  1508 
       
  1509     case UnmapNotify: {
       
  1510         /* Gee!  All of a sudden, you can't see yourself */
       
  1511         if (wdata->initialFocus == False) {
       
  1512             XtVaSetValues(wdata->winData.shell, XmNinput, False, NULL);
       
  1513         }
       
  1514         if (awt_wm_isStateNetHidden(XtWindow(wdata->winData.shell))) {
       
  1515             focusOnMapNotify = True;
       
  1516         }
       
  1517         break;
       
  1518     }
       
  1519 
       
  1520     case DestroyNotify: {       /* Foul play!  ICCCM forbids WM to do this! */
       
  1521         /* Your window is killed by the WM */
       
  1522         JNU_CallMethodByName(env, NULL, this, "handleDestroy", "()V");
       
  1523         if ((*env)->ExceptionOccurred(env)) {
       
  1524             (*env)->ExceptionDescribe(env);
       
  1525             (*env)->ExceptionClear(env);
       
  1526         }
       
  1527         break;
       
  1528     }
       
  1529 
       
  1530     case PropertyNotify: {
       
  1531         jint state, old_state, changed;
       
  1532 
       
  1533         /*
       
  1534          * Let's see if this is a window state protocol message, and
       
  1535          * if it is - decode a new state in terms of java constants.
       
  1536          */
       
  1537         if (!awt_wm_isStateChange(wdata, (XPropertyEvent *)event, &state)) {
       
  1538             /* Pakka Pakka seems not interested */
       
  1539             break;
       
  1540         }
       
  1541 
       
  1542         changed = wdata->state ^ state;
       
  1543         if (changed == 0) {
       
  1544             /* You feel dizzy for a moment, but nothing happens... */
       
  1545             DTRACE_PRINTLN("TL: >>> state unchanged");
       
  1546             break;
       
  1547         }
       
  1548 
       
  1549         old_state = wdata->state;
       
  1550         wdata->state = state;
       
  1551 
       
  1552 #ifdef DEBUG
       
  1553         DTRACE_PRINT("TL: >>> State Changed:");
       
  1554         if (changed & java_awt_Frame_ICONIFIED) {
       
  1555             if (state & java_awt_Frame_ICONIFIED) {
       
  1556                 DTRACE_PRINT(" ICON");
       
  1557             } else {
       
  1558                 DTRACE_PRINT(" !icon");
       
  1559             }
       
  1560         }
       
  1561         if (changed & java_awt_Frame_MAXIMIZED_VERT) {
       
  1562             if (state & java_awt_Frame_MAXIMIZED_VERT) {
       
  1563                 DTRACE_PRINT(" MAX_VERT");
       
  1564             } else {
       
  1565                 DTRACE_PRINT(" !max_vert");
       
  1566             }
       
  1567         }
       
  1568         if (changed & java_awt_Frame_MAXIMIZED_HORIZ) {
       
  1569             if (state & java_awt_Frame_MAXIMIZED_HORIZ) {
       
  1570                 DTRACE_PRINT(" MAX_HORIZ");
       
  1571             } else {
       
  1572                 DTRACE_PRINT(" !max_horiz");
       
  1573             }
       
  1574         }
       
  1575         DTRACE_PRINTLN("");
       
  1576 #endif
       
  1577 
       
  1578         if (changed & java_awt_Frame_ICONIFIED) {
       
  1579             /* Generate window de/iconified event for old clients */
       
  1580             if (state & java_awt_Frame_ICONIFIED) {
       
  1581                 DTRACE_PRINTLN("TL: ... handleIconify");
       
  1582                 JNU_CallMethodByName(env, NULL,
       
  1583                                      this, "handleIconify", "()V");
       
  1584             }
       
  1585             else {
       
  1586                 DTRACE_PRINTLN("TL: ... handleDeiconify");
       
  1587                 JNU_CallMethodByName(env, NULL,
       
  1588                                      this, "handleDeiconify", "()V");
       
  1589             }
       
  1590             if ((*env)->ExceptionOccurred(env)) {
       
  1591                 (*env)->ExceptionDescribe(env);
       
  1592                 (*env)->ExceptionClear(env);
       
  1593             }
       
  1594         }
       
  1595 
       
  1596         DTRACE_PRINTLN("TL: ... handleStateChange");
       
  1597         JNU_CallMethodByName(env, NULL,
       
  1598                              this, "handleStateChange", "(II)V",
       
  1599                              old_state, state);
       
  1600         if ((*env)->ExceptionOccurred(env)) {
       
  1601             (*env)->ExceptionDescribe(env);
       
  1602             (*env)->ExceptionClear(env);
       
  1603         }
       
  1604         break;
       
  1605     } /* PropertyNotify */
       
  1606 
       
  1607     case ReparentNotify: {
       
  1608         Window root = RootWindowOfScreen(XtScreen(wdata->winData.shell));
       
  1609 
       
  1610 #ifdef DEBUG
       
  1611         DTRACE_PRINT2("TL: ReparentNotify(0x%x/0x%x) to ",
       
  1612                       wdata->winData.shell, XtWindow(wdata->winData.shell));
       
  1613         if (event->xreparent.parent == root) {
       
  1614             DTRACE_PRINTLN("root");
       
  1615         } else {
       
  1616             DTRACE_PRINTLN1("window 0x%x", event->xreparent.parent);
       
  1617         }
       
  1618 #endif
       
  1619 
       
  1620         if (wdata->winData.flags & W_IS_EMBEDDED) {
       
  1621             DTRACE_PRINTLN("TL:   embedded frame - nothing to do");
       
  1622             break;
       
  1623         }
       
  1624 
       
  1625 #ifdef __linux__
       
  1626         if (!wdata->fixInsets) {
       
  1627             DTRACE_PRINTLN("TL:   insets already fixed");
       
  1628             break;
       
  1629         }
       
  1630         else {
       
  1631             wdata->fixInsets = False;
       
  1632         }
       
  1633 #endif
       
  1634 
       
  1635         if ((*env)->EnsureLocalCapacity(env, 1) < 0)
       
  1636             break;
       
  1637 
       
  1638         target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  1639 
       
  1640         x      = (*env)->GetIntField(env, target, componentIDs.x);
       
  1641         y      = (*env)->GetIntField(env, target, componentIDs.y);
       
  1642         width  = (*env)->GetIntField(env, target, componentIDs.width);
       
  1643         height = (*env)->GetIntField(env, target, componentIDs.height);
       
  1644 
       
  1645         /* The insets were literally hardcoded in the MWindowPeer.
       
  1646            But they are dependent upon both the window manager (WM)
       
  1647            and the hardware display.  So, these are usually wrong.
       
  1648            This leads to problems with shell positioning and size.
       
  1649            Furthermore, there is not a published interface or way
       
  1650            to obtain from any given window manager the dimensions
       
  1651            of its decoration windows (i.e., borders and title bar).
       
  1652            So, given this problem in design, we must workaround.
       
  1653            N.B. (0) This works.  But there is one functional caveat:
       
  1654            the frame.insets() function will usually return
       
  1655            the wrong values until AFTER the frame is shown.
       
  1656            It always did this before; it's just that now,
       
  1657            the values will become correct after rendering,
       
  1658            whereas before the values were never corrected.
       
  1659            (I believe this unavoidable given this design.)
       
  1660            (1) Note that we must/have to do this exactly once.
       
  1661            (2) The hardcoded values of ...create() (25,5)
       
  1662            are also utilized here and must be consistent.
       
  1663            This of course could be reworked as desired.
       
  1664            (3) Assume top border (title bar) is one width,
       
  1665            and other three borders are another width.
       
  1666            This, however, could be easily reworked below.       */
       
  1667 
       
  1668         /*
       
  1669          * The above comment is no longer completely true.
       
  1670          * The insets are no longer hardcoded but are retrieved from
       
  1671          * guessInsets(), either from a per-window manager default,
       
  1672          * set in the awt.properties file, or overwritten by the
       
  1673          * actual values determined from a previous frames
       
  1674          * reparenting.
       
  1675          */
       
  1676 
       
  1677         if (wdata->decor == AWT_NO_DECOR) {
       
  1678             if (!wdata->isResizable && !wdata->isFixedSizeSet) {
       
  1679                 reshape(env, this, wdata, x, y, width, height, False);
       
  1680                 if (wdata->warningWindow != NULL)
       
  1681                     awtJNI_ChangeInsets(env, this, wdata);
       
  1682             }
       
  1683         }
       
  1684         else if (event->xreparent.parent == root) {
       
  1685             wdata->reparented = False;
       
  1686             wdata->configure_seen = False;
       
  1687 
       
  1688             /*
       
  1689              * We can be repareted to root for two reasons:
       
  1690              *   . setVisible(false)
       
  1691              *   . WM exited
       
  1692              */
       
  1693             if (wdata->isShowing) { /* WM exited */
       
  1694                 /* Work around 4775545 */
       
  1695                 awt_wm_unshadeKludge(wdata);
       
  1696             }
       
  1697         }
       
  1698         else  { /* reparented to WM frame, figure out our insets */
       
  1699             XWindowAttributes   winAttr, actualAttr;
       
  1700             int32_t             correctWMTop = -1;
       
  1701             int32_t             correctWMLeft = -1;
       
  1702             int32_t             correctWMBottom;
       
  1703             int32_t             correctWMRight;
       
  1704             int32_t             topCorrection;
       
  1705             int32_t             leftCorrection;
       
  1706             int32_t             bottomCorrection = 0;
       
  1707             int32_t             rightCorrection = 0;
       
  1708             int32_t             screenX, screenY;
       
  1709             int32_t             i;
       
  1710             int32_t             actualWidth, actualHeight;
       
  1711             int32_t             t, l, b, r;
       
  1712             Window              containerWindow;
       
  1713 
       
  1714             /* Dummies for XQueryTree */
       
  1715             Window              ignore_Window, *ignore_WindowPtr;
       
  1716             uint32_t            ignore_uint;
       
  1717 
       
  1718             Boolean             setXY = True;
       
  1719             XSizeHints*         hints = XAllocSizeHints();
       
  1720 
       
  1721             wdata->reparented = True;
       
  1722 
       
  1723             if (hints != NULL) {
       
  1724                 long ignore = 0;
       
  1725                 XGetWMNormalHints(awt_display, XtWindow(wdata->winData.shell),
       
  1726                     hints, &ignore);
       
  1727                 setXY = (hints->flags & (USPosition|PPosition)) != 0;
       
  1728                 XFree(hints);
       
  1729             }
       
  1730 
       
  1731             /*
       
  1732              * Unfortunately the concept of "insets" borrowed to AWT
       
  1733              * from Win32 is *absolutely*, *unbelievably* foreign to
       
  1734              * X11.  Few WMs provide the size of frame decor
       
  1735              * (i.e. insets) in a property they set on the client
       
  1736              * window, so we check if we can get away with just
       
  1737              * peeking at it.  [Future versions of wm-spec might add a
       
  1738              * standardized hint for this].
       
  1739              *
       
  1740              * Otherwise we do some special casing.  Actually the
       
  1741              * fallback code ("default" case) seems to cover most of
       
  1742              * the existing WMs (modulo Reparent/Configure order
       
  1743              * perhaps?).
       
  1744              *
       
  1745              * Fallback code tries to account for the two most common cases:
       
  1746              *
       
  1747              * . single reparenting
       
  1748              *       parent window is the WM frame
       
  1749              *       [twm, olwm, sawfish]
       
  1750              *
       
  1751              * . double reparenting
       
  1752              *       parent is a lining exactly the size of the client
       
  1753              *       grandpa is the WM frame
       
  1754              *       [mwm, e!, kwin, fvwm2 ... ]
       
  1755              */
       
  1756 
       
  1757             if (awt_wm_getInsetsFromProp(event->xreparent.window,
       
  1758                                          &t, &l, &b, &r))
       
  1759             {
       
  1760                 correctWMTop    = t;
       
  1761                 correctWMLeft   = l;
       
  1762                 correctWMBottom = b;
       
  1763                 correctWMRight  = r;
       
  1764                 setXY = False;
       
  1765             }
       
  1766             else
       
  1767             switch (awt_wm_getRunningWM()) {
       
  1768 
       
  1769             /* should've been done in awt_wm_getInsetsFromProp */
       
  1770             case ENLIGHTEN_WM: {
       
  1771                 DTRACE_PRINTLN("TL:   hmm, E! insets should have been read"
       
  1772                                " from _E_FRAME_SIZE");
       
  1773                 /* enlightenment does double reparenting */
       
  1774                 syncTopLevelPos(XtDisplay(wdata->winData.shell),
       
  1775                                 event->xreparent.parent, &winAttr);
       
  1776 
       
  1777                 XQueryTree(XtDisplay(wdata->winData.shell),
       
  1778                            event->xreparent.parent,
       
  1779                            &ignore_Window,
       
  1780                            &containerWindow, /* actual WM frame */
       
  1781                            &ignore_WindowPtr,
       
  1782                            &ignore_uint);
       
  1783                 if (ignore_WindowPtr)
       
  1784                     XFree(ignore_WindowPtr);
       
  1785 
       
  1786                 correctWMLeft = winAttr.x;
       
  1787                 correctWMTop  = winAttr.y;
       
  1788 
       
  1789                 /*
       
  1790                  * Now get the actual dimensions of the parent window
       
  1791                  * resolve the difference.  We can't rely on the left
       
  1792                  * to be equal to right or bottom...  Enlightment
       
  1793                  * breaks that assumption.
       
  1794                  */
       
  1795                 XGetWindowAttributes(XtDisplay(wdata->winData.shell),
       
  1796                                      containerWindow, &actualAttr);
       
  1797                 correctWMRight  = actualAttr.width
       
  1798                     - (winAttr.width + correctWMLeft);
       
  1799                 correctWMBottom = actualAttr.height
       
  1800                     - (winAttr.height + correctWMTop) ;
       
  1801                 break;
       
  1802             }
       
  1803 
       
  1804             case ICE_WM:
       
  1805             case KDE2_WM: /* should've been done in awt_wm_getInsetsFromProp */
       
  1806             case CDE_WM:
       
  1807             case MOTIF_WM: {
       
  1808                 /* these are double reparenting too */
       
  1809                 syncTopLevelPos(XtDisplay(wdata->winData.shell),
       
  1810                                 event->xreparent.parent, &winAttr);
       
  1811 
       
  1812                 correctWMTop    = winAttr.y;
       
  1813                 correctWMLeft   = winAttr.x;
       
  1814                 correctWMRight  = correctWMLeft;
       
  1815                 correctWMBottom = correctWMLeft;
       
  1816 
       
  1817                 XTranslateCoordinates(awt_display, event->xreparent.window,
       
  1818                                       root, 0,0, &screenX, &screenY,
       
  1819                                       &containerWindow);
       
  1820 
       
  1821                 if ((screenX != x + wdata->leftGuess)
       
  1822                     || (screenY != y + wdata->topGuess))
       
  1823                 {
       
  1824                     /*
       
  1825                      * looks like the window manager has placed us somewhere
       
  1826                      * other than where we asked for, lets respect the window
       
  1827                      * and go where he put us, not where we tried to put us
       
  1828                      */
       
  1829                     x = screenX - correctWMLeft;
       
  1830                     y = screenY - correctWMTop;
       
  1831                 }
       
  1832                 break;
       
  1833             }
       
  1834 
       
  1835             case SAWFISH_WM:
       
  1836             case OPENLOOK_WM: {
       
  1837                 /* single reparenting */
       
  1838                 syncTopLevelPos(XtDisplay(wdata->winData.shell),
       
  1839                                 event->xreparent.window, &winAttr);
       
  1840 
       
  1841                 correctWMTop    = winAttr.y;
       
  1842                 correctWMLeft   = winAttr.x;
       
  1843                 correctWMRight  = correctWMLeft;
       
  1844                 correctWMBottom = correctWMLeft;
       
  1845                 break;
       
  1846             }
       
  1847 
       
  1848             case OTHER_WM:
       
  1849             default: {          /* this is very similar to the E! case above */
       
  1850                 Display *dpy = event->xreparent.display;
       
  1851                 Window w = event->xreparent.window;
       
  1852                 Window parent = event->xreparent.parent;
       
  1853                 XWindowAttributes wattr, pattr;
       
  1854 
       
  1855                 XGetWindowAttributes(dpy, w, &wattr);
       
  1856                 XGetWindowAttributes(dpy, parent, &pattr);
       
  1857 
       
  1858                 DTRACE_PRINTLN5("TL:   window attr +%d+%d+%dx%d (%d)",
       
  1859                                 wattr.x, wattr.y, wattr.width, wattr.height,
       
  1860                                 wattr.border_width);
       
  1861                 DTRACE_PRINTLN5("TL:   parent attr +%d+%d+%dx%d (%d)",
       
  1862                                 pattr.x, pattr.y, pattr.width, pattr.height,
       
  1863                                 pattr.border_width);
       
  1864 
       
  1865                 /*
       
  1866                  * Check for double-reparenting WM.
       
  1867                  *
       
  1868                  * If the parent is exactly the same size as the
       
  1869                  * top-level assume taht it's the "lining" window and
       
  1870                  * that the grandparent is the actual frame (NB: we
       
  1871                  * have already handled undecorated windows).
       
  1872                  *
       
  1873                  * XXX: what about timing issues that syncTopLevelPos
       
  1874                  * is supposed to work around?
       
  1875                  */
       
  1876                 if (wattr.x == 0 && wattr.y == 0
       
  1877                     && wattr.width  + 2*wattr.border_width == pattr.width
       
  1878                     && wattr.height + 2*wattr.border_width == pattr.height)
       
  1879                 {
       
  1880                     Window ignore_root, grandparent, *children;
       
  1881                     unsigned int ignore_nchildren;
       
  1882 
       
  1883                     DTRACE_PRINTLN("TL:   double reparenting WM detected");
       
  1884                     XQueryTree(dpy, parent,
       
  1885                                &ignore_root,
       
  1886                                &grandparent,
       
  1887                                &children,
       
  1888                                &ignore_nchildren);
       
  1889                     if (children)
       
  1890                         XFree(children);
       
  1891 
       
  1892                     /* take lining window into account */
       
  1893                     wattr.x = pattr.x;
       
  1894                     wattr.y = pattr.y;
       
  1895                     wattr.border_width += pattr.border_width;
       
  1896 
       
  1897                     parent = grandparent;
       
  1898                     XGetWindowAttributes(dpy, parent, &pattr);
       
  1899                     DTRACE_PRINTLN5("TL:   window attr +%d+%d+%dx%d (%d)",
       
  1900                                     wattr.x, wattr.y,
       
  1901                                     wattr.width, wattr.height,
       
  1902                                     wattr.border_width);
       
  1903                     DTRACE_PRINTLN5("TL:   parent attr +%d+%d+%dx%d (%d)",
       
  1904                                     pattr.x, pattr.y,
       
  1905                                     pattr.width, pattr.height,
       
  1906                                     pattr.border_width);
       
  1907                 }
       
  1908 
       
  1909                 /*
       
  1910                  * XXX: To be absolutely correct, we'd need to take
       
  1911                  * parent's border-width into account too, but the
       
  1912                  * rest of the code is happily unaware about border
       
  1913                  * widths and inner/outer distinction, so for the time
       
  1914                  * being, just ignore it.
       
  1915                  */
       
  1916                 correctWMTop = wattr.y + wattr.border_width;
       
  1917                 correctWMLeft = wattr.x + wattr.border_width;
       
  1918                 correctWMBottom = pattr.height
       
  1919                     - (wattr.y + wattr.height + 2*wattr.border_width);
       
  1920                 correctWMRight = pattr.width
       
  1921                     - (wattr.x + wattr.width + 2*wattr.border_width);
       
  1922                 DTRACE_PRINTLN4("TL: insets = top %d, left %d, bottom %d, right %d",
       
  1923                                 correctWMTop, correctWMLeft,
       
  1924                                 correctWMBottom, correctWMRight);
       
  1925                 break;
       
  1926             } /* default */
       
  1927 
       
  1928             } /* switch (runningWM) */
       
  1929 
       
  1930 
       
  1931             /*
       
  1932              * Ok, now see if we need adjust window size because
       
  1933              * initial insets were wrong (most likely they were).
       
  1934              */
       
  1935             topCorrection    = correctWMTop    - wdata->topGuess;
       
  1936             leftCorrection   = correctWMLeft   - wdata->leftGuess;
       
  1937             bottomCorrection = correctWMBottom - wdata->bottomGuess;
       
  1938             rightCorrection  = correctWMRight  - wdata->rightGuess;
       
  1939 
       
  1940             DTRACE_PRINTLN3("TL: top:    computed=%d, guess=%d, correction=%d",
       
  1941                 correctWMTop, wdata->topGuess, topCorrection);
       
  1942             DTRACE_PRINTLN3("TL: left:   computed=%d, guess=%d, correction=%d",
       
  1943                 correctWMLeft, wdata->leftGuess, leftCorrection);
       
  1944             DTRACE_PRINTLN3("TL: bottom: computed=%d, guess=%d, correction=%d",
       
  1945                 correctWMBottom, wdata->bottomGuess, bottomCorrection);
       
  1946             DTRACE_PRINTLN3("TL: right:  computed=%d, guess=%d, correction=%d",
       
  1947                 correctWMRight, wdata->rightGuess, rightCorrection);
       
  1948 
       
  1949             if (topCorrection != 0 || leftCorrection != 0
       
  1950                 || bottomCorrection != 0 || rightCorrection != 0)
       
  1951             {
       
  1952                 jboolean isPacked;
       
  1953 
       
  1954                 DTRACE_PRINTLN("TL: insets need correction");
       
  1955                 wdata->need_reshape = True;
       
  1956 
       
  1957                 globalTopGuess    = correctWMTop;
       
  1958                 globalLeftGuess   = correctWMLeft;
       
  1959                 globalBottomGuess = correctWMBottom;
       
  1960                 globalRightGuess  = correctWMRight;
       
  1961 
       
  1962                 /* guesses are for WM decor *only* */
       
  1963                 wdata->topGuess    = correctWMTop;
       
  1964                 wdata->leftGuess   = correctWMLeft;
       
  1965                 wdata->bottomGuess = correctWMBottom;
       
  1966                 wdata->rightGuess  = correctWMRight;
       
  1967 
       
  1968                 /*
       
  1969                  * Actual insets account for menubar/warning label,
       
  1970                  * so we can't assign directly but must adjust them.
       
  1971                  */
       
  1972                 wdata->top    += topCorrection;
       
  1973                 wdata->left   += leftCorrection;
       
  1974                 wdata->bottom += bottomCorrection;
       
  1975                 wdata->right  += rightCorrection;
       
  1976 
       
  1977                 awtJNI_ChangeInsets(env, this, wdata);
       
  1978 
       
  1979                 /*
       
  1980                  * If this window has been sized by a pack() we need
       
  1981                  * to keep the interior geometry intact.  Since pack()
       
  1982                  * computed width and height with wrong insets, we
       
  1983                  * must adjust the target dimensions appropriately.
       
  1984                  */
       
  1985                 isPacked = (*env)->GetBooleanField(env, target,
       
  1986                                                    componentIDs.isPacked);
       
  1987                 if (isPacked) {
       
  1988                     int32_t correctTargetW;
       
  1989                     int32_t correctTargetH;
       
  1990 
       
  1991                     DTRACE_PRINTLN("TL: window is packed, "
       
  1992                                    "adjusting size to preserve layout");
       
  1993 
       
  1994                     correctTargetW = width + (leftCorrection + rightCorrection);
       
  1995                     correctTargetH = height +(topCorrection + bottomCorrection);
       
  1996 
       
  1997                     (*env)->SetIntField(env, target, componentIDs.width,
       
  1998                                         (jint) correctTargetW);
       
  1999                     (*env)->SetIntField(env, target, componentIDs.height,
       
  2000                                         (jint) correctTargetH);
       
  2001                     /*
       
  2002                     **  Normally you only reconfigure the outerCanvas due to
       
  2003                     **  handling the ReconfigureNotify on the innerCanvas.
       
  2004                     **  However, in this case the innerCanvas may not have
       
  2005                     **  changed, but outterCanvas may still need to, since the
       
  2006                     **  insets have changed.
       
  2007                     */
       
  2008                     reshape(env, this, wdata, x, y,
       
  2009                             correctTargetW, correctTargetH, setXY);
       
  2010                     reconfigureOuterCanvas(env, target, this, wdata);
       
  2011                 } else {
       
  2012                     reshape(env, this, wdata, x, y, width, height, setXY);
       
  2013                     JNU_CallMethodByName(env, NULL, this,
       
  2014                         "handleResize", "(II)V", width, height);
       
  2015                 }
       
  2016             }
       
  2017 /* NEW for dialog */ /* XXX: what this comment is supposed to mean? */
       
  2018             else {
       
  2019                 wdata->need_reshape = False;
       
  2020                 /* fix for 4976337 - son@sparc.spb.su */
       
  2021                 /* we should find better fix later if needed */
       
  2022                 if (wdata->isResizable || !wdata->isFixedSizeSet) {
       
  2023                     reshape(env, this, wdata, x, y, width, height, setXY);
       
  2024                 }
       
  2025             }
       
  2026         }
       
  2027         (*env)->DeleteLocalRef(env, target);
       
  2028         break;
       
  2029     } /* ReparentNotify */
       
  2030 
       
  2031     case ConfigureNotify: {
       
  2032         DTRACE_PRINTLN2("TL: ConfigureNotify(0x%x/0x%x)",
       
  2033                         wdata->winData.shell, XtWindow(wdata->winData.shell));
       
  2034 
       
  2035         /*
       
  2036          * Some window managers configure before we are reparented and
       
  2037          * the send event flag is set! ugh... (Enlighetenment for one,
       
  2038          * possibly MWM as well).  If we haven't been reparented yet
       
  2039          * this is just the WM shuffling us into position.  Ignore
       
  2040          * it!!!! or we wind up in a bogus location.
       
  2041          */
       
  2042         runningWM = awt_wm_getRunningWM();
       
  2043         if (!wdata->reparented && wdata->isShowing &&
       
  2044             runningWM != NO_WM && wdata->decor != AWT_NO_DECOR) {
       
  2045             break;
       
  2046         }
       
  2047 
       
  2048         /*
       
  2049          * Notice that we have seen a ConfigureNotify after being
       
  2050          * reparented.  We should really check for it being a
       
  2051          * synthetic event, but metacity doesn't send one.
       
  2052          */
       
  2053         if (wdata->reparented)
       
  2054             wdata->configure_seen = 1;
       
  2055 
       
  2056         if ((*env)->EnsureLocalCapacity(env, 1) < 0) {
       
  2057             break;
       
  2058         }
       
  2059         target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  2060 
       
  2061         /*
       
  2062          * We can detect the difference between a move and a resize by
       
  2063          * checking the send_event flag on the event; if it's true,
       
  2064          * then it's indeed a move, if it's false, then this is a
       
  2065          * resize and we do not want to process it as a "move" (for
       
  2066          * resizes the x,y values are misleadingly set to 0,0 and so
       
  2067          * just checking for an x,y delta won't work).
       
  2068          */
       
  2069 
       
  2070         getTargetX = (*env)->GetIntField(env, target, componentIDs.x);
       
  2071         getTargetY = (*env)->GetIntField(env, target, componentIDs.y);
       
  2072 
       
  2073         DTRACE_PRINTLN2("TL:   target thinks (%d, %d)",
       
  2074                         getTargetX, getTargetY);
       
  2075         DTRACE_PRINTLN3("TL:   event is (%d, %d)%s",
       
  2076                         event->xconfigure.x, event->xconfigure.y,
       
  2077                         (event->xconfigure.send_event ? " synthetic" : ""));
       
  2078 
       
  2079         /*
       
  2080          * N.B. The wdata top offset is the offset from the outside of
       
  2081          * the entire (bordered window) to the inner/parent drawing
       
  2082          * area (canvas), NOT to the shell.  Thus, if a menubar is
       
  2083          * present and/or a warning window at the top (not NETSCAPE),
       
  2084          * the top offset will also include space for these.  In order
       
  2085          * to position the abstract java window relative to the shell,
       
  2086          * we must add back in the appropriate space for these when we
       
  2087          * subtract off the wdata top field.
       
  2088          */
       
  2089 #ifdef NETSCAPE
       
  2090         wwHeight = 0;
       
  2091 #else /* NETSCAPE */
       
  2092         if (wdata->warningWindow != NULL)
       
  2093             wwHeight = wdata->wwHeight;
       
  2094         else
       
  2095             wwHeight = 0;
       
  2096 #endif /* NETSCAPE */
       
  2097         topAdjust = wdata->mbHeight + wwHeight;
       
  2098 
       
  2099         /*
       
  2100          * Coordinates in Component.setLocation() are treated as the
       
  2101          * upper-left corner of the outer shell.  The x and y in the
       
  2102          * ConfigureNotify event, however, are the upper-left corner
       
  2103          * of the inset CLIENT window.  Therefore, the coordinates
       
  2104          * from the event are massaged using the inset values in order
       
  2105          * to determine if the top-level shell has moved.  In the
       
  2106          * event of a user- generated move event (i.e. dragging the
       
  2107          * window itself), these coordinates are written back into the
       
  2108          * Window object.
       
  2109          *
       
  2110          * Neat X/CDE/Native bug:
       
  2111          * If an attempt is made to move the shell in the y direction
       
  2112          * by an amount equal to the top inset, the Window isn't
       
  2113          * moved.  This can be seen here by examining event->xconfigure.y
       
  2114          * before and after such a request is made: the value remains
       
  2115          * unchanged.  This wrecks a little havoc here, as the x and y
       
  2116          * in the Component have already been set to the new location
       
  2117          * (in Component.reshape()), but the Window doesn't end up in
       
  2118          * the new location.  What's more, if a second request is
       
  2119          * made, the window will be relocated by TWICE the requested
       
  2120          * amount, sort of "catching up" it would seem.
       
  2121          *
       
  2122          * For a test case of this, see bug 4234645.
       
  2123          */
       
  2124         setTargetX = event->xconfigure.x - wdata->left;
       
  2125         setTargetY = event->xconfigure.y - wdata->top + topAdjust;
       
  2126 
       
  2127         width = (*env)->GetIntField(env, target, componentIDs.width);
       
  2128         height = (*env)->GetIntField(env, target, componentIDs.height);
       
  2129         checkNewXineramaScreen(env, this, wdata, setTargetX, setTargetY,
       
  2130                                width, height);
       
  2131 
       
  2132         if ((getTargetX != setTargetX || getTargetY != setTargetY)
       
  2133             && (event->xconfigure.send_event || runningWM == NO_WM))
       
  2134         {
       
  2135             (*env)->SetIntField(env, target, componentIDs.x, (jint)setTargetX);
       
  2136             (*env)->SetIntField(env, target, componentIDs.y, (jint)setTargetY);
       
  2137 #ifdef _pauly_debug
       
  2138             fprintf(stdout, " ++ shell move. Xevent x,y: %d, %d.\n",
       
  2139                     event->xconfigure.x, event->xconfigure.y);
       
  2140             fprintf(stdout, "    shell move. left: %d, top: %d, but offset: %d\n", wdata->left, wdata->top, topAdjust);
       
  2141             fprintf(stdout,"    shell move. target x: %d, target y: %d\n", setTargetX, setTargetY);
       
  2142             fprintf(stdout,"    shell move. ww height: %d\n", wwHeight);
       
  2143             fflush(stdout);
       
  2144 #endif /* _pauly_debug */
       
  2145 
       
  2146             DTRACE_PRINTLN2("TL:   handleMoved(%d, %d)",
       
  2147                             setTargetX, setTargetY);
       
  2148             JNU_CallMethodByName(env, NULL,
       
  2149                                  this, "handleMoved", "(II)V",
       
  2150                                  setTargetX, setTargetY);
       
  2151             if ((*env)->ExceptionOccurred(env)) {
       
  2152                 (*env)->ExceptionDescribe(env);
       
  2153                 (*env)->ExceptionClear(env);
       
  2154             }
       
  2155         }
       
  2156         else if (event->xconfigure.send_event == False) {
       
  2157 #ifdef _pauly_debug
       
  2158             fprintf(stdout,
       
  2159                     " ++ shell resize. Xevent x,y,w,h: %d, %d, %d, %d.\n",
       
  2160                     event->xconfigure.x, event->xconfigure.y,
       
  2161                     event->xconfigure.width, event->xconfigure.height);
       
  2162             fflush(stdout);
       
  2163 #endif /* _pauly_debug */
       
  2164 
       
  2165             wdata->shellResized = True;
       
  2166         }
       
  2167 
       
  2168 
       
  2169         (*env)->DeleteLocalRef(env, target);
       
  2170         raiseInputMethodWindow(wdata);
       
  2171 #ifdef __linux__
       
  2172         adjustStatusWindow(wdata->winData.shell);
       
  2173 #endif
       
  2174         break;
       
  2175     } /* ConfigureNotify */
       
  2176 
       
  2177     default:
       
  2178         break;
       
  2179     }
       
  2180 }
       
  2181 
       
  2182 
       
  2183 static void
       
  2184 Frame_quit(Widget w,
       
  2185            XtPointer client_data,
       
  2186            XtPointer call_data)
       
  2187 {
       
  2188     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  2189 
       
  2190     JNU_CallMethodByName(env, NULL, (jobject) client_data, "handleQuit", "()V");
       
  2191     if ((*env)->ExceptionOccurred(env)) {
       
  2192         (*env)->ExceptionDescribe(env);
       
  2193         (*env)->ExceptionClear(env);
       
  2194     }
       
  2195 }
       
  2196 
       
  2197 
       
  2198 static void
       
  2199 setDeleteCallback(jobject this, struct FrameData *wdata)
       
  2200 {
       
  2201     Atom xa_WM_DELETE_WINDOW;
       
  2202     Atom xa_WM_TAKE_FOCUS;
       
  2203     Atom xa_WM_PROTOCOLS;
       
  2204 
       
  2205     XtVaSetValues(wdata->winData.shell,
       
  2206                   XmNdeleteResponse, XmDO_NOTHING,
       
  2207                   NULL);
       
  2208     xa_WM_DELETE_WINDOW = XmInternAtom(XtDisplay(wdata->winData.shell),
       
  2209                                        "WM_DELETE_WINDOW", False);
       
  2210     xa_WM_TAKE_FOCUS = XmInternAtom(XtDisplay(wdata->winData.shell),
       
  2211                                     "WM_TAKE_FOCUS", False);
       
  2212     xa_WM_PROTOCOLS = XmInternAtom(XtDisplay(wdata->winData.shell),
       
  2213                                    "WM_PROTOCOLS", False);
       
  2214 
       
  2215     XmAddProtocolCallback(wdata->winData.shell,
       
  2216                           xa_WM_PROTOCOLS,
       
  2217                           xa_WM_DELETE_WINDOW,
       
  2218                           Frame_quit, (XtPointer) this);
       
  2219 }
       
  2220 
       
  2221 
       
  2222 extern AwtGraphicsConfigDataPtr
       
  2223 copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
       
  2224 
       
  2225 extern AwtGraphicsConfigDataPtr
       
  2226 getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
       
  2227 
       
  2228 // Returns true if this shell has some transient shell chidlren
       
  2229 // which are either Dialogs or Windows.
       
  2230 // Returns false otherwise.
       
  2231 Boolean hasTransientChildren(Widget shell) {
       
  2232     int childIndex;
       
  2233 
       
  2234     // Enumerate through the popups
       
  2235     for (childIndex = 0; childIndex < shell->core.num_popups; childIndex++) {
       
  2236         Widget childShell = shell->core.popup_list[childIndex];
       
  2237         // Find all transient shell which are either Dialog or Window
       
  2238         if (XtIsTransientShell(childShell)) {
       
  2239             Widget toplevel = findTopLevelByShell(childShell);
       
  2240             if (toplevel != NULL) {
       
  2241                 // It is Dialog or Window - return true.
       
  2242                 return True;
       
  2243             }
       
  2244         }
       
  2245     }
       
  2246     return False;
       
  2247 }
       
  2248 
       
  2249 extern Widget grabbed_widget;
       
  2250 /**
       
  2251  * Disposes top-level component and its widgets
       
  2252  */
       
  2253 static
       
  2254 void disposeTopLevel(JNIEnv * env, jobject this) {
       
  2255 
       
  2256     struct FrameData *wdata;
       
  2257     Widget parentShell;
       
  2258 
       
  2259     wdata = (struct FrameData *)
       
  2260         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  2261 
       
  2262     if (wdata == NULL || wdata->mainWindow == NULL
       
  2263         || wdata->winData.shell == NULL)
       
  2264     {
       
  2265         /* do nothing */
       
  2266         return;
       
  2267     }
       
  2268 
       
  2269     // Save parent shell for later disposal.
       
  2270     parentShell = XtParent(wdata->winData.shell);
       
  2271 
       
  2272     removeTopLevel(wdata);
       
  2273     if (wdata->isInputMethodWindow) {
       
  2274         removeInputMethodWindow(wdata);
       
  2275     }
       
  2276 
       
  2277     XtRemoveEventHandler(wdata->focusProxy, FocusChangeMask,
       
  2278                          False, shellEH, this);
       
  2279     XtUnmanageChild(wdata->focusProxy);
       
  2280     awt_util_consumeAllXEvents(wdata->focusProxy);
       
  2281     awt_util_cleanupBeforeDestroyWidget(wdata->focusProxy);
       
  2282     XtDestroyWidget(wdata->focusProxy);
       
  2283 
       
  2284     XtUnmanageChild(wdata->winData.comp.widget);
       
  2285     awt_delWidget(wdata->winData.comp.widget);
       
  2286     awt_util_consumeAllXEvents(wdata->winData.comp.widget);
       
  2287     awt_util_cleanupBeforeDestroyWidget(wdata->winData.comp.widget);
       
  2288     XtDestroyWidget(wdata->winData.comp.widget);
       
  2289 
       
  2290     XtUnmanageChild(wdata->mainWindow);
       
  2291     awt_util_consumeAllXEvents(wdata->mainWindow);
       
  2292     awt_util_consumeAllXEvents(wdata->winData.shell);
       
  2293     XtDestroyWidget(wdata->mainWindow);
       
  2294     XtDestroyWidget(wdata->winData.shell);
       
  2295     if (wdata->iconPixmap) {
       
  2296         XFreePixmap(awt_display, wdata->iconPixmap);
       
  2297     }
       
  2298 
       
  2299     if (grabbed_widget == wdata->winData.shell) {
       
  2300         XUngrabPointer(awt_display, CurrentTime);
       
  2301         XUngrabKeyboard(awt_display, CurrentTime);
       
  2302         grabbed_widget = NULL;
       
  2303     }
       
  2304 
       
  2305     free((void *) wdata);
       
  2306 
       
  2307     (*env)->SetLongField(env, this, mComponentPeerIDs.pData, 0);
       
  2308     awtJNI_DeleteGlobalRef(env, this);
       
  2309 
       
  2310     // Check if parent shell was scheduled for disposal.
       
  2311     // If it doesn't have window then we have to dispose it
       
  2312     // by ourselves right now.
       
  2313     // We can dispose shell only if it doesn't have "transient" children.
       
  2314     {
       
  2315         struct FrameData *pdata;
       
  2316         struct WidgetInfo* winfo;
       
  2317         Widget toplevel = findTopLevelByShell(parentShell);
       
  2318         if (toplevel == NULL) {
       
  2319             // Has already been deleted or it is top shell
       
  2320             return;
       
  2321         }
       
  2322         winfo = findWidgetInfo(toplevel);
       
  2323         DASSERT(winfo != NULL);
       
  2324         if (winfo == NULL) {
       
  2325             // Huh - has already been deleted?
       
  2326             return;
       
  2327         }
       
  2328         pdata = (struct FrameData *)
       
  2329             JNU_GetLongFieldAsPtr(env, winfo->peer, mComponentPeerIDs.pData);
       
  2330         DASSERT(pdata != NULL);
       
  2331         if (pdata == NULL) {
       
  2332             // Huh - has already been deleted?
       
  2333             return;
       
  2334         }
       
  2335         // 1) scheduled 2) no children 3) no window
       
  2336         if (pdata->isDisposeScheduled
       
  2337             && !hasTransientChildren(parentShell)
       
  2338             && XtWindow(parentShell) == None)
       
  2339         {
       
  2340             disposeTopLevel(env, winfo->peer);
       
  2341         }
       
  2342     }
       
  2343 }
       
  2344 
       
  2345 
       
  2346 /**
       
  2347  * Property change listener. Listens to _XA_JAVA_DISPOSE_PROPERTY_ATOM,
       
  2348  * disposes the top-level when this property has been changed.
       
  2349  */
       
  2350 static void
       
  2351 shellDisposeNotifyHandler(Widget w, XtPointer client_data,
       
  2352                            XEvent* event, Boolean* continue_to_dispatch) {
       
  2353     struct FrameData *wdata;
       
  2354 
       
  2355     *continue_to_dispatch = True;
       
  2356 
       
  2357     if (event->type == PropertyNotify &&
       
  2358         event->xproperty.atom == _XA_JAVA_DISPOSE_PROPERTY_ATOM)
       
  2359     {
       
  2360         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  2361 
       
  2362         wdata = (struct FrameData *)
       
  2363             JNU_GetLongFieldAsPtr(env, (jobject)client_data,
       
  2364                                   mComponentPeerIDs.pData);
       
  2365         if (wdata != NULL && wdata->isDisposeScheduled) {
       
  2366             disposeTopLevel(env, (jobject)client_data);
       
  2367 
       
  2368             // We've disposed top-level, no more actions on it
       
  2369             *continue_to_dispatch = False;
       
  2370         }
       
  2371     }
       
  2372 }
       
  2373 
       
  2374 /**
       
  2375  * Schedules top-level for later dispose - when all events
       
  2376  * on it will be processed.
       
  2377  */
       
  2378 static
       
  2379 void scheduleDispose(JNIEnv * env, jobject peer) {
       
  2380 
       
  2381     struct FrameData *wdata;
       
  2382 
       
  2383     wdata = (struct FrameData *)
       
  2384         JNU_GetLongFieldAsPtr(env, peer, mComponentPeerIDs.pData);
       
  2385 
       
  2386     if (wdata->isDisposeScheduled) {
       
  2387         return;
       
  2388     }
       
  2389 
       
  2390     wdata->isDisposeScheduled = True;
       
  2391     if (XtWindow(wdata->winData.shell) != None) {
       
  2392         XChangeProperty(awt_display, XtWindow(wdata->winData.shell),
       
  2393                         _XA_JAVA_DISPOSE_PROPERTY_ATOM, XA_ATOM, 32, PropModeAppend,
       
  2394                         (unsigned char *)"", 0);
       
  2395         XFlush(awt_display);
       
  2396         XSync(awt_display, False);
       
  2397     } else {
       
  2398         // If this top-level has children which are still visible then
       
  2399         // their disposal could have been scheduled. We shouldn't allow this widget
       
  2400 // to destroy its children top-levels. For this purpose we postpone the disposal
       
  2401         // of this toplevel until after all its children are disposed.
       
  2402         if (!hasTransientChildren(wdata->winData.shell)) {
       
  2403             disposeTopLevel(env, peer);
       
  2404         }
       
  2405     }
       
  2406 }
       
  2407 
       
  2408 
       
  2409 /* sun_awt_motif_MWindowPeer_pCreate() is native (X/Motif) create routine */
       
  2410 static char* focusProxyName = "FocusProxy";
       
  2411 
       
  2412 Widget createFocusProxy(jobject globalRef, Widget parent) {
       
  2413     Widget proxy;
       
  2414 #define MAX_ARGC 20
       
  2415     Arg args[MAX_ARGC];
       
  2416     int32_t argc;
       
  2417 
       
  2418     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  2419 
       
  2420     if (parent == NULL) {
       
  2421         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  2422         return NULL;
       
  2423     }
       
  2424     argc = 0;
       
  2425     XtSetArg(args[argc], XmNwidth, 1);
       
  2426     argc++;
       
  2427     XtSetArg(args[argc], XmNheight, 1);
       
  2428     argc++;
       
  2429     XtSetArg(args[argc], XmNx, -1);
       
  2430     argc++;
       
  2431     XtSetArg(args[argc], XmNy, -1);
       
  2432     argc++;
       
  2433     XtSetArg(args[argc], XmNmarginWidth, 0);
       
  2434     argc++;
       
  2435     XtSetArg(args[argc], XmNmarginHeight, 0);
       
  2436     argc++;
       
  2437     XtSetArg(args[argc], XmNspacing, 0);
       
  2438     argc++;
       
  2439     XtSetArg(args[argc], XmNresizePolicy, XmRESIZE_NONE);
       
  2440     argc++;
       
  2441 
       
  2442     DASSERT(!(argc > MAX_ARGC));
       
  2443     proxy = XmCreateDrawingArea(parent, focusProxyName, args, argc);
       
  2444     XtAddEventHandler(proxy,
       
  2445                       FocusChangeMask,
       
  2446                       False, shellEH, globalRef);
       
  2447     XtManageChild(proxy);
       
  2448 #undef MAX_ARGC
       
  2449     return proxy;
       
  2450 }
       
  2451 
       
  2452 /*
       
  2453  * Class:     sun_awt_motif_MWindowPeer
       
  2454  * Method:    pCreate
       
  2455  * Signature: (Lsun/awt/motif/MComponentPeer;Ljava/lang/String;)V
       
  2456  */
       
  2457 JNIEXPORT void JNICALL
       
  2458 Java_sun_awt_motif_MWindowPeer_pCreate(JNIEnv *env, jobject this,
       
  2459     jobject parent, jstring target_class_name, jboolean isFocusableWindow)
       
  2460 {
       
  2461 #define MAX_ARGC 50
       
  2462     Arg                 args[MAX_ARGC];
       
  2463     int32_t             argc;
       
  2464     struct FrameData    *wdata;
       
  2465     struct FrameData    *pdata = NULL;
       
  2466     char                *shell_name = NULL;
       
  2467     WidgetClass         shell_class;
       
  2468     Widget              parent_widget;
       
  2469     jobject             target;
       
  2470     jobject             insets;
       
  2471     jobject             winAttr;
       
  2472     jstring             warningString;
       
  2473     jboolean            resizable;
       
  2474     jboolean            isModal;
       
  2475     jboolean            initialFocus;
       
  2476     jint                state;
       
  2477     jclass              clazz;
       
  2478     jobject             globalRef = awtJNI_CreateAndSetGlobalRef(env, this);
       
  2479 
       
  2480     uint32_t            runningWM;      /* the running Window Manager   */
       
  2481     Widget              innerCanvasW;   /* form's child, parent of the
       
  2482                                            outer canvas (drawing area)  */
       
  2483     Position            x,y;
       
  2484     Dimension           w,h;
       
  2485     AwtGraphicsConfigDataPtr adata;
       
  2486     AwtGraphicsConfigDataPtr defConfig;
       
  2487     jobject gd = NULL;
       
  2488     jobject gc = NULL;
       
  2489     char *cname = NULL;
       
  2490     jstring jname;
       
  2491 
       
  2492     AWT_LOCK();
       
  2493 
       
  2494     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  2495 
       
  2496     if (JNU_IsNull(env, target)) {
       
  2497         JNU_ThrowNullPointerException(env, "null target");
       
  2498         AWT_UNLOCK();
       
  2499         return;
       
  2500     }
       
  2501 
       
  2502     wdata = ZALLOC(FrameData);
       
  2503     JNU_SetLongFieldFromPtr(env, this, mComponentPeerIDs.pData, wdata);
       
  2504     if (wdata == NULL) {
       
  2505         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
  2506         AWT_UNLOCK();
       
  2507         return;
       
  2508     }
       
  2509 
       
  2510     adata = copyGraphicsConfigToPeer(env, this);
       
  2511     defConfig = getDefaultConfig(adata->awt_visInfo.screen);
       
  2512 
       
  2513 
       
  2514     /* Retrieve the specified characteristics for this window */
       
  2515     winAttr = (*env)->GetObjectField(env, this, mWindowPeerIDs.winAttr);
       
  2516     resizable = (*env)->GetBooleanField( env,
       
  2517                                          winAttr,
       
  2518                                          mWindowAttributeIDs.isResizable);
       
  2519     state = (*env)->GetIntField( env,
       
  2520                                  winAttr,
       
  2521                                  mWindowAttributeIDs.initialState);
       
  2522     initialFocus = (*env)->GetBooleanField( env,
       
  2523                                             winAttr,
       
  2524                                             mWindowAttributeIDs.initialFocus);
       
  2525 
       
  2526     /* As of today decor is either on or off... except the InputMethodWindow */
       
  2527     if ((*env)->GetBooleanField(env, winAttr, mWindowAttributeIDs.nativeDecor)) {
       
  2528         wdata->decor = (*env)->GetIntField(env, winAttr, mWindowAttributeIDs.decorations);
       
  2529     } else {
       
  2530         wdata->decor = AWT_NO_DECOR;
       
  2531     }
       
  2532 
       
  2533     insets = (*env)->GetObjectField(env, this, mWindowPeerIDs.insets);
       
  2534 
       
  2535     /* The insets will be corrected upon the reparent
       
  2536            event in shellEH().  For now, use bogus values.      */
       
  2537     wdata->top = (*env)->GetIntField(env, insets, insetsIDs.top);
       
  2538     wdata->left = (*env)->GetIntField(env, insets, insetsIDs.left);
       
  2539     wdata->bottom = (*env)->GetIntField(env, insets, insetsIDs.bottom);
       
  2540     wdata->right = (*env)->GetIntField(env, insets, insetsIDs.right);
       
  2541     awt_Frame_guessInsets(wdata);
       
  2542     awtJNI_ChangeInsets(env, this, wdata);
       
  2543     wdata->reparented = False;
       
  2544     wdata->configure_seen = False;
       
  2545     x = (*env)->GetIntField(env, target, componentIDs.x) + wdata->left;
       
  2546     y = (*env)->GetIntField(env, target, componentIDs.y) + wdata->top;
       
  2547 
       
  2548     w = (*env)->GetIntField(env, target, componentIDs.width)
       
  2549         - (wdata->left + wdata->right);
       
  2550     h = (*env)->GetIntField(env, target, componentIDs.height)
       
  2551         - (wdata->top + wdata->bottom);
       
  2552     if (w < 0) w = 0;
       
  2553     if (h < 0) h = 0;
       
  2554 
       
  2555     DTRACE_PRINTLN1("TL: pCreate: state = 0x%X", state);
       
  2556 
       
  2557     wdata->isModal = 0;
       
  2558     wdata->initialFocus = (Boolean)initialFocus;
       
  2559     wdata->isShowing = False;
       
  2560     wdata->shellResized = False;
       
  2561     wdata->canvasResized = False;
       
  2562     wdata->menuBarReset = False;
       
  2563     wdata->need_reshape = False;
       
  2564     wdata->focusProxy = NULL;
       
  2565 #ifdef __linux__
       
  2566     wdata->fixInsets = True;
       
  2567 #endif
       
  2568     wdata->state = state;
       
  2569 
       
  2570     /* initialize screen to screen number in GraphicsConfig's device */
       
  2571     /* can the Window's GC ever be null? */
       
  2572     gc =  (*env)->GetObjectField(env, target, componentIDs.graphicsConfig);
       
  2573     DASSERT(gc);
       
  2574 
       
  2575     gd =  (*env)->GetObjectField(env, gc, x11GraphicsConfigIDs.screen);
       
  2576     DASSERT(gd);
       
  2577 
       
  2578     wdata->screenNum = (*env)->GetIntField(env, gd, x11GraphicsDeviceIDs.screen);
       
  2579 
       
  2580     wdata->isFocusableWindow = (Boolean)isFocusableWindow;
       
  2581 
       
  2582     /*
       
  2583      * Create a top-level shell widget.
       
  2584      */
       
  2585     argc = 0;
       
  2586     XtSetArg(args[argc], XmNsaveUnder, False); argc++;
       
  2587     if (resizable) {
       
  2588         XtSetArg(args[argc], XmNallowShellResize, True); argc++;
       
  2589     } else {
       
  2590         XtSetArg(args[argc], XmNallowShellResize, False); argc++;
       
  2591     }
       
  2592     XtSetArg(args[argc], XmNvisual, defConfig->awt_visInfo.visual); argc++;
       
  2593     XtSetArg(args[argc], XmNcolormap, defConfig->awt_cmap); argc++;
       
  2594     XtSetArg(args[argc], XmNdepth, defConfig->awt_depth); argc++;
       
  2595     XtSetArg(args[argc], XmNmappedWhenManaged, False); argc++;
       
  2596     XtSetArg(args[argc], XmNx, x); argc++;
       
  2597     XtSetArg(args[argc], XmNy, y); argc++;
       
  2598     XtSetArg(args[argc], XmNwidth, w); argc++;
       
  2599     XtSetArg(args[argc], XmNheight, h); argc++;
       
  2600 
       
  2601     XtSetArg(args[argc], XmNbuttonFontList, getMotifFontList()); argc++;
       
  2602     XtSetArg(args[argc], XmNlabelFontList, getMotifFontList()); argc++;
       
  2603     XtSetArg(args[argc], XmNtextFontList, getMotifFontList()); argc++;
       
  2604 
       
  2605     XtSetArg(args[argc], XmNmwmDecorations, wdata->decor); argc++;
       
  2606     XtSetArg(args[argc], XmNscreen,
       
  2607              ScreenOfDisplay(awt_display, defConfig->awt_visInfo.screen)); argc++;
       
  2608 
       
  2609     if (wdata->initialFocus == False || !isFocusableWindowByPeer(env, this)) {
       
  2610         XtSetArg(args[argc], XmNinput, False); argc++;
       
  2611     }
       
  2612 
       
  2613     if (wdata->decor == AWT_NO_DECOR) {
       
  2614         /* this is heinous but it can not be avoided for now.
       
  2615          ** this is the only known way to eliminate all decorations
       
  2616          ** for openlook, which btw, is a bug as ol theoretically
       
  2617          ** supports MWM_HINTS
       
  2618          */
       
  2619 #ifndef DO_FULL_DECOR
       
  2620         if (awt_wm_getRunningWM() == OPENLOOK_WM) {
       
  2621             XtSetArg(args[argc], XmNoverrideRedirect, True);
       
  2622             argc++;
       
  2623         }
       
  2624 #endif
       
  2625     }
       
  2626 
       
  2627     /* 4334958: Widget name is set to the Java class name */
       
  2628     shell_name =
       
  2629         (char *)JNU_GetStringPlatformChars(env, target_class_name, NULL);
       
  2630 
       
  2631     if (parent) {
       
  2632         pdata = (struct FrameData *)
       
  2633             (*env)->GetLongField(env, parent, mComponentPeerIDs.pData);
       
  2634     }
       
  2635 
       
  2636     /* Parenting tells us whether we wish to be transient or not */
       
  2637     if (pdata == NULL) {
       
  2638         if (!shell_name)
       
  2639             shell_name = "AWTapp";
       
  2640         shell_class =  topLevelShellWidgetClass;
       
  2641         parent_widget = awt_root_shell;
       
  2642     }
       
  2643     else {
       
  2644         if (!shell_name)
       
  2645             shell_name = "AWTdialog";
       
  2646         shell_class = transientShellWidgetClass;
       
  2647         parent_widget = pdata->winData.shell;
       
  2648         XtSetArg(args[argc], XmNtransient, True); argc++;
       
  2649         XtSetArg(args[argc], XmNtransientFor, parent_widget); argc++;
       
  2650 
       
  2651         /* Fix Forte Menu Bug. If Window name is "###overrideRedirect###",
       
  2652          * then set XmNoverrideRedirect to prevent Menus from getting focus.
       
  2653          * In JDK 1.2.2 we created Windows as xmMenuShellWidgetClass,
       
  2654          * so we did not need to do this. Swing DefaultPopupFactory's
       
  2655          * createHeavyWeightPopup sets Window name to "###overrideRedirect###".
       
  2656         */
       
  2657         /**
       
  2658          * Fix for 4476629. Allow Swing to create heavyweight popups which will
       
  2659          * not steal focus from Frame.
       
  2660          */
       
  2661         jname = (*env)->GetObjectField(env, target, componentIDs.name);
       
  2662         if (!JNU_IsNull(env, jname)) {
       
  2663           cname = (char *)JNU_GetStringPlatformChars(env, jname, NULL);
       
  2664         }
       
  2665         if ( (cname != NULL && strcmp(cname, "###overrideRedirect###") == 0)
       
  2666             || (!isFrameOrDialog(target, env)
       
  2667                 && !isFocusableWindowByPeer(env, this)
       
  2668                 )
       
  2669             )
       
  2670         {    /* mbron */
       
  2671             XtSetArg(args[argc], XmNoverrideRedirect, True);
       
  2672             argc++;
       
  2673         }
       
  2674         if (cname) {
       
  2675             JNU_ReleaseStringPlatformChars(env, jname, (const char *) cname);
       
  2676         }
       
  2677         (*env)->DeleteLocalRef(env, jname);
       
  2678     }
       
  2679     DASSERT(!(argc > MAX_ARGC));
       
  2680     wdata->winData.shell = XtCreatePopupShell(shell_name, shell_class,
       
  2681                                               parent_widget, args, argc);
       
  2682     if (shell_name) {
       
  2683         JNU_ReleaseStringPlatformChars(env, target_class_name, shell_name);
       
  2684     }
       
  2685 
       
  2686 #ifdef DEBUG
       
  2687     /* Participate in EditRes protocol to facilitate debugging */
       
  2688     XtAddEventHandler(wdata->winData.shell, (EventMask)0, True,
       
  2689                       _XEditResCheckMessages, NULL);
       
  2690 #endif
       
  2691 
       
  2692     setDeleteCallback(globalRef, wdata);
       
  2693 
       
  2694     /* Establish resizability.  For the case of not resizable, do not
       
  2695        yet set a fixed size here; we must wait until in the routine
       
  2696        sun_awt_motif_MWindowPeer_pReshape() after insets have been fixed.
       
  2697        This is because correction of the insets may affect shell size.
       
  2698        (See comments in shellEH() concerning correction of the insets.  */
       
  2699     /*
       
  2700      * Fix for BugTraq ID 4313607.
       
  2701      * Initial resizability will be set later in MWindowPeer_setResizable()
       
  2702      * called from init().
       
  2703      */
       
  2704     wdata->isResizable = True;
       
  2705     wdata->isFixedSizeSet = False;
       
  2706 
       
  2707     XtAddEventHandler(wdata->winData.shell,
       
  2708                       (StructureNotifyMask | PropertyChangeMask
       
  2709                        | VisibilityChangeMask),
       
  2710                       False, shellEH, globalRef);
       
  2711 
       
  2712     XtAddEventHandler(wdata->winData.shell,
       
  2713                       FocusChangeMask,
       
  2714                       False, shellFocusEH, globalRef);
       
  2715 
       
  2716 
       
  2717     /**
       
  2718      * Installing property change handler for DISPOSE property.
       
  2719      * This property will be changed when we need to dispose the whole
       
  2720      * top-level. The nature of PropertyNotify will guarantee that it is
       
  2721      * the latest event on the top-level so we can freely dispose it.
       
  2722      */
       
  2723     wdata->isDisposeScheduled = False;
       
  2724     if (_XA_JAVA_DISPOSE_PROPERTY_ATOM == 0) {
       
  2725         _XA_JAVA_DISPOSE_PROPERTY_ATOM = XInternAtom(awt_display, "_SUNW_JAVA_AWT_DISPOSE", False);
       
  2726     }
       
  2727     XtAddEventHandler(wdata->winData.shell, PropertyChangeMask, False,
       
  2728                       shellDisposeNotifyHandler, globalRef);
       
  2729 
       
  2730     /*
       
  2731      * Create "main" form.
       
  2732      */
       
  2733     argc = 0;
       
  2734     XtSetArg(args[argc], XmNmarginWidth, 0); argc++;
       
  2735     XtSetArg(args[argc], XmNmarginHeight, 0); argc++;
       
  2736     XtSetArg(args[argc], XmNhorizontalSpacing, 0); argc++;
       
  2737     XtSetArg(args[argc], XmNverticalSpacing, 0); argc++;
       
  2738     XtSetArg(args[argc], XmNresizePolicy, XmRESIZE_NONE); argc++;
       
  2739 
       
  2740     XtSetArg(args[argc], XmNbuttonFontList, getMotifFontList()); argc++;
       
  2741     XtSetArg(args[argc], XmNlabelFontList, getMotifFontList()); argc++;
       
  2742     XtSetArg(args[argc], XmNtextFontList, getMotifFontList()); argc++;
       
  2743 
       
  2744     DASSERT(!(argc > MAX_ARGC));
       
  2745     wdata->mainWindow = XmCreateForm(wdata->winData.shell, "main", args, argc);
       
  2746 
       
  2747     /* The widget returned by awt_canvas_create is a drawing area
       
  2748        (i.e., canvas) which is the child of another drawing area
       
  2749        parent widget.  The parent is the drawing area within the
       
  2750        form just created.  The child is an drawing area layer over
       
  2751        the entire frame window, including the form, any menu bar
       
  2752        and warning windows present, and also window manager stuff.
       
  2753        The top, bottom, left, and right fields in wdata maintain
       
  2754        the respective offsets between these two drawing areas.  */
       
  2755 
       
  2756     wdata->winData.comp.widget = awt_canvas_create((XtPointer)globalRef,
       
  2757                                                    wdata->mainWindow,
       
  2758                                                    "frame_",
       
  2759                                                    -1,
       
  2760                                                    -1,
       
  2761                                                    True,
       
  2762                                                    wdata,
       
  2763                                                    adata);
       
  2764     XtAddCallback(wdata->winData.comp.widget,
       
  2765                   XmNresizeCallback, outerCanvasResizeCB,
       
  2766                   globalRef);
       
  2767 
       
  2768     innerCanvasW = XtParent(wdata->winData.comp.widget);
       
  2769     XtVaSetValues(innerCanvasW,
       
  2770                   XmNleftAttachment, XmATTACH_FORM,
       
  2771                   XmNrightAttachment, XmATTACH_FORM,
       
  2772                   NULL);
       
  2773 
       
  2774     XtAddEventHandler(innerCanvasW, StructureNotifyMask, FALSE,
       
  2775                       innerCanvasEH, globalRef);
       
  2776 
       
  2777     wdata->focusProxy = createFocusProxy((XtPointer)globalRef,
       
  2778                                          wdata->mainWindow);
       
  2779 
       
  2780     /* No menu bar initially */
       
  2781     wdata->menuBar = NULL;
       
  2782     wdata->mbHeight = 0;
       
  2783 
       
  2784     /* If a warning window (string) is needed, establish it now.*/
       
  2785     warningString =
       
  2786         (*env)->GetObjectField(env, target, windowIDs.warningString);
       
  2787     if (!JNU_IsNull(env, warningString) ) {
       
  2788         char *wString;
       
  2789         /* Insert a warning window. It's height can't be set yet;
       
  2790            it will later be set in setMbAndWwHeightAndOffsets().*/
       
  2791         wString = (char *) JNU_GetStringPlatformChars(env, warningString, NULL);
       
  2792         wdata->warningWindow = awt_util_createWarningWindow(wdata->mainWindow, wString);
       
  2793         JNU_ReleaseStringPlatformChars(env, warningString, (const char *) wString);
       
  2794 
       
  2795         wdata->wwHeight = 0;
       
  2796         XtVaSetValues(wdata->warningWindow,
       
  2797                       XmNleftAttachment, XmATTACH_FORM,
       
  2798                       XmNrightAttachment, XmATTACH_FORM,
       
  2799                       NULL);
       
  2800 
       
  2801 #ifdef NETSCAPE
       
  2802         /* For NETSCAPE, warning window is at bottom of the form*/
       
  2803         XtVaSetValues(innerCanvasW,
       
  2804                       XmNtopAttachment, XmATTACH_FORM,
       
  2805                       NULL);
       
  2806         XtVaSetValues(wdata->warningWindow,
       
  2807                       XmNtopAttachment, XmATTACH_WIDGET,
       
  2808                       XmNtopWidget, innerCanvasW,
       
  2809                       XmNbottomAttachment, XmATTACH_FORM,
       
  2810                       NULL);
       
  2811 #else  /* NETSCAPE */
       
  2812         /* Otherwise (not NETSCAPE), warning is at top of form  */
       
  2813         XtVaSetValues(wdata->warningWindow,
       
  2814                       XmNtopAttachment, XmATTACH_FORM,
       
  2815                       NULL);
       
  2816         XtVaSetValues(innerCanvasW,
       
  2817                       XmNtopAttachment, XmATTACH_WIDGET,
       
  2818                       XmNtopWidget, wdata->warningWindow,
       
  2819                       XmNbottomAttachment, XmATTACH_FORM,
       
  2820                       NULL);
       
  2821 #endif /* NETSCAPE */
       
  2822 
       
  2823     } else {
       
  2824         /* No warning window present */
       
  2825         XtVaSetValues(innerCanvasW,
       
  2826                       XmNtopAttachment, XmATTACH_FORM,
       
  2827                       XmNbottomAttachment, XmATTACH_FORM,
       
  2828                       NULL);
       
  2829         wdata->warningWindow = NULL;
       
  2830         wdata->wwHeight = 0;
       
  2831     }
       
  2832 
       
  2833     awt_util_show(wdata->winData.comp.widget);
       
  2834 
       
  2835     AWT_FLUSH_UNLOCK();
       
  2836 
       
  2837     addTopLevel(wdata);
       
  2838 
       
  2839     /* Check whether this is an instance of InputMethodWindow or not */
       
  2840     if (inputMethodWindowClass == NULL) {
       
  2841         jclass localClass = (*env)->FindClass(env, "sun/awt/im/InputMethodWindow");
       
  2842         inputMethodWindowClass = (jclass)(*env)->NewGlobalRef(env, localClass);
       
  2843         (*env)->DeleteLocalRef(env, localClass);
       
  2844     }
       
  2845     if ((*env)->IsInstanceOf(env, target, inputMethodWindowClass)) {
       
  2846         wdata->isInputMethodWindow = True;
       
  2847         addInputMethodWindow(wdata);
       
  2848     }
       
  2849 } /* MWindowPeer_pCreate() */
       
  2850 
       
  2851 
       
  2852 /*
       
  2853  * Class:     sun_awt_motif_MWindowPeer
       
  2854  * Method:    pSetTitle
       
  2855  * Signature: (Ljava/lang/String;)V
       
  2856  */
       
  2857 JNIEXPORT void JNICALL
       
  2858 Java_sun_awt_motif_MWindowPeer_pSetTitle(JNIEnv *env, jobject this,
       
  2859     jstring title)
       
  2860 {
       
  2861     char *ctitle;
       
  2862     char *empty_string = " ";
       
  2863     struct FrameData *wdata;
       
  2864     XTextProperty text_prop;
       
  2865     char *c[1];
       
  2866     int32_t conv_result;
       
  2867 
       
  2868     AWT_LOCK();
       
  2869 
       
  2870     wdata = (struct FrameData *)
       
  2871         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  2872 
       
  2873     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  2874         JNU_ThrowNullPointerException(env, "null wdata or shell");
       
  2875         AWT_UNLOCK();
       
  2876         return;
       
  2877     }
       
  2878 
       
  2879     /* TODO: uwe: set _NET_WM_NAME property to utf-8 name */
       
  2880 
       
  2881     ctitle = (JNU_IsNull(env, title)) ? empty_string
       
  2882         : (char *) JNU_GetStringPlatformChars(env, title, NULL);
       
  2883 
       
  2884     if (strcmp(ctitle, "") == 0)
       
  2885         ctitle = empty_string;
       
  2886 
       
  2887     c[0] = ctitle;
       
  2888 
       
  2889     /* need to convert ctitle to CompoundText */
       
  2890     conv_result = XmbTextListToTextProperty(awt_display, c, 1,
       
  2891                                             XStdICCTextStyle,
       
  2892                                             &text_prop);
       
  2893 
       
  2894     /*
       
  2895      * XmbTextListToTextProperty returns value that is greater
       
  2896      * than Success if the supplied text is not fully convertible
       
  2897      * to specified encoding. In this case, the return value is
       
  2898      * the number of inconvertible characters. But convertibility
       
  2899      * is guaranteed for XCompoundTextStyle, so it will actually
       
  2900      * never be greater than Success. Errors handled below are
       
  2901      * represented by values that are lower than Success.
       
  2902      */
       
  2903     if (conv_result >= Success) {
       
  2904         XtVaSetValues(wdata->winData.shell,
       
  2905                   XmNtitle, text_prop.value,
       
  2906                   XmNtitleEncoding, text_prop.encoding,
       
  2907                   XmNiconName, text_prop.value,
       
  2908                   XmNiconNameEncoding, text_prop.encoding,
       
  2909                   XmNname, ctitle,
       
  2910                   NULL);
       
  2911     }
       
  2912 
       
  2913     if (ctitle != empty_string)
       
  2914         JNU_ReleaseStringPlatformChars(env, title, (const char *) ctitle);
       
  2915 
       
  2916     if (conv_result == XNoMemory) {
       
  2917         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
  2918         AWT_UNLOCK();
       
  2919         return;
       
  2920     }
       
  2921     if (conv_result == XLocaleNotSupported) {
       
  2922         JNU_ThrowInternalError(env, "Current locale is not supported");
       
  2923         AWT_UNLOCK();
       
  2924         return;
       
  2925     }
       
  2926 
       
  2927     XFree(text_prop.value);
       
  2928     AWT_FLUSH_UNLOCK();
       
  2929 }
       
  2930 
       
  2931 /*
       
  2932  * Class:     sun_awt_motif_MWindowPeer
       
  2933  * Method:    pToFront
       
  2934  * Signature: ()V
       
  2935  */
       
  2936 JNIEXPORT void JNICALL
       
  2937 Java_sun_awt_motif_MWindowPeer_pToFront(JNIEnv *env, jobject this)
       
  2938 {
       
  2939     struct FrameData *wdata;
       
  2940     jobject target;
       
  2941     Window shellWindow;
       
  2942     Boolean autoRequestFocus;
       
  2943     Boolean isModal = FALSE;
       
  2944 
       
  2945     AWT_LOCK();
       
  2946 
       
  2947     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  2948 
       
  2949     wdata = (struct FrameData *)
       
  2950         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  2951     if (wdata == NULL
       
  2952         || wdata->winData.comp.widget == NULL
       
  2953         || wdata->winData.shell == NULL
       
  2954         || wdata->mainWindow == NULL
       
  2955         || JNU_IsNull(env, target))
       
  2956     {
       
  2957         JNU_ThrowNullPointerException(env, "null widget/target data");
       
  2958         AWT_UNLOCK();
       
  2959         return;
       
  2960     }
       
  2961 
       
  2962     if ((shellWindow = XtWindow(wdata->winData.shell)) != None) {
       
  2963         XRaiseWindow(awt_display, shellWindow);
       
  2964 
       
  2965         autoRequestFocus = (*env)->GetBooleanField(env, target, windowIDs.isAutoRequestFocus);
       
  2966 
       
  2967         if (isDialog(target, env)) {
       
  2968             isModal = (*env)->GetBooleanField(env, target, dialogIDs.modal);
       
  2969         }
       
  2970 
       
  2971         // In contrast to XToolkit/WToolkit modal dialog can be unfocused.
       
  2972         // So we should also ask for modality in addition to 'autoRequestFocus'.
       
  2973         if (wdata->isFocusableWindow && (autoRequestFocus || isModal)) {
       
  2974             XSetInputFocus(awt_display, XtWindow(wdata->focusProxy), RevertToPointerRoot, CurrentTime);
       
  2975         }
       
  2976     }
       
  2977 
       
  2978    (*env)->DeleteLocalRef(env, target);
       
  2979 
       
  2980     AWT_UNLOCK();
       
  2981 }
       
  2982 
       
  2983 /*
       
  2984  * Class:     sun_awt_motif_MWindowPeer
       
  2985  * Method:    pShow
       
  2986  * Signature: ()V
       
  2987  */
       
  2988 JNIEXPORT void JNICALL
       
  2989 Java_sun_awt_motif_MWindowPeer_pShow(JNIEnv *env, jobject this)
       
  2990 {
       
  2991     Java_sun_awt_motif_MWindowPeer_pShowModal(env, this, JNI_FALSE);
       
  2992 }
       
  2993 
       
  2994 /*
       
  2995  * Class:     sun_awt_motif_MWindowPeer
       
  2996  * Method:    pShowModal
       
  2997  * Signature: (Z)V
       
  2998  */
       
  2999 JNIEXPORT void JNICALL
       
  3000 Java_sun_awt_motif_MWindowPeer_pShowModal(JNIEnv *env, jobject this,
       
  3001     jboolean isModal)
       
  3002 {
       
  3003     struct FrameData *wdata;
       
  3004     Boolean iconic;
       
  3005     jobject target;
       
  3006     Boolean locationByPlatform;
       
  3007 
       
  3008     AWT_LOCK();
       
  3009 
       
  3010     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  3011 
       
  3012     wdata = (struct FrameData *)
       
  3013         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3014     if (wdata == NULL
       
  3015         || wdata->winData.comp.widget == NULL
       
  3016         || wdata->winData.shell == NULL
       
  3017         || wdata->mainWindow == NULL
       
  3018         || (wdata->winData.flags & W_IS_EMBEDDED)
       
  3019         || JNU_IsNull(env, target))
       
  3020     {
       
  3021         JNU_ThrowNullPointerException(env, "null widget/target data");
       
  3022         AWT_UNLOCK();
       
  3023         return;
       
  3024     }
       
  3025 
       
  3026     DTRACE_PRINTLN2("TL: pShowModal(modal = %s) state = 0x%X",
       
  3027                     isModal ? "true" : "false",
       
  3028                     wdata->state);
       
  3029 
       
  3030     wdata->isModal = isModal;
       
  3031 
       
  3032     /*
       
  3033      * A workaround for bug 4062589 that is really a motif problem
       
  3034      * (see bug 4064803).  Before popping up a modal dialog, if a
       
  3035      * pulldown menu has the input focus (i.e. user has pulled the
       
  3036      * menu down), we send a fake click event and make sure the click
       
  3037      * event is processed.  With this simulation of user clicking, X
       
  3038      * server will not get confused about the modality and a
       
  3039      * subsequent click on the popup modal dialog will not cause
       
  3040      * system lockup.
       
  3041      */
       
  3042     if (wdata->isModal && awt_util_focusIsOnMenu(awt_display)
       
  3043         && awt_util_sendButtonClick(awt_display, InputFocus))
       
  3044     {
       
  3045         for (;;) {
       
  3046             XEvent ev;
       
  3047             XtAppPeekEvent(awt_appContext, &ev);
       
  3048             if ((ev.type == ButtonRelease)
       
  3049                 && (*(XButtonEvent *)&ev).send_event)
       
  3050             {
       
  3051                 XtAppProcessEvent(awt_appContext, XtIMAll);
       
  3052                 break;
       
  3053             } else {
       
  3054                 XtAppProcessEvent(awt_appContext, XtIMAll);
       
  3055             }
       
  3056         }
       
  3057     }
       
  3058     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  3059 
       
  3060     // 4488209: kdm@sparc.spb.su
       
  3061     // wdata->isShowing is True when toFront calls pShow.
       
  3062     // We do not need to do some things if wdata->isShowing is True.
       
  3063     if (!wdata->isShowing) {
       
  3064         XtVaSetValues(wdata->winData.comp.widget,
       
  3065                       XmNx, -(wdata->left),
       
  3066                       XmNy, -(wdata->top),
       
  3067                       NULL);
       
  3068 
       
  3069         /* But see below! */
       
  3070         iconic = (wdata->state & java_awt_Frame_ICONIFIED) ? True : False;
       
  3071         XtVaSetValues(wdata->winData.shell,
       
  3072                       XmNinitialState, iconic ? IconicState : NormalState,
       
  3073                       NULL);
       
  3074 
       
  3075         if (wdata->menuBar != NULL) {
       
  3076             awt_util_show(wdata->menuBar);
       
  3077         }
       
  3078         XtManageChild(wdata->mainWindow);
       
  3079         XtRealizeWidget(wdata->winData.shell); /* but not map it yet */
       
  3080 
       
  3081 /*         fprintf(stderr, "*** proxy window %x\n", XtWindow(wdata->focusProxy)); */
       
  3082         XStoreName(awt_display, XtWindow(wdata->focusProxy), "FocusProxy");
       
  3083         /*
       
  3084          * Maximization and other stuff that requires a live Window to set
       
  3085          * properties on to communicate with WM.
       
  3086          */
       
  3087         awt_wm_setExtendedState(wdata, wdata->state);
       
  3088         awt_wm_setShellDecor(wdata, wdata->isResizable);
       
  3089 
       
  3090         if (wdata->isModal) {
       
  3091             removePopupMenus();
       
  3092 #ifndef NOMODALFIX
       
  3093             /*
       
  3094              * Fix for 4078176 Modal dialogs don't act modal
       
  3095              * if addNotify() is called before setModal(true).
       
  3096              * Moved from Java_sun_awt_motif_MDialogPeer_create.
       
  3097              */
       
  3098             if (!wdata->callbacksAdded) {
       
  3099                 XtAddCallback(wdata->winData.shell,
       
  3100                               XtNpopupCallback, awt_shellPoppedUp,
       
  3101                               NULL);
       
  3102                 XtAddCallback(wdata->winData.shell,
       
  3103                               XtNpopdownCallback, awt_shellPoppedDown,
       
  3104                               NULL);
       
  3105                 wdata->callbacksAdded = True;
       
  3106             }
       
  3107 #endif /* !NOMODALFIX */
       
  3108             /*
       
  3109              * Set modality on the Shell, not the BB.  The BB expects that
       
  3110              * its parent is an xmDialogShell, which as the result of
       
  3111              * coalescing is now a transientShell...  This has resulted in
       
  3112              * a warning message generated under fvwm.  The shells are
       
  3113              * virtually identical and a review of Motif src suggests that
       
  3114              * setting dialog style on BB is a convenience not functional
       
  3115              * for BB so set Modality on shell, not the BB(form) widget.
       
  3116              */
       
  3117             XtVaSetValues(wdata->winData.shell,
       
  3118                           XmNmwmInputMode, MWM_INPUT_FULL_APPLICATION_MODAL,
       
  3119                           NULL);
       
  3120             XtManageChild(wdata->winData.comp.widget);
       
  3121         }
       
  3122         else {                  /* not modal */
       
  3123             XtVaSetValues(wdata->winData.shell,
       
  3124                           XmNmwmInputMode, MWM_INPUT_MODELESS, NULL);
       
  3125             XtManageChild(wdata->winData.comp.widget);
       
  3126             XtSetMappedWhenManaged(wdata->winData.shell, True);
       
  3127         }
       
  3128         if (wdata->isResizable) {
       
  3129             /* REMINDER: uwe: will need to revisit for setExtendedStateBounds */
       
  3130             awt_wm_removeSizeHints(wdata->winData.shell, PMinSize|PMaxSize);
       
  3131         }
       
  3132         locationByPlatform =
       
  3133             (*env)->GetBooleanField(env, target, windowIDs.locationByPlatform);
       
  3134         if (locationByPlatform) {
       
  3135             awt_wm_removeSizeHints(wdata->winData.shell, USPosition|PPosition);
       
  3136         }
       
  3137     }
       
  3138 
       
  3139     /*
       
  3140      * 4261047: always pop up with XtGrabNone.  Motif notices the
       
  3141      * modal input mode and perform the grab for us, doing its
       
  3142      * internal book-keeping as well.
       
  3143      */
       
  3144     XtPopup(wdata->winData.shell, XtGrabNone);
       
  3145     wdata->isShowing = True;
       
  3146 
       
  3147     wdata->initialFocus = (*env)->GetBooleanField(env, target, windowIDs.isAutoRequestFocus);
       
  3148 
       
  3149     if (wdata->isFocusableWindow) {
       
  3150         if (wdata->initialFocus || wdata->isModal) {
       
  3151             focusOnMapNotify = True;
       
  3152         } else {
       
  3153             XtVaSetValues(wdata->winData.shell, XmNinput, False, NULL);
       
  3154         }
       
  3155     }
       
  3156 
       
  3157     (*env)->DeleteLocalRef(env, target);
       
  3158 
       
  3159     AWT_FLUSH_UNLOCK();
       
  3160 }
       
  3161 
       
  3162 /*
       
  3163  * Class:     sun_awt_motif_MWindowPeer
       
  3164  * Method:    getState
       
  3165  * Signature: ()I
       
  3166  */
       
  3167 JNIEXPORT jint JNICALL
       
  3168 Java_sun_awt_motif_MWindowPeer_getState(JNIEnv *env, jobject this)
       
  3169 {
       
  3170     struct FrameData *wdata;
       
  3171     jint state;
       
  3172 
       
  3173     AWT_LOCK();
       
  3174 
       
  3175     wdata = (struct FrameData *)
       
  3176         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3177     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  3178         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3179         AWT_UNLOCK();
       
  3180         return java_awt_Frame_NORMAL;
       
  3181     }
       
  3182 
       
  3183     state = wdata->state;
       
  3184 
       
  3185     AWT_FLUSH_UNLOCK();
       
  3186     return state;
       
  3187 }
       
  3188 
       
  3189 /*
       
  3190  * Class:     sun_awt_motif_MWindowPeer
       
  3191  * Method:    setState
       
  3192  * Signature: (I)V
       
  3193  */
       
  3194 JNIEXPORT void JNICALL
       
  3195 Java_sun_awt_motif_MWindowPeer_setState(JNIEnv *env, jobject this,
       
  3196     jint state)
       
  3197 {
       
  3198     struct FrameData *wdata;
       
  3199     Widget shell;
       
  3200     Window shell_win;
       
  3201     jint changed;
       
  3202     Boolean changeIconic, iconic;
       
  3203 
       
  3204     AWT_LOCK();
       
  3205     wdata = (struct FrameData *)
       
  3206         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3207     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  3208         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3209         AWT_UNLOCK();
       
  3210         return;
       
  3211     }
       
  3212 
       
  3213     shell = wdata->winData.shell;
       
  3214     shell_win = XtWindow(shell);
       
  3215 
       
  3216     DTRACE_PRINTLN4("TL: setState(0x%x/0x%x, 0x%X -> 0x%X)",
       
  3217                     shell, shell_win,
       
  3218                     wdata->state, state);
       
  3219 
       
  3220     if (!wdata->isShowing) {
       
  3221         /*
       
  3222          * Not showing, so just record requested state; pShow will set
       
  3223          * initial state hints/properties appropriately before poping
       
  3224          * us up again.
       
  3225          */
       
  3226         DTRACE_PRINTLN("TL:     NOT showing (just record the new state)");
       
  3227         wdata->state = state;
       
  3228         AWT_UNLOCK();
       
  3229         return;
       
  3230     }
       
  3231 
       
  3232     /*
       
  3233      * Request the state transition from WM here and do java upcalls
       
  3234      * in shell event handler when WM actually changes our state.
       
  3235      */
       
  3236     changed = wdata->state ^ state;
       
  3237 
       
  3238     changeIconic = changed & java_awt_Frame_ICONIFIED;
       
  3239     iconic = (state & java_awt_Frame_ICONIFIED) ? True : False;
       
  3240 
       
  3241     if (changeIconic && iconic) {
       
  3242         DTRACE_PRINTLN("TL:     set iconic = True");
       
  3243         XIconifyWindow(XtDisplay(shell), shell_win,
       
  3244                        XScreenNumberOfScreen(XtScreen(shell)));
       
  3245     }
       
  3246 
       
  3247     /*
       
  3248      * If a change in both iconic and extended states requested, do
       
  3249      * changes to extended state when we are in iconic state.
       
  3250      */
       
  3251     if ((changed & ~java_awt_Frame_ICONIFIED) != 0) {
       
  3252         awt_wm_setExtendedState(wdata, state);
       
  3253     }
       
  3254 
       
  3255     if (changeIconic && !iconic) {
       
  3256         DTRACE_PRINTLN("TL:     set iconic = False");
       
  3257         XMapWindow(XtDisplay(shell), shell_win);
       
  3258     }
       
  3259 
       
  3260     AWT_FLUSH_UNLOCK();
       
  3261 }
       
  3262 
       
  3263 
       
  3264 /*
       
  3265  * Class:     sun_awt_motif_MWindowPeer
       
  3266  * Method:    pHide
       
  3267  * Signature: ()V
       
  3268  */
       
  3269 JNIEXPORT void JNICALL
       
  3270 Java_sun_awt_motif_MWindowPeer_pHide(JNIEnv *env, jobject this)
       
  3271 {
       
  3272     struct FrameData *wdata;
       
  3273 
       
  3274     AWT_LOCK();
       
  3275     wdata = (struct FrameData *)
       
  3276         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3277 
       
  3278     if (wdata == NULL
       
  3279         || wdata->winData.comp.widget == NULL
       
  3280         || wdata->winData.shell == NULL)
       
  3281     {
       
  3282         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3283         AWT_UNLOCK();
       
  3284         return;
       
  3285     }
       
  3286 
       
  3287     /**
       
  3288      * Disable proxy mechanism when Window's shell is being hidden
       
  3289      */
       
  3290     clearFocusPath(wdata->winData.shell);
       
  3291 
       
  3292     wdata->isShowing = False;   /* ignore window state events */
       
  3293 
       
  3294     if (XtIsRealized(wdata->winData.shell)) {
       
  3295         /* XXX: uwe: this is bogus */
       
  3296         /*
       
  3297          * Make sure we withdraw a window in an unmaximized state, or
       
  3298          * we'll lose out normal bounds (pShow will take care of
       
  3299          * hinting maximization, so when the window is shown again it
       
  3300          * will be correctly shown maximized).
       
  3301          */
       
  3302         if (wdata->state & java_awt_Frame_MAXIMIZED_BOTH) {
       
  3303             awt_wm_setExtendedState(wdata,
       
  3304                 wdata->state & ~java_awt_Frame_MAXIMIZED_BOTH);
       
  3305         }
       
  3306         XtUnmanageChild(wdata->winData.comp.widget);
       
  3307         XtPopdown(wdata->winData.shell);
       
  3308     }
       
  3309 
       
  3310     AWT_FLUSH_UNLOCK();
       
  3311 }
       
  3312 
       
  3313 
       
  3314 /* sun_awt_motif_MWindowPeer_pReshape() is native (X/Motif) routine that
       
  3315    is called to effect a reposition and / or resize of the target frame.
       
  3316    The parameters x,y,w,h specify target's x, y position, width, height.*/
       
  3317 
       
  3318 /*
       
  3319  * This functionality is invoked from both java and native code, and
       
  3320  * we only want to lock when invoking it from java, so wrap the native
       
  3321  * method version with the locking.
       
  3322  */
       
  3323 
       
  3324 /*
       
  3325  * Class:     sun_awt_motif_MWindowPeer
       
  3326  * Method:    pReshape
       
  3327  * Signature: (IIII)V
       
  3328  */
       
  3329 JNIEXPORT void JNICALL
       
  3330 Java_sun_awt_motif_MWindowPeer_pReshape(JNIEnv *env, jobject this,
       
  3331     jint x, jint y, jint w, jint h)
       
  3332 {
       
  3333     struct FrameData    *wdata;
       
  3334 
       
  3335     AWT_LOCK();
       
  3336 
       
  3337     wdata = (struct FrameData *)
       
  3338         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3339 
       
  3340     if (wdata == NULL ||
       
  3341         wdata->winData.comp.widget == NULL ||
       
  3342         wdata->winData.shell == NULL) {
       
  3343         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3344         AWT_UNLOCK();
       
  3345         return;
       
  3346     }
       
  3347 
       
  3348     // See if our new location is on a new screen
       
  3349     if (wdata->reparented) {
       
  3350         checkNewXineramaScreen(env, this, wdata, x, y, w, h);
       
  3351     }
       
  3352 
       
  3353     /**
       
  3354      * Fix for 4652685.
       
  3355      * Avoid setting position for embedded frames, since this conflicts with the
       
  3356      * fix for 4419207. We assume that the embedded frame never changes its
       
  3357      * position relative to the parent.
       
  3358      */
       
  3359     if (wdata->winData.flags & W_IS_EMBEDDED) {
       
  3360         x = 0;
       
  3361         y = 0;
       
  3362     }
       
  3363 
       
  3364     reshape(env, this, wdata, x, y, w, h, True);
       
  3365 
       
  3366     AWT_FLUSH_UNLOCK();
       
  3367 }
       
  3368 
       
  3369 /*
       
  3370  * Class:     sun_awt_motif_MEmbeddedFramePeer
       
  3371  * Method:    pReshapePrivate
       
  3372  * Signature: (IIII)V
       
  3373  */
       
  3374 JNIEXPORT void JNICALL
       
  3375 Java_sun_awt_motif_MEmbeddedFramePeer_pReshapePrivate(JNIEnv *env, jobject this,
       
  3376     jint x, jint y, jint w, jint h)
       
  3377 {
       
  3378     struct FrameData    *wdata;
       
  3379 
       
  3380     AWT_LOCK();
       
  3381 
       
  3382     wdata = (struct FrameData *)
       
  3383         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3384 
       
  3385     if (wdata == NULL ||
       
  3386         wdata->winData.comp.widget == NULL ||
       
  3387         wdata->winData.shell == NULL) {
       
  3388         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3389         AWT_UNLOCK();
       
  3390         return;
       
  3391     }
       
  3392 
       
  3393     reshape(env, this, wdata, x, y, w, h, True);
       
  3394 
       
  3395     AWT_FLUSH_UNLOCK();
       
  3396 }
       
  3397 
       
  3398 static void
       
  3399 reshape(JNIEnv *env, jobject this, struct FrameData *wdata,
       
  3400         jint x, jint y, jint w, jint h, Boolean setXY)
       
  3401 {
       
  3402     int32_t     topAdjust,      /* top adjustment of offset     */
       
  3403                 bottomAdjust;   /* bottom adjustment of offset  */
       
  3404     int32_t     width,          /* of X/Motif shell and form    */
       
  3405                 height;         /* of X/Motif shell and form    */
       
  3406     int32_t     w1, h1;
       
  3407     enum wmgr_t wm;             /* window manager */
       
  3408     XWindowAttributes winAttr;
       
  3409 
       
  3410     DTRACE_PRINTLN7("TL: reshape(0x%x/0x%x,\n"/**/
       
  3411                     "TL:         x = %d, y = %d, w = %d, h = %d, %s)",
       
  3412                     wdata->winData.shell, XtWindow(wdata->winData.shell),
       
  3413                     x, y, w, h,
       
  3414                     setXY ? "setXY" : "false");
       
  3415 
       
  3416     wm = awt_wm_getRunningWM();
       
  3417 
       
  3418     /* Make adjustments in case of a dynamically added/removed menu bar */
       
  3419     awtJNI_setMbAndWwHeightAndOffsets(env, this, wdata);
       
  3420 
       
  3421 #ifdef _pauly_debug
       
  3422     fprintf(stdout,"    reshape. offsets - top: %d, bottom: %d, left: %d, right: %d\n",
       
  3423             wdata->top, wdata->bottom, wdata->left, wdata->right);
       
  3424     fflush(stdout);
       
  3425 #endif /* _pauly_debug */
       
  3426 
       
  3427     /* The abstract java (target) position coordinates (x,y)
       
  3428        are for the bordered window.  Eventually(!), the Motif
       
  3429        (shell) coordinates (XmNx, XmNy) will exclude borders.
       
  3430        (This is true only AFTER shell is massaged by the WM.)   */
       
  3431 
       
  3432     /* The abstract java (target) width and height includes any WM
       
  3433        borders. But the Motif width and height excludes WM borders.
       
  3434        The wdata top and bottom fields may include space for menu bar,
       
  3435        warning window, etc. We must adjust by these values for shell.   */
       
  3436     topAdjust = 0;
       
  3437     bottomAdjust = 0;
       
  3438     /* Surprise - do not(!) check for nonNull MenuBar because that can
       
  3439        occur separately (in ...pSetMenubar()) from calculation of the
       
  3440        menu bar height and offsets (in setMbAndWwHeightAndOffsets()).
       
  3441        In any event, the offsets and wdata mbHeight field should jive.  */
       
  3442     topAdjust += wdata->mbHeight;
       
  3443     if  (wdata->warningWindow != NULL) {
       
  3444 #ifdef NETSCAPE
       
  3445         bottomAdjust += wdata->wwHeight;
       
  3446 #else /* NETSCAPE */
       
  3447         topAdjust += wdata->wwHeight;
       
  3448 #endif /* NETSCAPE */
       
  3449     }
       
  3450     if (wdata->hasTextComponentNative) {
       
  3451         bottomAdjust +=  wdata->imHeight;
       
  3452     }
       
  3453 #ifdef _pauly_debug
       
  3454     fprintf(stdout,"    reshape. adjustments - top: %d, bottom: %d\n", topAdjust, bottomAdjust);
       
  3455     fflush(stdout);
       
  3456 #endif /* _pauly_debug */
       
  3457 
       
  3458     width  = w - (wdata->left + wdata->right);
       
  3459     height = h - (wdata->top + wdata->bottom) + (topAdjust + bottomAdjust);
       
  3460 
       
  3461     /*
       
  3462      * Shell size.
       
  3463      * 4033151.  If nonpositive size specified (e.g., if no size
       
  3464      * given), establish minimum allowable size.  Note: Motif shell
       
  3465      * can not be sized 0.
       
  3466      */
       
  3467     w1 = (width  > 0) ? width  : 1;
       
  3468     h1 = (height > 0) ? height : 1;
       
  3469 
       
  3470     if (awt_wm_configureGravityBuggy() /* WM ignores window gravity */
       
  3471         && wdata->reparented && wdata->isShowing)
       
  3472     {
       
  3473         /*
       
  3474          * Buggy WM places client window at (x,y) ignoring the window
       
  3475          * gravity.  All our windows are NorthWestGravity, so adjust
       
  3476          * (x,y) by insets appropriately.
       
  3477          */
       
  3478         x += wdata->left;
       
  3479         y += wdata->top;
       
  3480         DTRACE_PRINTLN2("TL: work around WM gravity bug: x += %d, y += %d",
       
  3481                         wdata->left, wdata->top);
       
  3482     }
       
  3483 
       
  3484     if (wdata->imRemove) {
       
  3485         XtVaSetValues(XtParent(wdata->winData.comp.widget),
       
  3486                       XmNheight, (((h - (wdata->top + wdata->bottom)) > 0) ?
       
  3487                                   (h - (wdata->top + wdata->bottom)) : 1),
       
  3488                       NULL);
       
  3489         wdata->imRemove = False;
       
  3490     }
       
  3491 
       
  3492 #if 0 /* XXX: this screws insets calculation under KDE2 in the case of
       
  3493          negative x, y */
       
  3494     /*
       
  3495      * Without these checks, kwm places windows slightly off the screen,
       
  3496      * when there is a window underneath at (0,0) and empty space below,
       
  3497      * but not to the right.
       
  3498      */
       
  3499     if (x < 0) x = 0;
       
  3500     if (y < 0) y = 0;
       
  3501 #endif
       
  3502     if ((wdata->winData.flags & W_IS_EMBEDDED) == 0) {
       
  3503         if ((wm == MOTIF_WM) || (wm == CDE_WM)) {
       
  3504             /*
       
  3505              * By default MWM has "usePPosition: nonzero" and so ignores
       
  3506              * windows with PPosition (0,0).  Work around (should we???).
       
  3507              */
       
  3508             if ((x == 0) && (y == 0)) {
       
  3509                 x = y = 1;
       
  3510             }
       
  3511         }
       
  3512     }
       
  3513 
       
  3514     if ( wdata->decor == AWT_NO_DECOR ) {
       
  3515         if (setXY)
       
  3516             XtConfigureWidget(wdata->winData.shell, x, y, w1, h1, 0 );
       
  3517         else
       
  3518             XtResizeWidget(wdata->winData.shell, w1, h1, 0);
       
  3519     }
       
  3520     else {
       
  3521         /*
       
  3522          * 5006248, workaround for OpenLook WM.
       
  3523          * Thread gets stuck at XtVaSetValues call awaiting for first
       
  3524          * ConfigureNotify to come. For OpenLook it looks like a showstopper.
       
  3525          * We put dummy ConfigureNotify to satisfy the requirements.
       
  3526          */
       
  3527         if (awt_wm_getRunningWM() == OPENLOOK_WM) {
       
  3528             XEvent xev;
       
  3529             xev.xconfigure.type = ConfigureNotify;
       
  3530             xev.xconfigure.display = awt_display;
       
  3531             xev.xconfigure.window = XtWindow(wdata->winData.shell);
       
  3532             xev.xconfigure.event = xev.xconfigure.window;
       
  3533             xev.xconfigure.x = x;
       
  3534             xev.xconfigure.y = y;
       
  3535             xev.xconfigure.height = h1;
       
  3536             xev.xconfigure.width = w1;
       
  3537             xev.xconfigure.serial = NextRequest(awt_display) + 1; // see isMine() Xt inner function code.
       
  3538 
       
  3539             XPutBackEvent(awt_display, &xev);
       
  3540         }
       
  3541 
       
  3542         if (wdata->isResizable) {
       
  3543             XtVaSetValues(wdata->winData.shell,
       
  3544                           XmNwidth, w1,
       
  3545                           XmNheight, h1,
       
  3546                           NULL);
       
  3547         }
       
  3548         else {
       
  3549             /*
       
  3550              * Fix for BugTraq ID 4313607 - call awt_wm_setShellNotResizable
       
  3551              * regardless of wdata->isFixedSizeSet and wdata->reparented values.
       
  3552              */
       
  3553             DTRACE_PRINTLN("TL: set fixed size from reshape");
       
  3554             awt_wm_setShellNotResizable(wdata, w1, h1, True);
       
  3555             if (wdata->reparented && (w1 > 0) && (h1 > 0)) {
       
  3556                 wdata->isFixedSizeSet = True;
       
  3557             }
       
  3558         }
       
  3559         if (setXY)
       
  3560             XtVaSetValues(wdata->winData.shell,
       
  3561                           XmNx, x,
       
  3562                           XmNy, y,
       
  3563                           NULL);
       
  3564     }
       
  3565     /* inner/parent drawing area (parent is form) */
       
  3566     h1 = h - (wdata->top + wdata->bottom);
       
  3567     h1 = ( h1 > 0 ) ? h1 : 1;
       
  3568 #if 0
       
  3569     XtConfigureWidget(XtParent(wdata->winData.comp.widget),
       
  3570                       0, topAdjust, w1, h1, 0 );
       
  3571 #else
       
  3572     XtVaSetValues(XtParent(wdata->winData.comp.widget),
       
  3573                   XmNx, 0,
       
  3574                   XmNy, topAdjust,
       
  3575                   XmNwidth, w1,
       
  3576                   XmNheight, h1,
       
  3577                   NULL);
       
  3578 #endif
       
  3579 
       
  3580 #ifdef _pauly_debug
       
  3581         fprintf(stdout,"    reshape. setting inner canvas to: %d,%d,%d,%d\n",
       
  3582         0, topAdjust, w1, h1 );
       
  3583         fflush(stdout);
       
  3584 #endif /* _pauly_debug */
       
  3585 
       
  3586     wdata->menuBarReset = False;
       
  3587 
       
  3588     /* DTRACE_PRINTLN("TL: reshape -> returning"); */
       
  3589     return;
       
  3590 }
       
  3591 
       
  3592 /*
       
  3593  * Class:     sun_awt_motif_MEmbeddedFramePeer
       
  3594  * Method:    getBoundsPrivate
       
  3595  * Signature: ()Ljava/awt/Rectangle
       
  3596  */
       
  3597 JNIEXPORT jobject JNICALL Java_sun_awt_motif_MEmbeddedFramePeer_getBoundsPrivate
       
  3598   (JNIEnv * env, jobject this)
       
  3599 {
       
  3600     jobject bounds = NULL;
       
  3601     struct FrameData *cdata;
       
  3602     XWindowAttributes attr;
       
  3603 
       
  3604     AWT_LOCK();
       
  3605 
       
  3606     cdata = (struct FrameData *)
       
  3607         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3608     if (cdata == NULL || cdata->mainWindow == NULL) {
       
  3609         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3610         AWT_UNLOCK();
       
  3611         return NULL;
       
  3612     }
       
  3613     if (!XtIsRealized(cdata->mainWindow) || !XtIsRealized(cdata->winData.shell)) {
       
  3614         JNU_ThrowInternalError(env, "widget not visible on screen");
       
  3615         AWT_UNLOCK();
       
  3616         return NULL;
       
  3617     }
       
  3618 
       
  3619     memset(&attr, 0, sizeof(XWindowAttributes));
       
  3620     XGetWindowAttributes(awt_display, XtWindow(cdata->winData.shell), &attr);
       
  3621 
       
  3622     bounds = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V",
       
  3623                                 (jint)attr.x, (jint)attr.y, (jint)attr.width, (jint)attr.height);
       
  3624     if (((*env)->ExceptionOccurred(env)) || JNU_IsNull(env, bounds)) {
       
  3625         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3626         AWT_UNLOCK();
       
  3627         return NULL;
       
  3628     }
       
  3629 
       
  3630     AWT_UNLOCK();
       
  3631 
       
  3632     return bounds;
       
  3633 }
       
  3634 
       
  3635 /*
       
  3636  * Class:     sun_awt_motif_MWindowPeer
       
  3637  * Method:    pDispose
       
  3638  * Signature: ()V
       
  3639  */
       
  3640 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_pDispose
       
  3641 (JNIEnv *env, jobject this)
       
  3642 {
       
  3643     struct FrameData *wdata;
       
  3644 
       
  3645     AWT_LOCK();
       
  3646     wdata = (struct FrameData *)
       
  3647         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3648     if (wdata == NULL || wdata->mainWindow == NULL || wdata->winData.shell == NULL) {
       
  3649         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3650         AWT_UNLOCK();
       
  3651         return;
       
  3652     }
       
  3653     if (wdata->winData.flags & W_IS_EMBEDDED) {
       
  3654         awt_util_delEmbeddedFrame(wdata->winData.shell);
       
  3655         deinstall_xembed(wdata);
       
  3656     }
       
  3657     scheduleDispose(env, this);
       
  3658 
       
  3659     AWT_FLUSH_UNLOCK();
       
  3660 }
       
  3661 
       
  3662 /*
       
  3663  * Class:     sun_awt_motif_MFramePeer
       
  3664  * Method:    pGetIconSize
       
  3665  * Signature: (II)Z
       
  3666  */
       
  3667 JNIEXPORT jboolean JNICALL Java_sun_awt_motif_MFramePeer_pGetIconSize
       
  3668 (JNIEnv *env, jobject this, jint widthHint, jint heightHint)
       
  3669 {
       
  3670     struct FrameData *wdata;
       
  3671     uint32_t width, height, border_width, depth;
       
  3672     Window win;
       
  3673     int32_t x, y;
       
  3674     uint32_t mask;
       
  3675     XSetWindowAttributes attrs;
       
  3676     uint32_t saveWidth = 0;
       
  3677     uint32_t saveHeight = 0;
       
  3678     uint32_t dist = 0xffffffff;
       
  3679     int32_t diff = 0;
       
  3680     int32_t closestWidth;
       
  3681     int32_t closestHeight;
       
  3682     int32_t newDist;
       
  3683     int32_t found = 0;
       
  3684     AwtGraphicsConfigDataPtr adata;
       
  3685 
       
  3686     AWT_LOCK();
       
  3687     wdata = (struct FrameData *)
       
  3688         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3689     if (wdata == NULL) {
       
  3690         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3691         AWT_UNLOCK();
       
  3692         return FALSE;
       
  3693     }
       
  3694     XtVaGetValues(wdata->winData.shell,
       
  3695                   XmNiconWindow, &win,
       
  3696                   NULL);
       
  3697     if (!win) {
       
  3698         int32_t count;
       
  3699         int32_t i;
       
  3700         XIconSize *sizeList;
       
  3701 
       
  3702         adata = getGraphicsConfigFromComponentPeer(env, this);
       
  3703 
       
  3704         if (!XGetIconSizes(awt_display,
       
  3705                            RootWindow(awt_display, adata->awt_visInfo.screen),
       
  3706                            &sizeList, &count)) {
       
  3707             /* No icon sizes so can't set it -- Should we throw an exception?*/
       
  3708             /* [jk] I don't think so: simply fall back to 16x16 */
       
  3709             saveWidth = saveHeight = 16;
       
  3710             goto top;
       
  3711         }
       
  3712         for (i=0; i < count; i++) {
       
  3713             if (widthHint >= sizeList[i].min_width &&
       
  3714                 widthHint <= sizeList[i].max_width &&
       
  3715                 heightHint >= sizeList[i].min_height &&
       
  3716                 heightHint <= sizeList[i].max_height) {
       
  3717                 found = 1;
       
  3718                 if ((((widthHint-sizeList[i].min_width)
       
  3719                       % sizeList[i].width_inc) == 0) &&
       
  3720                     (((heightHint-sizeList[i].min_height)
       
  3721                       % sizeList[i].height_inc) ==0)) {
       
  3722                     /* Found an exact match */
       
  3723                     saveWidth = widthHint;
       
  3724                     saveHeight = heightHint;
       
  3725                     dist = 0;
       
  3726                     break;
       
  3727                 }
       
  3728                 diff = widthHint - sizeList[i].min_width;
       
  3729                 if (diff == 0) {
       
  3730                     closestWidth = widthHint;
       
  3731                 } else {
       
  3732                     diff = diff%sizeList[i].width_inc;
       
  3733                     closestWidth = widthHint - diff;
       
  3734                 }
       
  3735                 diff = heightHint - sizeList[i].min_height;
       
  3736                 if (diff == 0) {
       
  3737                     closestHeight = heightHint;
       
  3738                 } else {
       
  3739                     diff = diff%sizeList[i].height_inc;
       
  3740                     closestHeight = heightHint - diff;
       
  3741                 }
       
  3742                 newDist = closestWidth*closestWidth +
       
  3743                     closestHeight*closestHeight;
       
  3744                 if (dist > newDist) {
       
  3745                     saveWidth = closestWidth;
       
  3746                     saveHeight = closestHeight;
       
  3747                     dist = newDist;
       
  3748                 }
       
  3749             }
       
  3750         }
       
  3751 
       
  3752         if (!found) {
       
  3753 #if 1
       
  3754             /* [sbb] this code should work better than the original Solaris
       
  3755                code */
       
  3756             if (widthHint  >= sizeList[0].max_width ||
       
  3757                 heightHint >= sizeList[0].max_height) {
       
  3758               /* determine which way to scale */
       
  3759               int32_t wdiff = widthHint - sizeList[0].max_width;
       
  3760               int32_t hdiff = heightHint - sizeList[0].max_height;
       
  3761               if (wdiff >= hdiff) { /* need to scale width more  */
       
  3762                 saveWidth = sizeList[0].max_width;
       
  3763                 saveHeight = (int32_t)(((double)sizeList[0].max_width/widthHint) *
       
  3764                                    heightHint);
       
  3765               } else {
       
  3766                 saveWidth = (int32_t)(((double)sizeList[0].max_height/heightHint) *
       
  3767                                   widthHint);
       
  3768                 saveHeight = sizeList[0].max_height;
       
  3769               }
       
  3770             } else if (widthHint  < sizeList[0].min_width ||
       
  3771                        heightHint < sizeList[0].min_height) {
       
  3772                 saveWidth = (sizeList[0].min_width+sizeList[0].max_width)/2;
       
  3773                 saveHeight = (sizeList[0].min_height+sizeList[0].max_height)/2;
       
  3774             } else {            /* it fits within the right size */
       
  3775               saveWidth = widthHint;
       
  3776               saveHeight = heightHint;
       
  3777             }
       
  3778 
       
  3779 #else /* XXX: old Solaris code */
       
  3780             /* REMIND: Aspect ratio */
       
  3781             if (widthHint  >= sizeList[0].max_width &&
       
  3782                 heightHint >= sizeList[0].max_height) {
       
  3783                 saveWidth = sizeList[0].max_width;
       
  3784                 saveHeight = sizeList[0].max_height;
       
  3785             } else if (widthHint  >= sizeList[0].min_width &&
       
  3786                        heightHint >= sizeList[0].min_height) {
       
  3787                 saveWidth = sizeList[0].min_width;
       
  3788                 saveHeight = sizeList[0].min_height;
       
  3789             } else {
       
  3790                 saveWidth = (sizeList[0].min_width+sizeList[0].max_width)/2;
       
  3791                 saveHeight = (sizeList[0].min_height+sizeList[0].max_height)/2;
       
  3792             }
       
  3793 #endif
       
  3794         }
       
  3795         free((void *) sizeList);
       
  3796     } else {
       
  3797         Window root;
       
  3798         if (XGetGeometry(awt_display,
       
  3799                          win,
       
  3800                          &root,
       
  3801                          &x,
       
  3802                          &y,
       
  3803                          (uint32_t *)&saveWidth,
       
  3804                          (uint32_t *)&saveHeight,
       
  3805                          (uint32_t *)&border_width,
       
  3806                          (uint32_t *)&depth)) {
       
  3807         }
       
  3808     }
       
  3809 
       
  3810  top:
       
  3811     (*env)->SetIntField(env, this, mWindowPeerIDs.iconWidth, (jint)saveWidth);
       
  3812     (*env)->SetIntField(env, this, mWindowPeerIDs.iconHeight, (jint)saveHeight);
       
  3813 
       
  3814     AWT_UNLOCK();
       
  3815     return TRUE;
       
  3816 }
       
  3817 
       
  3818 /*
       
  3819  * Class:     sun_awt_motif_MFramePeer
       
  3820  * Method:    pSetIconImage
       
  3821  * Signature: ([B[I[SII)V
       
  3822  */
       
  3823 JNIEXPORT void JNICALL Java_sun_awt_motif_MFramePeer_pSetIconImage___3B_3I_3SII
       
  3824 (JNIEnv *env, jobject this,
       
  3825  jbyteArray jbyteData, jintArray jintData, jshortArray jushortData,
       
  3826  jint iconWidth, jint iconHeight)
       
  3827 {
       
  3828     struct FrameData *wdata;
       
  3829     Window win;
       
  3830     GC gc;
       
  3831     int32_t x, y;
       
  3832     XImage *dst;
       
  3833     uint32_t mask;
       
  3834     XSetWindowAttributes attrs;
       
  3835     jobject jbuf = NULL;
       
  3836     void *buf = NULL;
       
  3837     int32_t len = 0;
       
  3838     int32_t bpp, slp, bpsl;
       
  3839     AwtGraphicsConfigDataPtr adata;
       
  3840 
       
  3841     if (JNU_IsNull(env, jbyteData)) {
       
  3842         if (JNU_IsNull(env, jintData)) {
       
  3843             if (JNU_IsNull(env, jushortData)) {
       
  3844                 /* [jk] Don't throw an exception here, it breaks
       
  3845                  * programs that run correctly on Windows
       
  3846                  * JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3847                  */
       
  3848                 return;
       
  3849             } else {
       
  3850                 jbuf = jushortData;
       
  3851             }
       
  3852         } else {
       
  3853             jbuf = jintData;
       
  3854         }
       
  3855     } else {
       
  3856         jbuf = jbyteData;
       
  3857         len = (*env)->GetArrayLength(env, jbyteData);
       
  3858     }
       
  3859     AWT_LOCK();
       
  3860     wdata = (struct FrameData *)
       
  3861         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  3862     /* REMIND: Need to figure out how to display image on a pixmap */
       
  3863 
       
  3864     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  3865         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  3866         AWT_UNLOCK();
       
  3867         return;
       
  3868     }
       
  3869 
       
  3870     adata = getGraphicsConfigFromComponentPeer(env, this);
       
  3871 
       
  3872     /* [jk] we need a new pixmap everytime:
       
  3873      * Test case: src/share/test/awt/FrameTest.html Look at the icon,
       
  3874      * select Operations/Change IconImage, you should see a different
       
  3875      * icon now.
       
  3876      */
       
  3877     if (wdata->iconPixmap) {
       
  3878         XFreePixmap(awt_display, wdata->iconPixmap);
       
  3879         wdata->iconPixmap = None;
       
  3880     }
       
  3881 
       
  3882     if (wdata->iconPixmap == None) {
       
  3883         if ((wdata->iconPixmap =
       
  3884              XCreatePixmap(awt_display,
       
  3885                            RootWindow(awt_display, adata->awt_visInfo.screen),
       
  3886                            iconWidth, iconHeight,
       
  3887                            adata->awtImage->Depth)) == None) {
       
  3888             /* REMIND: How to warn that there was a problem? */
       
  3889             AWT_UNLOCK();
       
  3890             return;
       
  3891         }
       
  3892         wdata->iconWidth = iconWidth;
       
  3893         wdata->iconHeight = iconHeight;
       
  3894     }
       
  3895 
       
  3896     buf = (void *) (*env)->GetPrimitiveArrayCritical(env, jbuf, NULL);
       
  3897     if (jbyteData != NULL) {
       
  3898         int32_t i;
       
  3899         unsigned char *ubuf = (unsigned char *) buf;
       
  3900         /* Need to map from ICM lut to cmap */
       
  3901         for (i=0; i < len; i++) {
       
  3902             ubuf[i] = (ubuf[i] >= adata->color_data->awt_numICMcolors)
       
  3903                         ? 0
       
  3904                         : adata->color_data->awt_icmLUT2Colors[ubuf[i]];
       
  3905         }
       
  3906     }
       
  3907 
       
  3908     bpp = adata->awtImage->wsImageFormat.bits_per_pixel;
       
  3909     slp = adata->awtImage->wsImageFormat.scanline_pad;
       
  3910     bpsl = paddedwidth(iconWidth * bpp, slp) >> 3;
       
  3911     if (((bpsl << 3) / bpp) < iconWidth) {
       
  3912         (*env)->ReleasePrimitiveArrayCritical(env, jbuf, buf, JNI_ABORT);
       
  3913         AWT_UNLOCK();
       
  3914         return;
       
  3915     }
       
  3916     dst = XCreateImage(awt_display, adata->awt_visInfo.visual,
       
  3917                        adata->awtImage->Depth, ZPixmap, 0,
       
  3918                        buf, iconWidth, iconHeight, 32, bpsl);
       
  3919     if (dst == NULL) {
       
  3920         /* REMIND: How to warn that there was a problem? */
       
  3921         (*env)->ReleasePrimitiveArrayCritical(env, jbuf, buf, JNI_ABORT);
       
  3922         AWT_UNLOCK();
       
  3923         return;
       
  3924     }
       
  3925 
       
  3926     if ((gc = XCreateGC(awt_display, wdata->iconPixmap, 0, 0)) == NULL) {
       
  3927         XDestroyImage (dst);
       
  3928         (*env)->ReleasePrimitiveArrayCritical(env, jbuf, buf, JNI_ABORT);
       
  3929         AWT_UNLOCK();
       
  3930         return;
       
  3931     }
       
  3932 
       
  3933     XPutImage(awt_display, wdata->iconPixmap, gc, dst,
       
  3934               0, 0, 0, 0, iconWidth, iconHeight);
       
  3935     (*env)->ReleasePrimitiveArrayCritical(env, jbuf, buf, JNI_ABORT);
       
  3936     dst->data=NULL;
       
  3937     XDestroyImage(dst);
       
  3938     XFreeGC(awt_display, gc);
       
  3939 
       
  3940     XtVaGetValues(wdata->winData.shell,
       
  3941                   XmNiconWindow, &win,
       
  3942                   NULL);
       
  3943     if (!win) {
       
  3944         mask = CWBorderPixel | CWColormap | CWBackPixmap;
       
  3945         attrs.border_pixel = awt_defaultFg;
       
  3946         attrs.colormap = adata->awt_cmap;
       
  3947         attrs.background_pixmap = wdata->iconPixmap;
       
  3948         if (!(win = XCreateWindow(awt_display,
       
  3949                                   RootWindow(awt_display,
       
  3950                                              adata->awt_visInfo.screen),
       
  3951                                   0, 0, iconWidth, iconHeight,
       
  3952                                   (uint32_t) 0,
       
  3953                                   adata->awtImage->Depth,
       
  3954                                   InputOutput,
       
  3955                                   adata->awt_visInfo.visual,
       
  3956                                   mask, &attrs))) {
       
  3957             /* Still can't create the window so try setting iconPixmap */
       
  3958             XtVaSetValues(wdata->winData.shell,
       
  3959                           XmNiconPixmap, wdata->iconPixmap,
       
  3960                           NULL);
       
  3961             AWT_FLUSH_UNLOCK();
       
  3962             return;
       
  3963         }
       
  3964     }
       
  3965 
       
  3966     XtVaSetValues(wdata->winData.shell,
       
  3967                   XmNiconPixmap, wdata->iconPixmap,
       
  3968                   XmNiconWindow, win,
       
  3969                   NULL);
       
  3970 
       
  3971     XSetWindowBackgroundPixmap(awt_display, win, wdata->iconPixmap);
       
  3972     XClearWindow(awt_display, win);
       
  3973     AWT_FLUSH_UNLOCK();
       
  3974 }
       
  3975 
       
  3976 
       
  3977 /*
       
  3978  * Class:     sun_awt_motif_MWindowPeer
       
  3979  * Method:    setResizable
       
  3980  * Signature: (Z)V
       
  3981  */
       
  3982 JNIEXPORT void JNICALL
       
  3983 Java_sun_awt_motif_MWindowPeer_setResizable(JNIEnv *env, jobject this,
       
  3984     jboolean resizable)
       
  3985 {
       
  3986     struct FrameData    *wdata;
       
  3987     jobject             target;
       
  3988     int32_t             targetWidth,
       
  3989                         targetHeight;
       
  3990     int32_t             width,          /* fixed width if not resizable */
       
  3991                         height;         /* fixed height if not resizable*/
       
  3992     int32_t             verticalAdjust; /* menubar, warning window, etc.*/
       
  3993 
       
  3994     if ((*env)->EnsureLocalCapacity(env, 1) < 0) {
       
  3995         return;
       
  3996     }
       
  3997 
       
  3998     AWT_LOCK();
       
  3999 
       
  4000     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4001 
       
  4002     wdata = (struct FrameData *)
       
  4003         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4004 
       
  4005     if (wdata == NULL
       
  4006         || wdata->winData.comp.widget == NULL
       
  4007         || wdata->winData.shell == NULL
       
  4008         || JNU_IsNull(env, target))
       
  4009     {
       
  4010         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4011         if (!JNU_IsNull(env, target))
       
  4012             (*env)->DeleteLocalRef(env, target);
       
  4013         AWT_UNLOCK();
       
  4014         return;
       
  4015     }
       
  4016 
       
  4017     DTRACE_PRINTLN3("TL: setResizable(0x%x/0x%x, %s)",
       
  4018                     wdata->winData.shell, XtWindow(wdata->winData.shell),
       
  4019                     resizable ? "true" : "false");
       
  4020 
       
  4021     if ((!wdata->isResizable) && (resizable)) {
       
  4022         awt_wm_setShellResizable(wdata);
       
  4023         wdata->isFixedSizeSet = False;
       
  4024     }
       
  4025     else if ((wdata->isResizable) && (!resizable)) {
       
  4026         /*
       
  4027          * To calculate fixed window width, height, we must subtract
       
  4028          * off the window manager borders as stored in the wdata
       
  4029          * structure.  But note that the wdata top and bottom fields
       
  4030          * may include space for warning window, menubar, IM status;
       
  4031          * this IS part of shell.
       
  4032          */
       
  4033         verticalAdjust = wdata->mbHeight;
       
  4034         if (wdata->warningWindow != NULL) {
       
  4035             verticalAdjust += wdata->wwHeight;
       
  4036         }
       
  4037         if (wdata->hasTextComponentNative) {
       
  4038             verticalAdjust += wdata->imHeight;
       
  4039         }
       
  4040 
       
  4041         targetWidth  = (*env)->GetIntField(env, target, componentIDs.width);
       
  4042         targetHeight = (*env)->GetIntField(env, target, componentIDs.height);
       
  4043         width  = targetWidth  - (wdata->left + wdata->right);
       
  4044         height = targetHeight - (wdata->top + wdata->bottom) + verticalAdjust;
       
  4045 #ifdef __linux__
       
  4046         width  = (width  > 0) ? width  : 1;
       
  4047         height = (height > 0) ? height : 1;
       
  4048 #endif
       
  4049         DTRACE_PRINTLN2("TL:     setting fixed size %ld x %ld", width, height);
       
  4050         awt_wm_setShellNotResizable(wdata, width, height, False);
       
  4051         if ((width > 0) && (height > 0)) {
       
  4052             wdata->isFixedSizeSet = True;
       
  4053         }
       
  4054     }
       
  4055 
       
  4056     wdata->isResizable = (Boolean)resizable;
       
  4057 
       
  4058     (*env)->DeleteLocalRef(env, target);
       
  4059     AWT_FLUSH_UNLOCK();
       
  4060 }
       
  4061 
       
  4062 
       
  4063 /* sun_awt_motif_MWindowPeer_pSetMenuBar() is native (X/Motif) routine
       
  4064    which handles insertion or deletion of a menubar from this frame.    */
       
  4065 
       
  4066 /*
       
  4067  * Class:     sun_awt_motif_MWindowPeer
       
  4068  * Method:    pSetMenuBar
       
  4069  * Signature: (Lsun/awt/motif/MMenuBarPeer;)V
       
  4070  */
       
  4071 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_pSetMenuBar
       
  4072 (JNIEnv *env, jobject this, jobject mb)
       
  4073 {
       
  4074     struct FrameData            *wdata;
       
  4075     struct ComponentData        *mdata;
       
  4076     jobject                     target;
       
  4077     Widget                      innerCanvasW;   /* Motif inner canvas   */
       
  4078 #ifdef _pauly_debug
       
  4079     Dimension                   mbHeight;       /* Motif menubar height */
       
  4080 #endif /* _pauly_debug */
       
  4081 
       
  4082 #ifdef _pauly_debug
       
  4083     fprintf(stdout," ++ ...pSetMenuBar.\n");
       
  4084     fflush(stdout);
       
  4085 #endif /* _pauly_debug */
       
  4086 
       
  4087 
       
  4088     if ((*env)->EnsureLocalCapacity(env, 1) < 0) {
       
  4089         return;
       
  4090     }
       
  4091     AWT_LOCK();
       
  4092 
       
  4093     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4094 
       
  4095     wdata = (struct FrameData *)
       
  4096         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4097 
       
  4098     if (JNU_IsNull(env, target) || wdata == NULL) {
       
  4099         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4100         if  (!JNU_IsNull(env, target)) {
       
  4101             (*env)->DeleteLocalRef(env, target);
       
  4102         }
       
  4103         AWT_UNLOCK();
       
  4104         return;
       
  4105     }
       
  4106 
       
  4107     if (mb == NULL) {
       
  4108 #ifdef _pauly_debug
       
  4109         fprintf(stdout,"    ...pSetMenuBar. mb is null.\n");
       
  4110         fflush(stdout);
       
  4111 #endif /* _pauly_debug */
       
  4112         if  (wdata->menuBar != NULL) {
       
  4113             /* Redo attachments of other form widgets appropriately now */
       
  4114             innerCanvasW = XtParent(wdata->winData.comp.widget);
       
  4115 
       
  4116             if  (wdata->warningWindow == NULL) {
       
  4117                 /* no warning window: canvas is now attached to form    */
       
  4118                 XtVaSetValues(innerCanvasW,
       
  4119                               XmNtopAttachment, XmATTACH_FORM,
       
  4120                               NULL);
       
  4121             } else {
       
  4122                 /* warning window present - conditional on #define NETSCAPE:
       
  4123                    if NETSCAPE, warning window is at bottom, so canvas is
       
  4124                    attached to the form (as above); otherwise (not NETSCAPE),
       
  4125                    warning window itself is instead attached to form.   */
       
  4126 #ifdef NETSCAPE
       
  4127                 XtVaSetValues(innerCanvasW,
       
  4128                               XmNtopAttachment, XmATTACH_FORM,
       
  4129                               NULL);
       
  4130 #else  /* NETSCAPE */
       
  4131                 XtVaSetValues(wdata->warningWindow,
       
  4132                               XmNtopAttachment, XmATTACH_FORM,
       
  4133                               NULL);
       
  4134 #endif /* NETSCAPE */
       
  4135             }
       
  4136 
       
  4137             wdata->menuBarReset = True;
       
  4138         }
       
  4139         wdata->menuBar = NULL;
       
  4140         awtJNI_setMbAndWwHeightAndOffsets(env, this, wdata);
       
  4141         (*env)->DeleteLocalRef(env, target);
       
  4142         AWT_FLUSH_UNLOCK();
       
  4143 #ifdef _pauly_debug
       
  4144         fprintf(stdout,"    ...pSetMenuBar. Done.\n");
       
  4145         fflush(stdout);
       
  4146 #endif /* _pauly_debug */
       
  4147         return;
       
  4148     }
       
  4149 
       
  4150     mdata = (struct ComponentData *)
       
  4151         JNU_GetLongFieldAsPtr(env, mb, mMenuBarPeerIDs.pData);
       
  4152     if (mdata == NULL) {
       
  4153         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4154         (*env)->DeleteLocalRef(env, target);
       
  4155         AWT_UNLOCK();
       
  4156         return;
       
  4157     }
       
  4158 
       
  4159     /* OK - insert the new menu bar into the form (at the top).
       
  4160        Redo the attachments of other form widgets appropriately.*/
       
  4161 
       
  4162     if  (wdata->menuBar == NULL)
       
  4163         wdata->menuBarReset = True;
       
  4164     wdata->menuBar = mdata->widget;
       
  4165 
       
  4166 #ifdef _pauly_debug
       
  4167     XtVaGetValues(mdata->widget, XmNheight, &mbHeight, NULL);
       
  4168     fprintf(stdout,"    ...pSetMenuBar. new menu bar (widget %x, parent: %x) - menu bar height: %d\n", wdata->menuBar, XtParent(wdata->menuBar), mbHeight);
       
  4169     fflush(stdout);
       
  4170 #endif /* _pauly_debug */
       
  4171 
       
  4172     XtVaSetValues(mdata->widget,
       
  4173                   XmNtopAttachment, XmATTACH_FORM,
       
  4174                   XmNleftAttachment, XmATTACH_FORM,
       
  4175                   XmNrightAttachment, XmATTACH_FORM,
       
  4176                   NULL);
       
  4177 
       
  4178     innerCanvasW = XtParent(wdata->winData.comp.widget);
       
  4179 
       
  4180     if  (wdata->warningWindow == NULL) {
       
  4181         /* no warning window: menu bar at top, canvas attached to it    */
       
  4182         XtVaSetValues(innerCanvasW,
       
  4183                       XmNtopAttachment, XmATTACH_WIDGET,
       
  4184                       XmNtopWidget, mdata->widget,
       
  4185                       NULL);
       
  4186     } else {
       
  4187         /* warning window present - conditional on #define NETSCAPE:
       
  4188            if NETSCAPE, warning window is at bottom, so canvas is
       
  4189            attached to menu bar (as above); otherwise (not NETSCAPE),
       
  4190            the warning window is attached just below the menu bar.  */
       
  4191 #ifdef NETSCAPE
       
  4192         XtVaSetValues(innerCanvasW,
       
  4193                       XmNtopAttachment, XmATTACH_WIDGET,
       
  4194                       XmNtopWidget, mdata->widget,
       
  4195                       NULL);
       
  4196 #else  /* NETSCAPE */
       
  4197         XtVaSetValues(wdata->warningWindow,
       
  4198                       XmNtopAttachment, XmATTACH_WIDGET,
       
  4199                       XmNtopWidget, mdata->widget,
       
  4200                       NULL);
       
  4201 #endif /* NETSCAPE */
       
  4202     }
       
  4203 
       
  4204     XtManageChild(mdata->widget);
       
  4205     XtMapWidget(mdata->widget);
       
  4206     XSync(awt_display, False);
       
  4207     awtJNI_setMbAndWwHeightAndOffsets(env, this, wdata);
       
  4208 
       
  4209 #ifdef _pauly_debug
       
  4210     XtVaGetValues(mdata->widget, XmNheight, &mbHeight, NULL);
       
  4211     fprintf(stdout,"    ...pSetMenuBar. with menu bar: menu bar height: %d, top offset: %d, bottom offset: %d\n", mbHeight, wdata->top, wdata->bottom);
       
  4212     fflush(stdout);
       
  4213 #endif /* _pauly_debug */
       
  4214 
       
  4215     (*env)->DeleteLocalRef(env, target);
       
  4216 
       
  4217     AWT_FLUSH_UNLOCK();
       
  4218 
       
  4219 #ifdef _pauly_debug
       
  4220     fprintf(stdout,"    ...pSetMenuBar. Done\n");
       
  4221     fflush(stdout);
       
  4222 #endif /* _pauly_debug */
       
  4223 }
       
  4224 
       
  4225 /*
       
  4226  * Class:     sun_awt_motif_MWindowPeer
       
  4227  * Method:    toBack
       
  4228  * Signature: ()V
       
  4229  */
       
  4230 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_toBack
       
  4231 (JNIEnv *env, jobject this)
       
  4232 {
       
  4233     struct FrameData *wdata;
       
  4234 
       
  4235     AWT_LOCK();
       
  4236 
       
  4237     wdata = (struct FrameData *)
       
  4238         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4239 
       
  4240     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  4241         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4242         AWT_UNLOCK();
       
  4243         return;
       
  4244     }
       
  4245     if (XtWindow(wdata->winData.shell) != 0) {
       
  4246         XLowerWindow(awt_display, XtWindow(wdata->winData.shell));
       
  4247     }
       
  4248     AWT_FLUSH_UNLOCK();
       
  4249 }
       
  4250 
       
  4251 /*
       
  4252  * Class:     sun_awt_motif_MWindowPeer
       
  4253  * Method:    updateAlwaysOnTop
       
  4254  * Signature: ()V
       
  4255  */
       
  4256 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_updateAlwaysOnTop
       
  4257 (JNIEnv *env, jobject this, jboolean isOnTop)
       
  4258 {
       
  4259     struct FrameData *wdata;
       
  4260     AWT_LOCK();
       
  4261     wdata = (struct FrameData *)
       
  4262         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4263     awt_wm_updateAlwaysOnTop(wdata, isOnTop);
       
  4264     AWT_FLUSH_UNLOCK();
       
  4265 }
       
  4266 
       
  4267 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_addTextComponentNative
       
  4268 (JNIEnv *env, jobject this, jobject tc)
       
  4269 {
       
  4270     struct FrameData            *wdata;
       
  4271     jobject                     target;
       
  4272 
       
  4273     if (JNU_IsNull(env, this)) {
       
  4274         return;
       
  4275     }
       
  4276 
       
  4277     AWT_LOCK();
       
  4278 
       
  4279     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4280     wdata = (struct FrameData *)
       
  4281         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4282 
       
  4283     if (wdata == NULL ||
       
  4284         wdata->winData.comp.widget==NULL ||
       
  4285         wdata->winData.shell==NULL ||
       
  4286         JNU_IsNull(env, target)) {
       
  4287         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4288         AWT_UNLOCK();
       
  4289         return;
       
  4290     }
       
  4291     if ( !wdata->hasTextComponentNative) {
       
  4292         wdata->hasTextComponentNative = True;
       
  4293         wdata->imHeight = awt_motif_getIMStatusHeight(wdata->winData.shell, tc);
       
  4294         wdata->bottom += wdata->imHeight;
       
  4295         awtJNI_ChangeInsets(env, this, wdata);
       
  4296         reshape(env, this, wdata,
       
  4297                 (*env)->GetIntField(env, target, componentIDs.x),
       
  4298                 (*env)->GetIntField(env, target, componentIDs.y),
       
  4299                 (*env)->GetIntField(env, target, componentIDs.width),
       
  4300                 (*env)->GetIntField(env, target, componentIDs.height),
       
  4301                 True);
       
  4302     }
       
  4303     AWT_UNLOCK();
       
  4304 }
       
  4305 
       
  4306 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_removeTextComponentNative
       
  4307 (JNIEnv *env, jobject this)
       
  4308 {
       
  4309     struct FrameData            *wdata;
       
  4310     jobject                     target;
       
  4311 
       
  4312     if (JNU_IsNull(env, this)) {
       
  4313         return;
       
  4314     }
       
  4315 
       
  4316     AWT_LOCK();
       
  4317 
       
  4318     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4319     wdata = (struct FrameData *)
       
  4320         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4321 
       
  4322     if (wdata == NULL ||
       
  4323         wdata->winData.comp.widget== NULL ||
       
  4324         wdata->winData.shell== NULL ||
       
  4325         JNU_IsNull(env, target)) {
       
  4326         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4327         AWT_UNLOCK();
       
  4328         return;
       
  4329     }
       
  4330     if (!wdata->hasTextComponentNative) {
       
  4331         AWT_UNLOCK();
       
  4332         return;
       
  4333     }
       
  4334 
       
  4335     wdata->bottom -= wdata->imHeight;
       
  4336     awtJNI_ChangeInsets(env, this, wdata);
       
  4337     wdata->imRemove = True;
       
  4338     reshape(env, this, wdata,
       
  4339             (*env)->GetIntField(env, target, componentIDs.x),
       
  4340             (*env)->GetIntField(env, target, componentIDs.y),
       
  4341             (*env)->GetIntField(env, target, componentIDs.width),
       
  4342             (*env)->GetIntField(env, target, componentIDs.height),
       
  4343             True);
       
  4344 
       
  4345     wdata->hasTextComponentNative = False;
       
  4346     wdata->imHeight = 0;
       
  4347 
       
  4348     AWT_UNLOCK();
       
  4349 } /* ...removeTextComponentPeer() */
       
  4350 
       
  4351 static Atom java_protocol = None;
       
  4352 static Atom motif_wm_msgs = None;
       
  4353 
       
  4354 static void im_callback(Widget shell, XtPointer client_data, XtPointer call_data)
       
  4355 {
       
  4356     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
  4357     JNU_CallMethodByName(env, NULL,
       
  4358                          (jobject)client_data,
       
  4359                          "notifyIMMOptionChange",
       
  4360                          "()V");
       
  4361 }
       
  4362 
       
  4363 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_pSetIMMOption
       
  4364 (JNIEnv *env, jobject this, jstring option)
       
  4365 {
       
  4366     char        *coption;
       
  4367     char        *empty = "InputMethod";
       
  4368     char        *menuItem;
       
  4369     jobject     globalRef;
       
  4370     struct FrameData *wdata;
       
  4371 
       
  4372     AWT_LOCK();
       
  4373 
       
  4374     wdata = (struct FrameData *)
       
  4375         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4376     if (wdata == NULL || wdata->winData.shell == NULL) {
       
  4377         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4378         AWT_UNLOCK();
       
  4379         return;
       
  4380     }
       
  4381 
       
  4382     globalRef = (jobject)JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.jniGlobalRef);
       
  4383     coption = (JNU_IsNull(env, option)) ? empty : (char *) JNU_GetStringPlatformChars(env, option, NULL);
       
  4384     if (java_protocol == None || motif_wm_msgs == None) {
       
  4385         java_protocol = XmInternAtom(awt_display, "_JAVA_IM_MSG", False);
       
  4386         motif_wm_msgs = XmInternAtom(awt_display, "_MOTIF_WM_MESSAGES", False);
       
  4387     }
       
  4388     XmAddProtocols (wdata->winData.shell, motif_wm_msgs, &java_protocol, 1);
       
  4389     XmAddProtocolCallback(wdata->winData.shell, motif_wm_msgs, java_protocol, im_callback, (XtPointer)globalRef);
       
  4390 
       
  4391     if ((menuItem = awt_util_makeWMMenuItem(coption, java_protocol))) {
       
  4392         XtVaSetValues(wdata->winData.shell,
       
  4393                       XmNmwmMenu,
       
  4394                       menuItem,
       
  4395                       NULL);
       
  4396         free(menuItem);
       
  4397     }
       
  4398     if (coption != empty)
       
  4399         JNU_ReleaseStringPlatformChars(env, option, (const char *) coption);
       
  4400     AWT_FLUSH_UNLOCK();
       
  4401 }
       
  4402 
       
  4403 
       
  4404 JNIEXPORT void JNICALL
       
  4405 Java_sun_awt_motif_MEmbeddedFramePeer_synthesizeFocusInOut(JNIEnv *env, jobject this,
       
  4406                                                            jboolean b)
       
  4407 {
       
  4408     EmbeddedFrame *ef;
       
  4409     Boolean dummy;
       
  4410 
       
  4411     AWT_LOCK();
       
  4412     ef = theEmbeddedFrameList;
       
  4413     while (ef != NULL) {
       
  4414         if ((*env)->IsSameObject(env, ef->javaRef, this)) {
       
  4415             XFocusChangeEvent xev;
       
  4416             xev.display = awt_display;
       
  4417             xev.serial = 0;
       
  4418             xev.type = b ? FocusIn : FocusOut;
       
  4419             xev.send_event = False;
       
  4420             xev.window = XtWindow(ef->embeddedFrame);
       
  4421             xev.mode = NotifyNormal;
       
  4422             xev.detail = NotifyNonlinear;
       
  4423             shellEH(ef->embeddedFrame, this, (XEvent*)&xev, &dummy);
       
  4424             break;
       
  4425         }
       
  4426         ef = ef->next;
       
  4427     }
       
  4428     AWT_UNLOCK();
       
  4429 }
       
  4430 
       
  4431 JNIEXPORT void JNICALL
       
  4432 Java_sun_awt_motif_MEmbeddedFramePeer_traverseOut(JNIEnv *env, jobject this, jboolean direction)
       
  4433 {
       
  4434     struct FrameData            *wdata;
       
  4435 
       
  4436     if (JNU_IsNull(env, this)) {
       
  4437         return;
       
  4438     }
       
  4439 
       
  4440     AWT_LOCK();
       
  4441 
       
  4442     wdata = (struct FrameData *)
       
  4443         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4444 
       
  4445     if (wdata == NULL ||
       
  4446         wdata->winData.comp.widget== NULL ||
       
  4447         wdata->winData.shell== NULL)
       
  4448     {
       
  4449         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4450         AWT_UNLOCK();
       
  4451         return;
       
  4452     }
       
  4453     xembed_traverse_out(wdata, direction);
       
  4454     AWT_UNLOCK();
       
  4455 }
       
  4456 
       
  4457 
       
  4458 JNIEXPORT void JNICALL
       
  4459 Java_sun_awt_motif_MEmbeddedFramePeer_NEFcreate(JNIEnv *env, jobject this,
       
  4460                                                 jobject parent, jlong handle)
       
  4461 {
       
  4462 #undef MAX_ARGC
       
  4463 #define MAX_ARGC 40
       
  4464     Arg      args[MAX_ARGC];
       
  4465     int32_t  argc;
       
  4466     struct   FrameData *wdata;
       
  4467     jobject  target;
       
  4468     jstring  warningString;
       
  4469     jboolean resizable;
       
  4470     jobject  globalRef = awtJNI_CreateAndSetGlobalRef(env, this);
       
  4471     Widget   innerCanvasW;  /* form's child, parent of the outer canvas
       
  4472                                drawing area */
       
  4473     AwtGraphicsConfigDataPtr adata;
       
  4474     AwtGraphicsConfigDataPtr defConfig;
       
  4475 
       
  4476     AWT_LOCK();
       
  4477 
       
  4478     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4479 
       
  4480     if (JNU_IsNull(env, target)) {
       
  4481         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4482         AWT_UNLOCK();
       
  4483         return;
       
  4484     }
       
  4485 
       
  4486     wdata = ZALLOC(FrameData);
       
  4487     JNU_SetLongFieldFromPtr(env, this, mComponentPeerIDs.pData, wdata);
       
  4488     if (wdata == NULL) {
       
  4489         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
  4490         AWT_UNLOCK();
       
  4491         return;
       
  4492     }
       
  4493 
       
  4494     adata = getGraphicsConfigFromComponentPeer(env, this);
       
  4495     defConfig = getDefaultConfig(adata->awt_visInfo.screen);
       
  4496 
       
  4497     /* A variation on Netscape's hack for embedded frames: the client area
       
  4498      * of the browser is a Java Frame for parenting purposes, but really a
       
  4499      * Motif child window
       
  4500      */
       
  4501     wdata->winData.flags |= W_IS_EMBEDDED;
       
  4502 
       
  4503     wdata->top = 0;
       
  4504     wdata->left = 0;
       
  4505     wdata->bottom = 0;
       
  4506     wdata->right = 0;
       
  4507     awtJNI_ChangeInsets(env, this, wdata);
       
  4508 
       
  4509 
       
  4510     wdata->isModal = 0;
       
  4511     wdata->isShowing = False;
       
  4512     wdata->shellResized = False;
       
  4513     wdata->canvasResized = False;
       
  4514     wdata->menuBarReset = False;
       
  4515 
       
  4516     resizable = (*env)->GetBooleanField(env, target, frameIDs.resizable);
       
  4517 
       
  4518     wdata->winData.shell = (Widget)handle;
       
  4519     awt_util_addEmbeddedFrame(wdata->winData.shell, globalRef);
       
  4520 
       
  4521     install_xembed((Widget)handle, wdata);
       
  4522 
       
  4523     setDeleteCallback(globalRef, wdata);
       
  4524     /* Establish resizability.  For the case of not resizable, do not
       
  4525        yet set a fixed size here; we must wait until in the routine
       
  4526        sun_awt_motif_MWindowPeer_pReshape() after insets have been fixed.
       
  4527        This is because correction of the insets may affect shell size.
       
  4528        (See comments in shellEH() concerning correction of the insets.  */
       
  4529     /*
       
  4530      * Fix for BugTraq ID 4313607.
       
  4531      * Initial resizability will be set later in MWindowPeer_setResizable()
       
  4532      * called from init(). But the real changes will be made only if the new
       
  4533      * and old resizability values are different at that point, so we
       
  4534      * initialize isResizable with inverse value here to get the job done.
       
  4535      */
       
  4536     wdata->isResizable = !resizable;
       
  4537     wdata->isFixedSizeSet = False;
       
  4538 #if 0
       
  4539     if (resizable) {
       
  4540         awt_wm_setShellResizable(wdata);
       
  4541     }
       
  4542 #endif
       
  4543 
       
  4544     XtAddEventHandler(wdata->winData.shell, StructureNotifyMask | FocusChangeMask,
       
  4545                       FALSE, (XtEventHandler)shellEH, globalRef);
       
  4546 
       
  4547 
       
  4548     argc = 0;
       
  4549     XtSetArg(args[argc], XmNvisual, defConfig->awt_visInfo.visual); argc++;
       
  4550     XtSetArg(args[argc], XmNcolormap, defConfig->awt_cmap); argc++;
       
  4551     XtSetArg(args[argc], XmNdepth, defConfig->awt_depth); argc++;
       
  4552     XtSetArg(args[argc], XmNmarginWidth, 0); argc++;
       
  4553     XtSetArg(args[argc], XmNmarginHeight, 0); argc++;
       
  4554     XtSetArg(args[argc], XmNhorizontalSpacing, 0); argc++;
       
  4555     XtSetArg(args[argc], XmNverticalSpacing, 0); argc++;
       
  4556     XtSetArg(args[argc], XmNscreen,
       
  4557              ScreenOfDisplay(awt_display, defConfig->awt_visInfo.screen)); argc++;
       
  4558 
       
  4559 
       
  4560     XtSetArg(args[argc], XmNresizePolicy, XmRESIZE_NONE); argc++;
       
  4561 
       
  4562     DASSERT(!(argc > MAX_ARGC));
       
  4563     wdata->mainWindow = XmCreateForm(wdata->winData.shell, "main", args, argc);
       
  4564 
       
  4565     /* The widget returned by awt_canvas_create is a drawing area
       
  4566        (i.e., canvas) which is the child of another drawing area
       
  4567        parent widget.  The parent is the drawing area within the
       
  4568        form just created.  The child is an drawing area layer over
       
  4569        the entire frame window, including the form, any menu bar
       
  4570        and warning windows present, and also window manager stuff.
       
  4571        The top, bottom, left, and right fields in wdata maintain
       
  4572        the respective offsets between these two drawing areas.  */
       
  4573 
       
  4574     wdata->winData.comp.widget = awt_canvas_create((XtPointer)globalRef,
       
  4575                                                    wdata->mainWindow,
       
  4576                                                    "frame_",
       
  4577                                                    -1,
       
  4578                                                    -1,
       
  4579                                                    True,
       
  4580                                                    wdata,
       
  4581                                                    defConfig);
       
  4582 
       
  4583     XtAddCallback(wdata->winData.comp.widget,
       
  4584                   XmNresizeCallback,
       
  4585                   outerCanvasResizeCB,
       
  4586                   globalRef);
       
  4587 
       
  4588 
       
  4589     innerCanvasW = XtParent(wdata->winData.comp.widget);
       
  4590     XtVaSetValues(innerCanvasW,
       
  4591                   XmNleftAttachment, XmATTACH_FORM,
       
  4592                   XmNrightAttachment, XmATTACH_FORM,
       
  4593                   NULL);
       
  4594 
       
  4595 
       
  4596     XtAddEventHandler(innerCanvasW, StructureNotifyMask, FALSE,
       
  4597                       (XtEventHandler)innerCanvasEH, globalRef);
       
  4598 
       
  4599     /* No menu bar initially */
       
  4600     wdata->menuBar = NULL;
       
  4601     wdata->mbHeight = 0;
       
  4602 
       
  4603     /* If a warning window (string) is needed, establish it now.*/
       
  4604     warningString =
       
  4605         (*env)->GetObjectField(env, target, windowIDs.warningString);
       
  4606 
       
  4607     /* No warning window present */
       
  4608     XtVaSetValues(innerCanvasW,
       
  4609                   XmNtopAttachment, XmATTACH_FORM,
       
  4610                   XmNbottomAttachment, XmATTACH_FORM,
       
  4611                   NULL);
       
  4612     wdata->warningWindow = NULL;
       
  4613     wdata->wwHeight = 0;
       
  4614 
       
  4615 
       
  4616     awt_util_show(wdata->winData.comp.widget);
       
  4617 
       
  4618     AWT_FLUSH_UNLOCK();
       
  4619 }  /* MEmbeddedFramePeer_NEFcreate() */
       
  4620 
       
  4621 
       
  4622 JNIEXPORT void JNICALL
       
  4623 Java_sun_awt_motif_MEmbeddedFramePeer_pShowImpl(JNIEnv *env, jobject this)
       
  4624 {
       
  4625     struct FrameData *wdata;
       
  4626 
       
  4627     AWT_LOCK();
       
  4628 
       
  4629     wdata = (struct FrameData *)
       
  4630         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4631     if (wdata == NULL ||
       
  4632         wdata->winData.comp.widget == NULL ||
       
  4633         wdata->winData.shell == NULL ||
       
  4634         wdata->mainWindow == NULL) {
       
  4635         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4636         AWT_UNLOCK();
       
  4637         return;
       
  4638     }
       
  4639     XtVaSetValues(wdata->winData.comp.widget,
       
  4640                   XmNx, -(wdata->left),
       
  4641                   XmNy, -(wdata->top), NULL);
       
  4642 
       
  4643     if (wdata->menuBar != 0) {
       
  4644         awt_util_show(wdata->menuBar);
       
  4645     }
       
  4646 
       
  4647     XtManageChild(wdata->mainWindow);
       
  4648     if (XtWindow(wdata->winData.shell) == None) {
       
  4649         XtRealizeWidget(wdata->winData.shell);
       
  4650     }
       
  4651     XtManageChild(wdata->winData.comp.widget);
       
  4652     XtSetMappedWhenManaged(wdata->winData.shell, True);
       
  4653     XtPopup(wdata->winData.shell, XtGrabNone);
       
  4654     wdata->isShowing = True;
       
  4655 
       
  4656     AWT_FLUSH_UNLOCK();
       
  4657 }
       
  4658 
       
  4659 /*
       
  4660  * Create a local managed widget inside a given X window.
       
  4661  * We allocate a top-level shell and then reparent it into the
       
  4662  * given window id.
       
  4663  *
       
  4664  * This is used to take the X11 window ID that has been passed
       
  4665  * to us by our parent Navigator plugin and return a widget
       
  4666  * that can be used as the base for our Java EmbeddeFrame.
       
  4667  *
       
  4668  * Note that the ordering of the various calls is tricky here as
       
  4669  * we have to cope with the variations between 1.1.3, 1.1.6,
       
  4670  * and 1.2.
       
  4671  */
       
  4672 JNIEXPORT jlong JNICALL
       
  4673 Java_sun_awt_motif_MEmbeddedFrame_getWidget(
       
  4674                 JNIEnv *env, jclass clz, jlong winid)
       
  4675 {
       
  4676     Arg args[40];
       
  4677     int argc;
       
  4678     Widget w;
       
  4679     Window child, parent;
       
  4680     Visual *visual;
       
  4681     Colormap cmap;
       
  4682     int depth;
       
  4683     int ncolors;
       
  4684 
       
  4685     /*
       
  4686      * Create a top-level shell.  Note that we need to use the
       
  4687      * AWT's own awt_display to initialize the widget.  If we
       
  4688      * try to create a second X11 display connection the Java
       
  4689      * runtimes get very confused.
       
  4690      */
       
  4691     AWT_LOCK();
       
  4692 
       
  4693     argc = 0;
       
  4694     XtSetArg(args[argc], XtNsaveUnder, False); argc++;
       
  4695     XtSetArg(args[argc], XtNallowShellResize, False); argc++;
       
  4696 
       
  4697     /* the awt initialization should be done by now (awt_GraphicsEnv.c) */
       
  4698 
       
  4699     getAwtData(&depth,&cmap,&visual,&ncolors,NULL);
       
  4700 
       
  4701     XtSetArg(args[argc], XtNvisual, visual); argc++;
       
  4702     XtSetArg(args[argc], XtNdepth, depth); argc++;
       
  4703     XtSetArg(args[argc], XtNcolormap, cmap); argc++;
       
  4704 
       
  4705     XtSetArg(args[argc], XtNwidth, 1); argc++;
       
  4706     XtSetArg(args[argc], XtNheight, 1); argc++;
       
  4707     /* The shell has to have relative coords of O,0? */
       
  4708     XtSetArg(args[argc], XtNx, 0); argc++;
       
  4709     XtSetArg(args[argc], XtNy, 0); argc++;
       
  4710 
       
  4711     /* The shell widget starts out as a top level widget.
       
  4712      * Without intervention, it will be managed by the window
       
  4713      * manager and will be its own widow. So, until it is reparented,
       
  4714      *  we don't map it.
       
  4715      */
       
  4716     XtSetArg(args[argc], XtNmappedWhenManaged, False); argc++;
       
  4717 
       
  4718     w = XtAppCreateShell("AWTapp","XApplication",
       
  4719                                     vendorShellWidgetClass,
       
  4720                                     awt_display,
       
  4721                                     args,
       
  4722                                     argc);
       
  4723     XtRealizeWidget(w);
       
  4724 
       
  4725     /*
       
  4726      * Now reparent our new Widget into our Navigator window
       
  4727      */
       
  4728     parent = (Window) winid;
       
  4729     child = XtWindow(w);
       
  4730     XReparentWindow(awt_display, child, parent, 0, 0);
       
  4731     XFlush(awt_display);
       
  4732     XSync(awt_display, False);
       
  4733     XtVaSetValues(w, XtNx, 0, XtNy, 0, NULL);
       
  4734     XFlush(awt_display);
       
  4735     XSync(awt_display, False);
       
  4736 
       
  4737     AWT_UNLOCK();
       
  4738 
       
  4739     return (jlong)w;
       
  4740 }
       
  4741 
       
  4742 /*
       
  4743  * Make sure the given widget is mapped.
       
  4744  *
       
  4745  * This isn't necessary on JDK 1.1.5 but is needed on JDK 1.1.4
       
  4746  */
       
  4747 JNIEXPORT jint JNICALL
       
  4748 Java_sun_awt_motif_MEmbeddedFrame_mapWidget(JNIEnv *env, jclass clz, jlong widget)
       
  4749 {
       
  4750     Widget w = (Widget)widget;
       
  4751     /*
       
  4752      * this is what JDK 1.1.5 does in MFramePeer.pShow.
       
  4753      */
       
  4754     AWT_LOCK();
       
  4755     XtSetMappedWhenManaged(w, True);
       
  4756     XtPopup(w, XtGrabNone);
       
  4757     AWT_UNLOCK();
       
  4758     return (jint) 1;
       
  4759 }
       
  4760 
       
  4761 
       
  4762 JNIEXPORT jboolean JNICALL
       
  4763 Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedActive(JNIEnv *env, jobject this)
       
  4764 {
       
  4765     struct FrameData *wdata;
       
  4766     Boolean res;
       
  4767 
       
  4768     AWT_LOCK();
       
  4769 
       
  4770     wdata = (struct FrameData *)
       
  4771         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4772     if (wdata == NULL ||
       
  4773         wdata->winData.comp.widget == NULL ||
       
  4774         wdata->winData.shell == NULL ||
       
  4775         wdata->mainWindow == NULL) {
       
  4776         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4777         AWT_UNLOCK();
       
  4778         return False;
       
  4779     }
       
  4780 
       
  4781     res = isXEmbedActive(wdata);
       
  4782     AWT_UNLOCK();
       
  4783     return res;
       
  4784 
       
  4785 }
       
  4786 
       
  4787 JNIEXPORT jboolean JNICALL
       
  4788 Java_sun_awt_motif_MEmbeddedFramePeer_isXEmbedApplicationActive(JNIEnv *env, jobject this)
       
  4789 {
       
  4790     struct FrameData *wdata;
       
  4791     Boolean res;
       
  4792 
       
  4793     AWT_LOCK();
       
  4794 
       
  4795     wdata = (struct FrameData *)
       
  4796         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4797     if (wdata == NULL ||
       
  4798         wdata->winData.comp.widget == NULL ||
       
  4799         wdata->winData.shell == NULL ||
       
  4800         wdata->mainWindow == NULL) {
       
  4801         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4802         AWT_UNLOCK();
       
  4803         return False;
       
  4804     }
       
  4805 
       
  4806     res = isXEmbedApplicationActive(wdata);
       
  4807     AWT_UNLOCK();
       
  4808     return res;
       
  4809 
       
  4810 }
       
  4811 
       
  4812 JNIEXPORT void JNICALL
       
  4813 Java_sun_awt_motif_MEmbeddedFramePeer_requestXEmbedFocus(JNIEnv *env, jobject this)
       
  4814 {
       
  4815     struct FrameData *wdata;
       
  4816 
       
  4817     AWT_LOCK();
       
  4818 
       
  4819     wdata = (struct FrameData *)
       
  4820         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4821     if (wdata == NULL ||
       
  4822         wdata->winData.comp.widget == NULL ||
       
  4823         wdata->winData.shell == NULL ||
       
  4824         wdata->mainWindow == NULL) {
       
  4825         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4826         AWT_UNLOCK();
       
  4827         return;
       
  4828     }
       
  4829 
       
  4830     requestXEmbedFocus(wdata);
       
  4831     AWT_UNLOCK();
       
  4832 }
       
  4833 
       
  4834 /*
       
  4835  * Class:     sun_awt_motif_MWindowPeer
       
  4836  * Method:    setSaveUnder
       
  4837  * Signature: (Z)V
       
  4838  */
       
  4839 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_setSaveUnder
       
  4840 (JNIEnv *env, jobject this, jboolean state)
       
  4841 {
       
  4842     struct FrameData    *wdata;
       
  4843     jobject             target;
       
  4844 
       
  4845     AWT_LOCK();
       
  4846 
       
  4847     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4848 
       
  4849     wdata = (struct FrameData *)
       
  4850         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4851 
       
  4852     if (wdata == NULL ||
       
  4853         wdata->winData.comp.widget == NULL ||
       
  4854         wdata->winData.shell == NULL ||
       
  4855         JNU_IsNull(env, target)) {
       
  4856         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4857         if  (!JNU_IsNull(env, target))
       
  4858             (*env)->DeleteLocalRef(env, target);
       
  4859         AWT_UNLOCK();
       
  4860         return;
       
  4861     }
       
  4862 
       
  4863     XtVaSetValues(wdata->winData.shell, XmNsaveUnder, state, NULL);
       
  4864 
       
  4865     AWT_FLUSH_UNLOCK();
       
  4866 }
       
  4867 
       
  4868 
       
  4869 /*
       
  4870  * Class:     sun_awt_motif_MWindowPeer
       
  4871  * Method:    setFocusableWindow
       
  4872  * Signature: (Z)V
       
  4873  */
       
  4874 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_setFocusableWindow
       
  4875 (JNIEnv *env, jobject this, jboolean isFocusableWindow)
       
  4876 {
       
  4877     struct FrameData    *wdata;
       
  4878     jobject             target;
       
  4879 
       
  4880     AWT_LOCK();
       
  4881 
       
  4882     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
  4883 
       
  4884     wdata = (struct FrameData *)
       
  4885         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
  4886 
       
  4887     if (wdata == NULL ||
       
  4888         wdata->winData.comp.widget == NULL ||
       
  4889         wdata->winData.shell == NULL ||
       
  4890         JNU_IsNull(env, target)) {
       
  4891         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4892         if  (!JNU_IsNull(env, target))
       
  4893             (*env)->DeleteLocalRef(env, target);
       
  4894         AWT_UNLOCK();
       
  4895         return;
       
  4896     }
       
  4897 
       
  4898     wdata->isFocusableWindow = isFocusableWindow;
       
  4899 
       
  4900     AWT_FLUSH_UNLOCK();
       
  4901 }
       
  4902 
       
  4903 /*
       
  4904  * Class:     sun_awt_motif_MWindowPeer
       
  4905  * Method:    resetTargetGC
       
  4906  * Signature: ()V
       
  4907  */
       
  4908 JNIEXPORT void JNICALL Java_sun_awt_motif_MWindowPeer_resetTargetGC
       
  4909   (JNIEnv * env, jobject this, jobject target)
       
  4910 {
       
  4911     (*env)->CallVoidMethod(env, target, windowIDs.resetGCMID);
       
  4912 }
       
  4913 
       
  4914 
       
  4915 /*
       
  4916  * Old, compatibility, backdoor for DT.  This is a different
       
  4917  * implementation.  It keeps the signature, but acts on
       
  4918  * awt_root_shell, not the frame passed as an argument.  Note, that
       
  4919  * the code that uses the old backdoor doesn't work correctly with
       
  4920  * gnome session proxy that checks for WM_COMMAND when the window is
       
  4921  * firts mapped, because DT code calls this old backdoor *after* the
       
  4922  * frame is shown or it would get NPE with old AWT (previous
       
  4923  * implementation of this backdoor) otherwise.  Old style session
       
  4924  * managers (e.g. CDE) that check WM_COMMAND only during session
       
  4925  * checkpoint should work fine, though.
       
  4926  *
       
  4927  * NB: The function name looks deceptively like a JNI native method
       
  4928  * name.  It's not!  It's just a plain function.
       
  4929  */
       
  4930 JNIEXPORT void JNICALL
       
  4931 Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this,
       
  4932     jobject frame, jstring jcommand)
       
  4933 {
       
  4934     const char *command;
       
  4935     XTextProperty text_prop;
       
  4936     char *c[1];
       
  4937     int32_t status;
       
  4938 
       
  4939     AWT_LOCK();
       
  4940 
       
  4941     if (awt_root_shell == NULL) {
       
  4942         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4943         AWT_UNLOCK();
       
  4944         return;
       
  4945     }
       
  4946 
       
  4947     if (XtWindow(awt_root_shell) == None) {
       
  4948         JNU_ThrowNullPointerException(env, "NullPointerException");
       
  4949         AWT_UNLOCK();
       
  4950         return;
       
  4951     }
       
  4952 
       
  4953     /* need to convert ctitle to CompoundText */
       
  4954     command = (char *) JNU_GetStringPlatformChars(env, jcommand, NULL);
       
  4955     c[0] = (char *)command;
       
  4956     status = XmbTextListToTextProperty(awt_display, c, 1,
       
  4957                                        XStdICCTextStyle, &text_prop);
       
  4958 
       
  4959     if (status == Success || status > 0) {
       
  4960         XSetTextProperty(awt_display, XtWindow(awt_root_shell),
       
  4961                          &text_prop, XA_WM_COMMAND);
       
  4962         if (text_prop.value != NULL)
       
  4963             XFree(text_prop.value);
       
  4964     }
       
  4965 
       
  4966     JNU_ReleaseStringPlatformChars(env, jcommand, command);
       
  4967 
       
  4968     AWT_UNLOCK();
       
  4969     return;
       
  4970 }
       
  4971 
       
  4972 
       
  4973 /*
       
  4974  * New DT backdoor to set WM_COMMAND.  New code should use this
       
  4975  * backdoor and call it *before* the first frame is shown so that
       
  4976  * gnome session proxy can correctly handle it.
       
  4977  *
       
  4978  * NB: The function name looks deceptively like a JNI native method
       
  4979  * name.  It's not!  It's just a plain function.
       
  4980  */
       
  4981 JNIEXPORT void JNICALL
       
  4982 Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv)
       
  4983 {
       
  4984     static const char empty[] = "";
       
  4985 
       
  4986     int argc;
       
  4987     const char **cargv;
       
  4988     XTextProperty text_prop;
       
  4989     int status;
       
  4990     int i;
       
  4991 
       
  4992     AWT_LOCK();
       
  4993 
       
  4994     if (awt_root_shell == NULL) {
       
  4995         JNU_ThrowNullPointerException(env, "AWT root shell");
       
  4996         AWT_UNLOCK();
       
  4997         return;
       
  4998     }
       
  4999 
       
  5000     if (XtWindow(awt_root_shell) == None) {
       
  5001         JNU_ThrowNullPointerException(env, "AWT root shell is unrealized");
       
  5002         AWT_UNLOCK();
       
  5003         return;
       
  5004     }
       
  5005 
       
  5006     argc = (int)(*env)->GetArrayLength(env, jargv);
       
  5007     if (argc == 0) {
       
  5008         /* nothing to do */
       
  5009         AWT_UNLOCK();
       
  5010         return;
       
  5011     }
       
  5012 
       
  5013     /* array of C strings */
       
  5014     cargv = (const char **)calloc(argc, sizeof(char *));
       
  5015     if (cargv == NULL) {
       
  5016         JNU_ThrowOutOfMemoryError(env, "Unable to allocate cargv");
       
  5017         AWT_UNLOCK();
       
  5018         return;
       
  5019     }
       
  5020 
       
  5021     /* fill C array with platform chars of java strings */
       
  5022     for (i = 0; i < argc; ++i) {
       
  5023         jstring js;
       
  5024         const char *cs;
       
  5025 
       
  5026         cs = NULL;
       
  5027         js = (*env)->GetObjectArrayElement(env, jargv, i);
       
  5028         if (js != NULL) {
       
  5029             cs = JNU_GetStringPlatformChars(env, js, NULL);
       
  5030         }
       
  5031         if (cs == NULL) {
       
  5032             cs = empty;
       
  5033         }
       
  5034 
       
  5035         cargv[i] = cs;
       
  5036         (*env)->DeleteLocalRef(env, js);
       
  5037     }
       
  5038 
       
  5039     /* grr, X prototype doesn't declare cargv as const, thought it really is */
       
  5040     status = XmbTextListToTextProperty(awt_display, (char **)cargv, argc,
       
  5041                                        XStdICCTextStyle, &text_prop);
       
  5042     if (status < 0) {
       
  5043         switch (status) {
       
  5044         case XNoMemory:
       
  5045             JNU_ThrowOutOfMemoryError(env,
       
  5046                 "XmbTextListToTextProperty: XNoMemory");
       
  5047             break;
       
  5048         case XLocaleNotSupported:
       
  5049             JNU_ThrowInternalError(env,
       
  5050                 "XmbTextListToTextProperty: XLocaleNotSupported");
       
  5051             break;
       
  5052         case XConverterNotFound:
       
  5053             JNU_ThrowNullPointerException(env,
       
  5054                 "XmbTextListToTextProperty: XConverterNotFound");
       
  5055             break;
       
  5056         default:
       
  5057             JNU_ThrowInternalError(env,
       
  5058                 "XmbTextListToTextProperty: unknown error");
       
  5059         }
       
  5060     } else {
       
  5061         /*
       
  5062          * status == Success (i.e. 0) or
       
  5063          * status > 0 - a number of unconvertible characters
       
  5064          *              (cannot happen for XStdICCTextStyle).
       
  5065          */
       
  5066         XSetTextProperty(awt_display, XtWindow(awt_root_shell),
       
  5067                          &text_prop, XA_WM_COMMAND);
       
  5068     }
       
  5069 
       
  5070     /* release platform chars */
       
  5071     for (i = 0; i < argc; ++i) {
       
  5072         jstring js;
       
  5073 
       
  5074         if (cargv[i] == empty)
       
  5075             continue;
       
  5076 
       
  5077         js = (*env)->GetObjectArrayElement(env, jargv, i);
       
  5078         JNU_ReleaseStringPlatformChars(env, js, cargv[i]);
       
  5079         (*env)->DeleteLocalRef(env, js);
       
  5080     }
       
  5081     if (text_prop.value != NULL)
       
  5082       XFree(text_prop.value);
       
  5083 
       
  5084     AWT_UNLOCK();
       
  5085     return;
       
  5086 }
       
  5087 
       
  5088 /*
       
  5089  * Class:     java_awt_TrayIcon
       
  5090  * Method:    initIDs
       
  5091  * Signature: ()V
       
  5092  */
       
  5093 JNIEXPORT void JNICALL Java_java_awt_TrayIcon_initIDs(JNIEnv *env , jclass clazz)
       
  5094 {
       
  5095 }