jdk/src/solaris/native/sun/awt/awt_xembed_server.c
changeset 11237 ff9cf1de21fa
parent 11236 0de47eef399c
parent 11235 3117d9a4bb02
child 11238 e2e56339976e
equal deleted inserted replaced
11236:0de47eef399c 11237:ff9cf1de21fa
     1 /*
       
     2  * Copyright (c) 2003, 2005, Oracle and/or its affiliates. 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.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 // TODO: Propogate applicationActive from Java
       
    27 
       
    28 #ifdef HEADLESS
       
    29     #error This file should not be included in headless library
       
    30 #endif
       
    31 
       
    32 #include "awt_p.h"
       
    33 
       
    34 #include <X11/Xproto.h>
       
    35 #include <X11/Xlib.h>
       
    36 #include <X11/Xatom.h>
       
    37 #include <Xm/MwmUtil.h>
       
    38 #ifdef __linux__
       
    39 #include <execinfo.h>
       
    40 #endif
       
    41 #include <stdio.h>
       
    42 #include <stdlib.h>
       
    43 
       
    44 /* JNI headers */
       
    45 #include "java_awt_Frame.h"     /* for frame state constants */
       
    46 #include "java_awt_event_KeyEvent.h"
       
    47 #include "awt_wm.h"
       
    48 #include "awt_util.h"           /* for X11 error handling macros */
       
    49 #include "awt_xembed.h"
       
    50 #include "awt_Component.h"
       
    51 #include "awt_AWTEvent.h"
       
    52 #include "canvas.h"
       
    53 #include "sun_awt_motif_MEmbedCanvasPeer.h"
       
    54 
       
    55 #ifdef DOTRACE
       
    56 #define MTRACE(param) fprintf(stderr, param)
       
    57 #define MTRACEP1(format, p1) fprintf(stderr, format, p1)
       
    58 #define MTRACEP2(format, p1, p2) fprintf(stderr, format, p1, p2)
       
    59 #define MTRACEP3(format, p1, p2, p3) fprintf(stderr, format, p1, p2, p3)
       
    60 #define MTRACEP4(format, p1, p2, p3, p4) fprintf(stderr, format, p1, p2, p3, p4)
       
    61 #define MTRACEP5(format, p1, p2, p3, p4, p5) fprintf(stderr, format, p1, p2, p3, p4, p5)
       
    62 #define MTRACEP6(format, p1, p2, p3, p4, p5, p6) fprintf(stderr, format, p1, p2, p3, p4, p5, p6)
       
    63 #define MTRACEP7(format, p1, p2, p3, p4, p5, p6, p7) fprintf(stderr, format, p1, p2, p3, p4, p5, p6, p7)
       
    64 #else
       
    65 #define MTRACE(param)
       
    66 #define MTRACEP1(format, p1)
       
    67 #define MTRACEP2(format, p1, p2)
       
    68 #define MTRACEP3(format, p1, p2, p3)
       
    69 #define MTRACEP4(format, p1, p2, p3, p4)
       
    70 #define MTRACEP5(format, p1, p2, p3, p4, p5)
       
    71 #define MTRACEP6(format, p1, p2, p3, p4, p5, p6)
       
    72 #define MTRACEP7(format, p1, p2, p3, p4, p5, p6, p7)
       
    73 #endif
       
    74 
       
    75 /**************************** XEmbed server DnD support ***********************/
       
    76 extern Atom XA_XdndAware;
       
    77 extern Boolean
       
    78 register_xembed_drop_site(JNIEnv* env, Display* dpy, jobject server,
       
    79                           Window serverHandle, Window clientHandle);
       
    80 extern Boolean
       
    81 unregister_xembed_drop_site(JNIEnv* env, Display* dpy, jobject server,
       
    82                             Window serverHandle, Window clientHandle);
       
    83 extern void
       
    84 forward_event_to_embedded(Window embedded, jlong ctxt, jint eventID);
       
    85 
       
    86 extern const char * msg_to_str(int msg);
       
    87 
       
    88 void
       
    89 set_xembed_drop_target(JNIEnv* env, jobject server);
       
    90 void
       
    91 remove_xembed_drop_target(JNIEnv* env, jobject server);
       
    92 Boolean
       
    93 is_xembed_client(Window window);
       
    94 /******************************************************************************/
       
    95 extern struct MComponentPeerIDs mComponentPeerIDs;
       
    96 static jobject createRectangle(JNIEnv* env, int x, int y, int width, int height);
       
    97 static jobject createDimension(JNIEnv* env, int width, int height);
       
    98 static void processXEmbedInfo(JNIEnv* env, jobject this);
       
    99 static Atom XA_XEmbedInfo;
       
   100 static Atom XA_XEmbed;
       
   101 static jmethodID requestXEmbedFocusMID, focusNextMID, focusPrevMID,
       
   102     registerAcceleratorMID, unregisterAcceleratorMID,
       
   103     grabKeyMID, ungrabKeyMID, childResizedMID,
       
   104     setXEmbedDropTargetMID, removeXEmbedDropTargetMID;
       
   105 static jfieldID keysymFID, modifiersFID, applicationActiveFID;
       
   106 
       
   107 typedef struct _xembed_server_data {
       
   108     Window handle; // pointer to plugin intermediate widget, XEmbed client
       
   109     Window serverHandle;
       
   110     Widget serverWidget;
       
   111     Boolean dispatching; // whether we dispatch messages for handle
       
   112     int version;
       
   113     jobject server;
       
   114     struct _xembed_server_data * next;
       
   115 } xembed_server_data, * pxembed_server_data;
       
   116 
       
   117 static pxembed_server_data xembed_list = NULL;
       
   118 
       
   119 static pxembed_server_data
       
   120 getData(Window handle) {
       
   121     pxembed_server_data temp = xembed_list;
       
   122     while (temp != NULL) {
       
   123         if (temp->handle == handle) {
       
   124             return temp;
       
   125         }
       
   126         temp = temp->next;
       
   127     }
       
   128     return NULL;
       
   129 }
       
   130 
       
   131 static pxembed_server_data
       
   132 getDataByEmbedder(jobject server) {
       
   133     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   134     pxembed_server_data temp = xembed_list;
       
   135     DASSERT(server != NULL);
       
   136     while (temp != NULL) {
       
   137         if ((*env)->IsSameObject(env, temp->server, server)) {
       
   138             return temp;
       
   139         }
       
   140         temp = temp->next;
       
   141     }
       
   142     return NULL;
       
   143 }
       
   144 
       
   145 static pxembed_server_data
       
   146 getDataByServerHandle(Window serverHandle) {
       
   147     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   148     pxembed_server_data temp = xembed_list;
       
   149     Widget serverWidget = NULL;
       
   150     if (serverHandle == None) {
       
   151         return NULL;
       
   152     }
       
   153     serverWidget = XtWindowToWidget(awt_display, serverHandle);
       
   154     while (temp != NULL) {
       
   155         if (temp->serverHandle == serverHandle || temp->serverWidget == serverWidget) {
       
   156             temp->serverHandle = serverWidget;
       
   157             return temp;
       
   158         }
       
   159         temp = temp->next;
       
   160     }
       
   161     return NULL;
       
   162 }
       
   163 
       
   164 static pxembed_server_data
       
   165 addData(jobject server) {
       
   166     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   167     struct ComponentData *cdata;
       
   168     xembed_server_data * data = malloc(sizeof(xembed_server_data));
       
   169     DASSERT(server != NULL);
       
   170     memset(data, 0, sizeof(xembed_server_data));
       
   171     data->server = server;
       
   172     cdata = (struct ComponentData *)
       
   173         JNU_GetLongFieldAsPtr(env, server, mComponentPeerIDs.pData);
       
   174     DASSERT(cdata != NULL);
       
   175     data->serverHandle = XtWindow(cdata->widget);
       
   176     data->serverWidget = cdata->widget;
       
   177     data->next = xembed_list;
       
   178     xembed_list = data;
       
   179     return data;
       
   180 }
       
   181 
       
   182 static void
       
   183 removeData(jobject server) {
       
   184     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   185     pxembed_server_data * temp = &xembed_list;
       
   186     DASSERT(server != NULL);
       
   187     while (*temp != NULL) {
       
   188         if ((*env)->IsSameObject(env, (*temp)->server, server)) {
       
   189             xembed_server_data * data = *temp;
       
   190             *temp = (*temp)->next;
       
   191             DASSERT(data->server != NULL);
       
   192             (*env)->DeleteGlobalRef(env, data->server);
       
   193             free(data);
       
   194             return;
       
   195         }
       
   196         temp = &(*temp)->next;
       
   197     }
       
   198 }
       
   199 
       
   200 void
       
   201 initXEmbedServerData() {
       
   202     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   203     jclass clazz;
       
   204     MTRACE("initXEmbedServerData\n");
       
   205     XA_XEmbedInfo = XInternAtom(awt_display, "_XEMBED_INFO", False);
       
   206     XA_XEmbed = XInternAtom(awt_display, "_XEMBED", False);
       
   207 
       
   208     clazz = (*env)->FindClass(env, "sun/awt/motif/MEmbedCanvasPeer");
       
   209     DASSERT(clazz != NULL);
       
   210     requestXEmbedFocusMID = (*env)->GetMethodID(env, clazz, "requestXEmbedFocus", "()V");
       
   211     DASSERT(requestXEmbedFocusMID != NULL);
       
   212     focusNextMID = (*env)->GetMethodID(env, clazz, "focusNext", "()V");
       
   213     DASSERT(focusNextMID != NULL);
       
   214     focusPrevMID = (*env)->GetMethodID(env, clazz, "focusPrev", "()V");
       
   215     DASSERT(focusPrevMID != NULL);
       
   216     registerAcceleratorMID = (*env)->GetMethodID(env, clazz, "registerAccelerator", "(JJJ)V");
       
   217     DASSERT(registerAcceleratorMID != NULL);
       
   218     unregisterAcceleratorMID = (*env)->GetMethodID(env, clazz, "unregisterAccelerator", "(J)V");
       
   219     DASSERT(unregisterAcceleratorMID != NULL);
       
   220     grabKeyMID = (*env)->GetMethodID(env, clazz, "grabKey", "(JJ)V");
       
   221     DASSERT(grabKeyMID != NULL);
       
   222     ungrabKeyMID = (*env)->GetMethodID(env, clazz, "ungrabKey", "(JJ)V");
       
   223     DASSERT(ungrabKeyMID != NULL);
       
   224     childResizedMID = (*env)->GetMethodID(env, clazz, "childResized", "()V");
       
   225     DASSERT(childResizedMID != NULL);
       
   226     setXEmbedDropTargetMID =
       
   227         (*env)->GetMethodID(env, clazz, "setXEmbedDropTarget", "()V");
       
   228     DASSERT(setXEmbedDropTargetMID != NULL);
       
   229     removeXEmbedDropTargetMID =
       
   230         (*env)->GetMethodID(env, clazz, "removeXEmbedDropTarget", "()V");
       
   231     DASSERT(removeXEmbedDropTargetMID != NULL);
       
   232 
       
   233     applicationActiveFID = (*env)->GetFieldID(env, clazz, "applicationActive", "Z");
       
   234     DASSERT(applicationActiveFID != NULL);
       
   235     (*env)->DeleteLocalRef(env, clazz);
       
   236 
       
   237     clazz = (*env)->FindClass(env, "sun/awt/motif/GrabbedKey");
       
   238     DASSERT(clazz != NULL);
       
   239     keysymFID = (*env)->GetFieldID(env, clazz, "keysym", "J");
       
   240     DASSERT(keysymFID != NULL);
       
   241     modifiersFID = (*env)->GetFieldID(env, clazz, "modifiers", "J");
       
   242     DASSERT(modifiersFID != NULL);
       
   243     (*env)->DeleteLocalRef(env, clazz);
       
   244 }
       
   245 
       
   246 /*
       
   247  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   248  * Method:    initXEmbedServer
       
   249  * Signature: ()V
       
   250  */
       
   251 JNIEXPORT void JNICALL
       
   252 Java_sun_awt_motif_MEmbedCanvasPeer_initXEmbedServer(JNIEnv *env, jobject this) {
       
   253     struct ComponentData *cdata;
       
   254     AWT_LOCK();
       
   255     MTRACE("initXEmbedServer\n");
       
   256     addData((*env)->NewGlobalRef(env, this));
       
   257     if (XA_XEmbedInfo == None) {
       
   258         initXEmbedServerData();
       
   259     }
       
   260     cdata = (struct ComponentData *)
       
   261         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   262 /*     XSelectInput(awt_display, XtWindow(cdata->widget), SubstructureNotifyMask); */
       
   263     XtAddEventHandler(cdata->widget,
       
   264                       SubstructureNotifyMask,
       
   265                       False, null_event_handler, NULL);
       
   266     AWT_UNLOCK();
       
   267 }
       
   268 
       
   269 /*
       
   270  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   271  * Method:    destroyXEmbedServer
       
   272  * Signature: ()V
       
   273  */
       
   274 JNIEXPORT void JNICALL
       
   275 Java_sun_awt_motif_MEmbedCanvasPeer_destroyXEmbedServer(JNIEnv *env, jobject this) {
       
   276     AWT_LOCK();
       
   277     MTRACE("destroyXEmbedServer\n");
       
   278     removeData(this);
       
   279     AWT_UNLOCK();
       
   280 }
       
   281 
       
   282 /*
       
   283  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   284  * Method:    isXEmbedActive
       
   285  * Signature: ()Z
       
   286  */
       
   287 JNIEXPORT jboolean JNICALL
       
   288 Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive(JNIEnv *env, jobject this) {
       
   289     pxembed_server_data sdata;
       
   290     jboolean res = JNI_FALSE;
       
   291     AWT_LOCK();
       
   292     sdata = getDataByEmbedder(this);
       
   293     if (sdata != NULL) {
       
   294         res = (sdata->handle != None)?JNI_TRUE:JNI_FALSE;
       
   295     }
       
   296     AWT_UNLOCK();
       
   297     return res;
       
   298 }
       
   299 
       
   300 /*
       
   301  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   302  * Method:    initDispatching
       
   303  * Signature: ()V
       
   304  */
       
   305 JNIEXPORT void JNICALL
       
   306 Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching (JNIEnv *env, jobject this) {
       
   307     pxembed_server_data sdata;
       
   308     AWT_LOCK();
       
   309     MTRACE("initDispatching\n");
       
   310     sdata = getDataByEmbedder(this);
       
   311     if (sdata != NULL) {
       
   312         XSelectInput(awt_display, sdata->handle, StructureNotifyMask | PropertyChangeMask);
       
   313         sdata->dispatching = True;
       
   314         register_xembed_drop_site(env, awt_display, sdata->server,
       
   315                                   sdata->serverHandle, sdata->handle);
       
   316     }
       
   317     processXEmbedInfo(env, this);
       
   318     Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded(env, this);
       
   319     AWT_UNLOCK();
       
   320 }
       
   321 
       
   322 /*
       
   323  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   324  * Method:    endDispatching
       
   325  * Signature: ()V
       
   326  */
       
   327 JNIEXPORT void JNICALL
       
   328 Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching (JNIEnv *env, jobject this) {
       
   329     pxembed_server_data sdata;
       
   330     AWT_LOCK();
       
   331     MTRACE("endDispatching\n");
       
   332     sdata = getDataByEmbedder(this);
       
   333     if (sdata != NULL) {
       
   334         unregister_xembed_drop_site(env, awt_display, sdata->server,
       
   335                                     sdata->serverHandle, sdata->handle);
       
   336         sdata->dispatching = False;
       
   337     }
       
   338     AWT_UNLOCK();
       
   339 }
       
   340 
       
   341 /*
       
   342  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   343  * Method:    embedChild
       
   344  * Signature: (J)V
       
   345  */
       
   346 JNIEXPORT void JNICALL
       
   347 Java_sun_awt_motif_MEmbedCanvasPeer_embedChild (JNIEnv * env, jobject this, jlong handle) {
       
   348     pxembed_server_data sdata;
       
   349     AWT_LOCK();
       
   350     MTRACE("embedChild\n");
       
   351     sdata = getDataByEmbedder(this);
       
   352     if (sdata != NULL) {
       
   353         if (sdata->handle != None) {
       
   354             Java_sun_awt_motif_MEmbedCanvasPeer_detachChild(env, this);
       
   355         }
       
   356         sdata->handle = (Window)handle;
       
   357         Java_sun_awt_motif_MEmbedCanvasPeer_initDispatching(env, this);
       
   358     }
       
   359     AWT_UNLOCK();
       
   360 }
       
   361 
       
   362 /*
       
   363  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   364  * Method:    childDestroyed
       
   365  * Signature: ()V
       
   366  */
       
   367 JNIEXPORT void JNICALL
       
   368 Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed (JNIEnv *env, jobject this) {
       
   369     pxembed_server_data sdata;
       
   370     AWT_LOCK();
       
   371     MTRACE("childDestroyed\n");
       
   372     Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching(env, this);
       
   373     sdata = getDataByEmbedder(this);
       
   374     if (sdata != NULL) {
       
   375         sdata->handle = None;
       
   376     }
       
   377     AWT_UNLOCK();
       
   378 }
       
   379 
       
   380 /*
       
   381  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   382  * Method:    getEmbedPreferredSize
       
   383  * Signature: ()Ljava/awt/Dimension;
       
   384  */
       
   385 JNIEXPORT jobject JNICALL
       
   386 Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedPreferredSize (JNIEnv *env, jobject this) {
       
   387     pxembed_server_data sdata;
       
   388     jobject res = NULL;
       
   389     XSizeHints * hints;
       
   390     long dummy;
       
   391     AWT_LOCK();
       
   392     MTRACE("getPreferredSize\n");
       
   393     sdata = getDataByEmbedder(this);
       
   394     if (sdata != NULL) {
       
   395         hints = XAllocSizeHints();
       
   396         DASSERT(hints != NULL);
       
   397         DASSERT(sdata->handle != None);
       
   398         if (XGetWMNormalHints(awt_display, sdata->handle, hints, &dummy) == Success) {
       
   399             res = createDimension(env, hints->width, hints->height);
       
   400         }
       
   401         XFree(hints);
       
   402     }
       
   403     AWT_UNLOCK();
       
   404     return res;
       
   405 }
       
   406 
       
   407 /*
       
   408  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   409  * Method:    getEmbedMinimumSize
       
   410  * Signature: ()Ljava/awt/Dimension;
       
   411  */
       
   412 JNIEXPORT jobject JNICALL
       
   413 Java_sun_awt_motif_MEmbedCanvasPeer_getEmbedMinimumSize (JNIEnv *env, jobject this) {
       
   414     pxembed_server_data sdata;
       
   415     jobject res = NULL;
       
   416     XSizeHints * hints;
       
   417     long dummy;
       
   418     AWT_LOCK();
       
   419     MTRACE("getMinimumSize\n");
       
   420     sdata = getDataByEmbedder(this);
       
   421     if (sdata != NULL) {
       
   422         hints = XAllocSizeHints();
       
   423         DASSERT(hints != NULL);
       
   424         DASSERT(sdata->handle != None);
       
   425         if (XGetWMNormalHints(awt_display, sdata->handle, hints, &dummy) == Success) {
       
   426             res = createDimension(env, hints->min_width, hints->min_height);
       
   427         }
       
   428         XFree(hints);
       
   429     }
       
   430     AWT_UNLOCK();
       
   431     return res;
       
   432 }
       
   433 
       
   434 /*
       
   435  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   436  * Method:    getClientBounds
       
   437  * Signature: ()Ljava/awt/Rectangle;
       
   438  */
       
   439 JNIEXPORT jobject JNICALL
       
   440 Java_sun_awt_motif_MEmbedCanvasPeer_getClientBounds (JNIEnv *env, jobject this) {
       
   441     pxembed_server_data sdata;
       
   442     jobject res = NULL;
       
   443     AWT_LOCK();
       
   444     MTRACE("getClientBounds\n");
       
   445     sdata = getDataByEmbedder(this);
       
   446     if (sdata != NULL) {
       
   447         XWindowAttributes attrs;
       
   448         DASSERT(sdata->handle != None);
       
   449         if (XGetWindowAttributes(awt_display, sdata->handle, &attrs) == Success) {
       
   450             res = createRectangle(env, attrs.x, attrs.y, attrs.width, attrs.height);
       
   451         }
       
   452     }
       
   453     AWT_UNLOCK();
       
   454     return res;
       
   455 }
       
   456 
       
   457 Boolean
       
   458 isApplicationActive(JNIEnv * env, jobject this) {
       
   459     return (*env)->GetBooleanField(env, this, applicationActiveFID);
       
   460 }
       
   461 
       
   462 /*
       
   463  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   464  * Method:    notifyChildEmbedded
       
   465  * Signature: ()V
       
   466  */
       
   467 JNIEXPORT void JNICALL
       
   468 Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded (JNIEnv *env, jobject this) {
       
   469     struct ComponentData *cdata;
       
   470     pxembed_server_data sdata;
       
   471     AWT_LOCK();
       
   472     MTRACE("notifyChildEmbedded\n");
       
   473     cdata = (struct ComponentData *)
       
   474         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   475     sdata = getDataByEmbedder(this);
       
   476     if (sdata != NULL) {
       
   477         DASSERT(sdata->handle != None);
       
   478         DASSERT(cdata != NULL);
       
   479         DASSERT(XtWindow(cdata->widget) != None);
       
   480         sendMessageHelper(sdata->handle, XEMBED_EMBEDDED_NOTIFY, XtWindow(cdata->widget), min(sdata->version, XEMBED_VERSION), 0);
       
   481         if (isApplicationActive(env, this)) {
       
   482             sendMessage(sdata->handle, XEMBED_WINDOW_ACTIVATE);
       
   483         }
       
   484     }
       
   485     AWT_UNLOCK();
       
   486 }
       
   487 
       
   488 /*
       
   489  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   490  * Method:    detachChild
       
   491  * Signature: ()V
       
   492  */
       
   493 JNIEXPORT void JNICALL
       
   494 Java_sun_awt_motif_MEmbedCanvasPeer_detachChild (JNIEnv *env, jobject this) {
       
   495     pxembed_server_data sdata;
       
   496     AWT_LOCK();
       
   497     MTRACE("detachChild\n");
       
   498     sdata = getDataByEmbedder(this);
       
   499     if (sdata != NULL) {
       
   500         /**
       
   501          *  XEmbed specification:
       
   502          *  "The embedder can unmap the client and reparent the client window to the root window. If the
       
   503          *  client receives an ReparentNotify event, it should check the parent field of the XReparentEvent
       
   504          *  structure. If this is the root window of the window's screen, then the protocol is finished and
       
   505          *  there is no further interaction. If it is a window other than the root window, then the protocol
       
   506          *  continues with the new parent acting as the embedder window."
       
   507          */
       
   508         DASSERT(sdata->handle != None);
       
   509         XUnmapWindow(awt_display, sdata->handle);
       
   510         XReparentWindow(awt_display, sdata->handle, DefaultRootWindow(awt_display), 0, 0);
       
   511         Java_sun_awt_motif_MEmbedCanvasPeer_endDispatching(env, this);
       
   512         sdata->handle = None;
       
   513     }
       
   514     AWT_UNLOCK();
       
   515 }
       
   516 
       
   517 /*
       
   518  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   519  * Method:    forwardKeyEvent
       
   520  * Signature: (Ljava/awt/event/KeyEvent;)V
       
   521  */
       
   522 JNIEXPORT void JNICALL
       
   523 Java_sun_awt_motif_MEmbedCanvasPeer_forwardKeyEvent (JNIEnv *env, jobject this, jobject event) {
       
   524     pxembed_server_data sdata;
       
   525     jbyteArray array;
       
   526     XEvent *xevent;
       
   527     AWT_LOCK();
       
   528     MTRACE("forwardKeyEvent\n");
       
   529     sdata = getDataByEmbedder(this);
       
   530     if (sdata != NULL) {
       
   531         DASSERT(sdata->handle != None);
       
   532         array = (jbyteArray)(*env)->GetObjectField(env, event, awtEventIDs.bdata);
       
   533         if (array == NULL) {
       
   534             MTRACE("array is null\n");
       
   535             AWT_UNLOCK();
       
   536             return;
       
   537         }
       
   538 
       
   539         xevent = (XEvent *)(*env)->GetByteArrayElements(env, array, NULL);
       
   540         if (xevent == NULL) {
       
   541             (*env)->DeleteLocalRef(env, array);
       
   542             MTRACE("xevent is null\n");
       
   543             AWT_UNLOCK();
       
   544             return;
       
   545         }
       
   546         xevent->xany.window = sdata->handle;
       
   547         XSendEvent(awt_display, sdata->handle, False, NoEventMask, xevent);
       
   548         (*env)->DeleteLocalRef(env, array);
       
   549     }
       
   550     AWT_UNLOCK();
       
   551 }
       
   552 
       
   553 /*
       
   554  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   555  * Method:    getAWTKeyCodeForKeySym
       
   556  * Signature: (I)I
       
   557  */
       
   558 JNIEXPORT jint JNICALL
       
   559 Java_sun_awt_motif_MEmbedCanvasPeer_getAWTKeyCodeForKeySym (JNIEnv *env, jobject this, jint keysym) {
       
   560     jint keycode = java_awt_event_KeyEvent_VK_UNDEFINED;
       
   561     Boolean mapsToUnicodeChar;
       
   562     jint keyLocation;
       
   563     keysymToAWTKeyCode(keysym, &keycode, &mapsToUnicodeChar, &keyLocation);
       
   564     return keycode;
       
   565 }
       
   566 
       
   567 /*
       
   568  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   569  * Method:    sendMessage
       
   570  * Signature: (I)V
       
   571  */
       
   572 JNIEXPORT void JNICALL
       
   573 Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__I (JNIEnv *env, jobject this, jint msg) {
       
   574     pxembed_server_data sdata;
       
   575     AWT_LOCK();
       
   576     MTRACEP2("sendMessage %d(%s)\n", msg, msg_to_str(msg));
       
   577     sdata = getDataByEmbedder(this);
       
   578     if (sdata != NULL) {
       
   579         DASSERT(sdata->handle != None);
       
   580         sendMessage(sdata->handle, msg);
       
   581     }
       
   582     AWT_UNLOCK();
       
   583 }
       
   584 
       
   585 /*
       
   586  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   587  * Method:    sendMessage
       
   588  * Signature: (IJJJ)V
       
   589  */
       
   590 JNIEXPORT void JNICALL
       
   591 Java_sun_awt_motif_MEmbedCanvasPeer_sendMessage__IJJJ (JNIEnv *env, jobject this, jint msg, jlong detail, jlong data1, jlong data2) {
       
   592     pxembed_server_data sdata;
       
   593     AWT_LOCK();
       
   594     MTRACEP5("sendMessage2 msg %d(%s) detail %d data: %d %d\n", msg, msg_to_str(msg), detail, data1, data2);
       
   595     sdata = getDataByEmbedder(this);
       
   596     if (sdata != NULL) {
       
   597         DASSERT(sdata->handle != None);
       
   598         sendMessageHelper(sdata->handle, msg, detail, data1, data2);
       
   599     }
       
   600     AWT_UNLOCK();
       
   601 }
       
   602 
       
   603 static jobject
       
   604 createRectangle(JNIEnv* env, int x, int y, int width, int height) {
       
   605     static jclass clazz;
       
   606     static jmethodID mid;
       
   607     jobject rect = NULL;
       
   608     if (mid == 0) {
       
   609         jclass l_clazz = (*env)->FindClass(env, "java/awt/Rectangle");
       
   610         DASSERT(l_clazz != NULL);
       
   611         mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V");
       
   612         DASSERT(mid != NULL);
       
   613         clazz = (*env)->NewGlobalRef(env, l_clazz);
       
   614         (*env)->DeleteLocalRef(env, l_clazz);
       
   615     }
       
   616     if (mid != NULL) {
       
   617         rect = (*env)->NewObject(env, clazz, mid, x, y, width, height);
       
   618         if ((*env)->ExceptionOccurred(env)) {
       
   619             return NULL;
       
   620         }
       
   621     }
       
   622     return rect;
       
   623 }
       
   624 
       
   625 static jobject
       
   626 createDimension(JNIEnv* env, int width, int height) {
       
   627     static jclass clazz;
       
   628     static jmethodID mid;
       
   629     jobject dim = NULL;
       
   630     if (mid == 0) {
       
   631         jclass l_clazz = (*env)->FindClass(env, "java/awt/Dimension");
       
   632         DASSERT(l_clazz != NULL);
       
   633         mid = (*env)->GetMethodID(env, clazz, "<init>", "(II)V");
       
   634         DASSERT(mid != NULL);
       
   635         clazz = (*env)->NewGlobalRef(env, l_clazz);
       
   636         (*env)->DeleteLocalRef(env, l_clazz);
       
   637     }
       
   638     if (mid != NULL) {
       
   639         dim = (*env)->NewObject(env, clazz, mid, width, height);
       
   640         if ((*env)->ExceptionOccurred(env)) {
       
   641             return NULL;
       
   642         }
       
   643     }
       
   644     return dim;
       
   645 }
       
   646 
       
   647 Boolean isMapped(Window w) {
       
   648     XWindowAttributes attr;
       
   649     Status status = 0;
       
   650     WITH_XERROR_HANDLER(xerror_ignore_bad_window);
       
   651     status = XGetWindowAttributes(awt_display, w, &attr);
       
   652     RESTORE_XERROR_HANDLER;
       
   653     if (status == 0 || xerror_code != Success) {
       
   654         return False;
       
   655     }
       
   656     return !(attr.map_state == IsUnmapped);
       
   657 }
       
   658 
       
   659 static void
       
   660 processXEmbedInfo(JNIEnv * env, jobject this) {
       
   661     pxembed_server_data sdata;
       
   662     AWT_LOCK();
       
   663     MTRACE("processXEmbedInfo\n");
       
   664     sdata = getDataByEmbedder(this);
       
   665     if (Java_sun_awt_motif_MEmbedCanvasPeer_isXEmbedActive(env, this)) {
       
   666         Atom actual_type;
       
   667         int actual_format;
       
   668         unsigned long nitems;
       
   669         unsigned long bytes_after;
       
   670         CARD32 * data = NULL;
       
   671         DASSERT(sdata->handle != None);
       
   672         if (XGetWindowProperty(awt_display, sdata->handle, XA_XEmbedInfo,
       
   673                            0, 2, False, XA_XEmbedInfo, &actual_type,
       
   674                            &actual_format, &nitems, &bytes_after,
       
   675                                (unsigned char**)&data) != Success)
       
   676         {
       
   677             AWT_UNLOCK();
       
   678             return;
       
   679         }
       
   680         if (actual_type == XA_XEmbedInfo && actual_format == 32
       
   681             && nitems == 2)
       
   682         {
       
   683             CARD32 flags;
       
   684             Boolean new_mapped, currently_mapped;
       
   685             sdata->version = *data;
       
   686             flags = *(data+1);
       
   687             new_mapped = (flags & XEMBED_MAPPED) != 0;
       
   688             currently_mapped = isMapped(sdata->handle);
       
   689             if (new_mapped != currently_mapped) {
       
   690                 if (new_mapped) {
       
   691                     XMapWindow(awt_display, sdata->handle);
       
   692                 } else {
       
   693                     XUnmapWindow(awt_display, sdata->handle);
       
   694                 }
       
   695             }
       
   696         }
       
   697         if (data != NULL) {
       
   698             XFree(data);
       
   699         }
       
   700     }
       
   701     AWT_UNLOCK();
       
   702 }
       
   703 
       
   704 /**
       
   705  * Handles client message on embedder
       
   706  */
       
   707 static void
       
   708 handleClientMessage(JNIEnv* env, jobject this, XClientMessageEvent * ev) {
       
   709     pxembed_server_data sdata;
       
   710     AWT_LOCK();
       
   711     MTRACEP5("handleClientMessage: 0=%ld 1=%ld 2=%ld 3=%ld 4=%ld\n",
       
   712             ev->data.l[0], ev->data.l[1], ev->data.l[2], ev->data.l[3], ev->data.l[4]);
       
   713     sdata = getDataByEmbedder(this);
       
   714     if (sdata != NULL && sdata->handle != None) {
       
   715         switch ((int)ev->data.l[1]) {
       
   716           case XEMBED_REQUEST_FOCUS:
       
   717               MTRACE("REQUEST_FOCUS\n");
       
   718               (*env)->CallVoidMethod(env, this, requestXEmbedFocusMID);
       
   719               break;
       
   720           case XEMBED_FOCUS_NEXT:
       
   721               MTRACE("FOCUS_NEXT\n");
       
   722               (*env)->CallVoidMethod(env, this, focusNextMID);
       
   723               break;
       
   724           case XEMBED_FOCUS_PREV:
       
   725               MTRACE("FOCUS_PREV\n");
       
   726               (*env)->CallVoidMethod(env, this, focusPrevMID);
       
   727               break;
       
   728           case XEMBED_REGISTER_ACCELERATOR:
       
   729               MTRACE("REGISTER_ACCEL\n");
       
   730               (*env)->CallVoidMethod(env, this, registerAcceleratorMID,
       
   731                                      (jlong)ev->data.l[2],
       
   732                                      (jlong)ev->data.l[3],
       
   733                                      (jlong)ev->data.l[4]);
       
   734               break;
       
   735           case XEMBED_UNREGISTER_ACCELERATOR:
       
   736               MTRACE("UNREGISTER_ACCEL\n");
       
   737               (*env)->CallVoidMethod(env, this, unregisterAcceleratorMID,
       
   738                                      (jlong)ev->data.l[2]);
       
   739               break;
       
   740           case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
       
   741               MTRACE("GRAB_KEY\n");
       
   742               (*env)->CallVoidMethod(env, this, grabKeyMID,
       
   743                                      (jlong)ev->data.l[3],
       
   744                                      (jlong)ev->data.l[4]);
       
   745               break;
       
   746           case NON_STANDARD_XEMBED_GTK_UNGRAB_KEY:
       
   747               MTRACE("UNGRAB_KEY\n");
       
   748               (*env)->CallVoidMethod(env, this, ungrabKeyMID,
       
   749                                      (jlong)ev->data.l[3],
       
   750                                      (jlong)ev->data.l[4]);
       
   751           case _SUN_XEMBED_START:
       
   752               MTRACE("XEMBED_START\n");
       
   753               processXEmbedInfo(env, this);
       
   754               Java_sun_awt_motif_MEmbedCanvasPeer_notifyChildEmbedded(env, this);
       
   755               break;
       
   756         }
       
   757     }
       
   758     AWT_UNLOCK();
       
   759 }
       
   760 
       
   761 /**
       
   762  * Handles property changes on xembed client
       
   763  */
       
   764 static void
       
   765 handlePropertyNotify(XPropertyEvent * ev) {
       
   766     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   767     pxembed_server_data sdata;
       
   768     AWT_LOCK();
       
   769     MTRACE("handlePropertyNotify\n");
       
   770     sdata = getData(ev->window);
       
   771     if (sdata != NULL) {
       
   772         if (ev->atom == XA_WM_NORMAL_HINTS) {
       
   773             DASSERT(sdata->server != NULL);
       
   774             (*env)->CallVoidMethod(env, sdata->server, childResizedMID);
       
   775             MTRACE("NORMAL_HINTS have changed\n");
       
   776         } else if (ev->atom == XA_XdndAware) {
       
   777             unregister_xembed_drop_site(env, awt_display, sdata->server,
       
   778                                         sdata->serverHandle, sdata->handle);
       
   779             if (ev->state == PropertyNewValue) {
       
   780                 register_xembed_drop_site(env, awt_display, sdata->server,
       
   781                                           sdata->serverHandle, sdata->handle);
       
   782             }
       
   783         } else if (ev->atom == XA_XEmbedInfo) {
       
   784             DASSERT(sdata->server != NULL);
       
   785             MTRACE("XEMBED_INFO has changed\n");
       
   786             processXEmbedInfo(env, sdata->server);
       
   787         }
       
   788     }
       
   789     AWT_UNLOCK();
       
   790 }
       
   791 
       
   792 static void
       
   793 handleConfigureNotify(XConfigureEvent * ev) {
       
   794     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   795     pxembed_server_data sdata;
       
   796     AWT_LOCK();
       
   797     MTRACE("handleConfigureNotify\n");
       
   798     sdata = getData(ev->window);
       
   799     if (sdata != NULL) {
       
   800         DASSERT(sdata->server != NULL);
       
   801         (*env)->CallVoidMethod(env, sdata->server, childResizedMID);
       
   802     }
       
   803     AWT_UNLOCK();
       
   804 }
       
   805 
       
   806 /*
       
   807  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   808  * Method:    sendMessage
       
   809  * Signature: (IJJJ)V
       
   810  */
       
   811 JNIEXPORT void JNICALL
       
   812 Java_sun_awt_motif_GrabbedKey_initKeySymAndModifiers (JNIEnv *env, jobject this, jobject keyevent) {
       
   813     jbyteArray array;
       
   814     XEvent *xevent;
       
   815     int keysym, modifiers;
       
   816     int keycode;
       
   817     AWT_LOCK();
       
   818     array = (jbyteArray)(*env)->GetObjectField(env, keyevent, awtEventIDs.bdata);
       
   819     if (array == NULL) {
       
   820         AWT_UNLOCK();
       
   821         return;
       
   822     }
       
   823     xevent = (XEvent *)(*env)->GetByteArrayElements(env, array, NULL);
       
   824     if (xevent == NULL) {
       
   825         (*env)->DeleteLocalRef(env, array);
       
   826         AWT_UNLOCK();
       
   827         return;
       
   828     }
       
   829     keycode = (*env)->GetIntField(env, keyevent, keyEventIDs.keyCode);
       
   830     keysym = awt_getX11KeySym(keycode);
       
   831     modifiers = xevent->xkey.state;
       
   832     (*env)->SetLongField(env, this, keysymFID, (jlong)keysym);
       
   833     (*env)->SetLongField(env, this, modifiersFID, (jlong)modifiers);
       
   834     (*env)->DeleteLocalRef(env, array);
       
   835     AWT_UNLOCK();
       
   836 }
       
   837 
       
   838 #ifdef __linux__
       
   839 void
       
   840 print_stack (void)
       
   841 {
       
   842   void *array[10];
       
   843   size_t size;
       
   844   char **strings;
       
   845   size_t i;
       
   846 
       
   847   size = backtrace (array, 10);
       
   848   strings = backtrace_symbols (array, size);
       
   849 
       
   850   fprintf (stderr, "Obtained %zd stack frames.\n", size);
       
   851 
       
   852   for (i = 0; i < size; i++)
       
   853      fprintf (stderr, "%s\n", strings[i]);
       
   854 
       
   855   free (strings);
       
   856 }
       
   857 #endif
       
   858 
       
   859 extern int32_t  numEventsHandled;
       
   860 
       
   861 XCreateWindowEvent cr;
       
   862 
       
   863 void
       
   864 dispatchEmbedderEvent(jobject server, XEvent * ev) {
       
   865     JNIEnv      *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   866     DASSERT(server != NULL);
       
   867     DASSERT(ev != NULL);
       
   868     AWT_LOCK();
       
   869 /*     MTRACE("dispatchEmebddedEvent\n"); */
       
   870     switch (ev->type) {
       
   871       case CreateNotify:
       
   872 
       
   873           MTRACEP3("CreateNotify for %x, serial %d, num events %d\n", (ev->xcreatewindow.window), (ev->xany.serial), (numEventsHandled));
       
   874           Java_sun_awt_motif_MEmbedCanvasPeer_embedChild(env, server, ev->xcreatewindow.window);
       
   875           break;
       
   876       case DestroyNotify:
       
   877           MTRACE("DestroyNotify\n");
       
   878           Java_sun_awt_motif_MEmbedCanvasPeer_childDestroyed(env, server);
       
   879           break;
       
   880       case ReparentNotify:
       
   881           MTRACEP2("ReparentNotify for %x, parent %x\n", (ev->xreparent.window), (ev->xreparent.parent));
       
   882           Java_sun_awt_motif_MEmbedCanvasPeer_embedChild(env, server, ev->xreparent.window);
       
   883           break;
       
   884       case ClientMessage:
       
   885           MTRACE("ClientMessage\n");
       
   886           handleClientMessage(env, server, &ev->xclient);
       
   887           break;
       
   888     }
       
   889     AWT_UNLOCK();
       
   890 }
       
   891 
       
   892 void
       
   893 dispatchEmbeddingClientEvent(XEvent * ev) {
       
   894     DASSERT(ev != NULL);
       
   895     MTRACE("dispatchEmbeddingClientEvent\n");
       
   896     switch (ev->type) {
       
   897       case PropertyNotify:
       
   898           handlePropertyNotify(&ev->xproperty);
       
   899           break;
       
   900       case ConfigureNotify:
       
   901           handleConfigureNotify(&ev->xconfigure);
       
   902           break;
       
   903     }
       
   904 }
       
   905 
       
   906 void
       
   907 xembed_serverEventHandler(XEvent * ev) {
       
   908     pxembed_server_data sdata;
       
   909     sdata = getData(ev->xany.window);
       
   910     if (sdata != NULL) { // Event on client
       
   911         dispatchEmbeddingClientEvent(ev);
       
   912     } else {
       
   913         sdata = getDataByServerHandle(ev->xany.window);
       
   914         if (sdata != NULL) {
       
   915             DASSERT(sdata->server != NULL);
       
   916             dispatchEmbedderEvent(sdata->server, ev);
       
   917         }
       
   918     }
       
   919 }
       
   920 
       
   921 /**************************** XEmbed server DnD support ***********************/
       
   922 void
       
   923 set_xembed_drop_target(JNIEnv* env, jobject server) {
       
   924 
       
   925     (*env)->CallVoidMethod(env, server, setXEmbedDropTargetMID);
       
   926 }
       
   927 
       
   928 void
       
   929 remove_xembed_drop_target(JNIEnv* env, jobject server) {
       
   930     (*env)->CallVoidMethod(env, server, removeXEmbedDropTargetMID);
       
   931 }
       
   932 
       
   933 Boolean
       
   934 is_xembed_client(Window window) {
       
   935     return getData(window) != NULL;
       
   936 }
       
   937 /******************************************************************************/
       
   938 
       
   939 /*
       
   940  * Class:     sun_awt_motif_MEmbedCanvasPeer
       
   941  * Method:    getWindow
       
   942  * Signature: ()V
       
   943  */
       
   944 JNIEXPORT jlong JNICALL
       
   945 Java_sun_awt_motif_MEmbedCanvasPeer_getWindow(JNIEnv *env, jobject this) {
       
   946     struct ComponentData *cdata;
       
   947     Window res = None;
       
   948     AWT_LOCK();
       
   949     cdata = (struct ComponentData *)
       
   950         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   951     DASSERT(cdata != NULL);
       
   952     res = XtWindow(cdata->widget);
       
   953     AWT_UNLOCK();
       
   954     return (jlong)res;
       
   955 }
       
   956 
       
   957 JNIEXPORT void JNICALL
       
   958 Java_sun_awt_motif_MEmbedCanvasPeer_forwardEventToEmbedded(JNIEnv *env,
       
   959                                                            jobject this,
       
   960                                                            jlong ctxt,
       
   961                                                            jint eventID){
       
   962     pxembed_server_data sdata;
       
   963     AWT_LOCK();
       
   964     sdata = getDataByEmbedder(this);
       
   965     if (sdata != NULL) {
       
   966         forward_event_to_embedded(sdata->handle, ctxt, eventID);
       
   967     }
       
   968     AWT_UNLOCK();
       
   969 }