< prev index next >

src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java

Print this page
rev 1571 : 8010297: Missing isLoggable() checks in logging code
Summary: Add isLoggable() checks
Reviewed-by: anthony, mchung, serb
Contributed-by: Laurent Bourges <bourges.laurent@gmail.com>


 105             applicationActive = toplevel.isFocused();
 106         }
 107     }
 108 
 109     void deinstallActivateListener() {
 110         Window toplevel = getTopLevel(target);
 111         if (toplevel != null) {
 112             toplevel.removeWindowFocusListener(this);
 113         }
 114     }
 115 
 116     boolean isXEmbedActive() {
 117         return xembed.handle != 0;
 118     }
 119 
 120     boolean isApplicationActive() {
 121         return applicationActive;
 122     }
 123 
 124     void initDispatching() {
 125         if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Init embedding for " + Long.toHexString(xembed.handle));


 126         XToolkit.awtLock();
 127         try {
 128             XToolkit.addEventDispatcher(xembed.handle, xembed);
 129             XlibWrapper.XSelectInput(XToolkit.getDisplay(), xembed.handle,
 130                                      XlibWrapper.StructureNotifyMask | XlibWrapper.PropertyChangeMask);
 131 
 132             XDropTargetRegistry.getRegistry().registerXEmbedClient(getWindow(), xembed.handle);
 133         } finally {
 134             XToolkit.awtUnlock();
 135         }
 136         xembed.processXEmbedInfo();
 137 
 138         notifyChildEmbedded();
 139     }
 140 
 141     void endDispatching() {

 142         xembedLog.fine("End dispatching for " + Long.toHexString(xembed.handle));

 143         XToolkit.awtLock();
 144         try {
 145             XDropTargetRegistry.getRegistry().unregisterXEmbedClient(getWindow(), xembed.handle);
 146             // We can't deselect input since someone else might be interested in it
 147             XToolkit.removeEventDispatcher(xembed.handle, xembed);
 148         } finally {
 149             XToolkit.awtUnlock();
 150         }
 151     }
 152 
 153     void embedChild(long child) {
 154         if (xembed.handle != 0) {
 155             detachChild();
 156         }
 157         xembed.handle = child;
 158         initDispatching();
 159     }
 160 
 161     void childDestroyed() {

 162         xembedLog.fine("Child " + Long.toHexString(xembed.handle) + " has self-destroyed.");

 163         endDispatching();
 164         xembed.handle = 0;
 165     }
 166 
 167     public void handleEvent(AWTEvent e) {
 168         super.handleEvent(e);
 169         if (isXEmbedActive()) {
 170             switch (e.getID()) {
 171               case FocusEvent.FOCUS_GAINED:
 172                   canvasFocusGained((FocusEvent)e);
 173                   break;
 174               case FocusEvent.FOCUS_LOST:
 175                   canvasFocusLost((FocusEvent)e);
 176                   break;
 177               case KeyEvent.KEY_PRESSED:
 178               case KeyEvent.KEY_RELEASED:
 179                   if (!((InputEvent)e).isConsumed()) {
 180                       forwardKeyEvent((KeyEvent)e);
 181                   }
 182                   break;


 301                 XToolkit.RESTORE_XERROR_HANDLER();
 302 
 303                 if (status == 0 ||
 304                     (XToolkit.saved_error != null &&
 305                      XToolkit.saved_error.get_error_code() != XlibWrapper.Success)) {
 306                     return null;
 307                 }
 308 
 309                 return new Rectangle(wattr.get_x(), wattr.get_y(), wattr.get_width(), wattr.get_height());
 310             } finally {
 311                 wattr.dispose();
 312             }
 313         } finally {
 314             XToolkit.awtUnlock();
 315         }
 316     }
 317 
 318     void childResized() {
 319         if (xembedLog.isLoggable(Level.FINER)) {
 320             Rectangle bounds = getClientBounds();

 321             xembedLog.finer("Child resized: " + bounds);

 322             // It is not required to update embedder's size when client size changes
 323             // However, since there is no any means to get client size it seems to be the
 324             // only way to provide it. However, it contradicts with Java layout concept -
 325             // so it is disabled for now.
 326 //             Rectangle my_bounds = getBounds();
 327 //             setBounds(my_bounds.x, my_bounds.y, bounds.width, bounds.height, SET_BOUNDS);
 328         }
 329         XToolkit.postEvent(XToolkit.targetToAppContext(target), new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
 330     }
 331 
 332     void focusNext() {
 333         if (isXEmbedActive()) {
 334             xembedLog.fine("Requesting focus for the next component after embedder");
 335             postEvent(new InvocationEvent(target, new Runnable() {
 336                     public void run() {
 337                         KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(target);
 338                     }
 339                 }));
 340         } else {
 341             xembedLog.fine("XEmbed is not active - denying focus next");


 364                     }
 365                 }));
 366         } else {
 367             xembedLog.fine("XEmbed is not active - denying request focus");
 368         }
 369     }
 370 
 371     void notifyChildEmbedded() {
 372         xembed.sendMessage(xembed.handle, XEMBED_EMBEDDED_NOTIFY, getWindow(), Math.min(xembed.version, XEMBED_VERSION), 0);
 373         if (isApplicationActive()) {
 374             xembedLog.fine("Sending WINDOW_ACTIVATE during initialization");
 375             xembed.sendMessage(xembed.handle, XEMBED_WINDOW_ACTIVATE);
 376             if (hasFocus()) {
 377                 xembedLog.fine("Sending FOCUS_GAINED during initialization");
 378                 xembed.sendMessage(xembed.handle, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0);
 379             }
 380         }
 381     }
 382 
 383     void detachChild() {
 384         if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Detaching child " + Long.toHexString(xembed.handle));


 385         /**
 386          *  XEmbed specification:
 387          *  "The embedder can unmap the client and reparent the client window to the root window. If the
 388          *  client receives an ReparentNotify event, it should check the parent field of the XReparentEvent
 389          *  structure. If this is the root window of the window's screen, then the protocol is finished and
 390          *  there is no further interaction. If it is a window other than the root window, then the protocol
 391          *  continues with the new parent acting as the embedder window."
 392          */
 393         XToolkit.awtLock();
 394         try {
 395             XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), xembed.handle);
 396             XlibWrapper.XReparentWindow(XToolkit.getDisplay(), xembed.handle, XToolkit.getDefaultRootWindow(), 0, 0);
 397         } finally {
 398             XToolkit.awtUnlock();
 399         }
 400         endDispatching();
 401         xembed.handle = 0;
 402     }
 403 
 404     public void windowGainedFocus(WindowEvent e) {


 445                 }
 446             }
 447             xembed.sendMessage(xembed.handle, XEMBED_FOCUS_OUT, num, 0, 0);
 448         }
 449     }
 450 
 451     static byte[] getBData(KeyEvent e) {
 452         return AWTAccessor.getAWTEventAccessor().getBData(e);
 453     }
 454 
 455     void forwardKeyEvent(KeyEvent e) {
 456         xembedLog.fine("Try to forward key event");
 457         byte[] bdata = getBData(e);
 458         long data = Native.toData(bdata);
 459         if (data == 0) {
 460             return;
 461         }
 462         try {
 463             XKeyEvent ke = new XKeyEvent(data);
 464             ke.set_window(xembed.handle);
 465             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Forwarding native key event: " + ke);


 466             XToolkit.awtLock();
 467             try {
 468                 XlibWrapper.XSendEvent(XToolkit.getDisplay(), xembed.handle, false, XlibWrapper.NoEventMask, data);
 469             } finally {
 470                 XToolkit.awtUnlock();
 471             }
 472         } finally {
 473             XlibWrapper.unsafe.freeMemory(data);
 474         }
 475     }
 476 
 477 
 478     /**
 479      * Grab/ungrab key functionality is an unofficial API supported by
 480      * GTK.  Unfortunately, it doesn't support accelerator API, so,
 481      * since this is the ONLY shortcut-processing API available, we
 482      * must support it.  See XEmbed.NON_STANDARD_XEMBED_GTK_*
 483      * messages.  The format of these messages is as follows:
 484      * - request from client:
 485      * data[1] = NON_STANDARD_XEMBED_GTK_GRAB_KEY or NON_STANDARD_XEMBED_GTK_UNGRAB_KEY
 486      * data[3] = X keysym
 487      * data[4] = X modifiers
 488      *
 489      * - response from server (in case the grabbed key has been pressed):
 490      * forwarded XKeyEvent that matches keysym/modifiers pair
 491      */
 492     void grabKey(final long keysym, final long modifiers) {
 493         postEvent(new InvocationEvent(target, new Runnable() {
 494                 public void run() {
 495                     GrabbedKey grab = new GrabbedKey(keysym, modifiers);
 496                     if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Grabbing key: " + grab);


 497                     synchronized(GRAB_LOCK) {
 498                         grabbed_keys.add(grab);
 499                     }
 500                 }
 501             }));
 502     }
 503 
 504     void ungrabKey(final long keysym, final long modifiers) {
 505         postEvent(new InvocationEvent(target, new Runnable() {
 506                 public void run() {
 507                     GrabbedKey grab = new GrabbedKey(keysym, modifiers);
 508                     if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("UnGrabbing key: " + grab);


 509                     synchronized(GRAB_LOCK) {
 510                         grabbed_keys.remove(grab);
 511                     }
 512                 }
 513             }));
 514     }
 515 
 516     void registerAccelerator(final long accel_id, final long keysym, final long modifiers) {
 517         postEvent(new InvocationEvent(target, new Runnable() {
 518                 public void run() {
 519                     AWTKeyStroke stroke = xembed.getKeyStrokeForKeySym(keysym, modifiers);
 520                     if (stroke != null) {
 521                         if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Registering accelerator " + accel_id + " for " + stroke);


 522                         synchronized(ACCEL_LOCK) {
 523                             accelerators.put(accel_id, stroke);
 524                             accel_lookup.put(stroke, accel_id);
 525                         }
 526                     }
 527                     propogateRegisterAccelerator(stroke);
 528                 }
 529             }));
 530     }
 531 
 532     void unregisterAccelerator(final long accel_id) {
 533         postEvent(new InvocationEvent(target, new Runnable() {
 534                 public void run() {
 535                     AWTKeyStroke stroke = null;
 536                     synchronized(ACCEL_LOCK) {
 537                         stroke = accelerators.get(accel_id);
 538                         if (stroke != null) {
 539                             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Unregistering accelerator: " + accel_id);


 540                             accelerators.remove(accel_id);
 541                             accel_lookup.remove(stroke); // FIXME: How about several accelerators with the same stroke?
 542                         }
 543                     }
 544                     propogateUnRegisterAccelerator(stroke);
 545                 }
 546             }));
 547     }
 548 
 549     void propogateRegisterAccelerator(AWTKeyStroke stroke) {
 550         // Find the top-level and see if it is XEmbed client. If so, ask him to
 551         // register the accelerator
 552         XWindowPeer parent = getToplevelXWindow();
 553         if (parent != null && parent instanceof XEmbeddedFramePeer) {
 554             XEmbeddedFramePeer embedded = (XEmbeddedFramePeer)parent;
 555             embedded.registerAccelerator(stroke);
 556         }
 557     }
 558 
 559     void propogateUnRegisterAccelerator(AWTKeyStroke stroke) {


 565             embedded.unregisterAccelerator(stroke);
 566         }
 567     }
 568 
 569     public boolean postProcessKeyEvent(KeyEvent e) {
 570         // Processing events only if we are in the focused window but
 571         // we are not focus owner since otherwise we will get
 572         // duplicate shortcut events in the client - one is from
 573         // activate_accelerator, another from forwarded event
 574         // FIXME: This is probably an incompatibility, protocol
 575         // doesn't say anything about disable accelerators when client
 576         // is focused.
 577 
 578         XWindowPeer parent = getToplevelXWindow();
 579         if (parent == null || !((Window)parent.getTarget()).isFocused() || target.isFocusOwner()) {
 580             return false;
 581         }
 582 
 583         boolean result = false;
 584 
 585         if (xembedLog.isLoggable(Level.FINER)) xembedLog.finer("Post-processing event " + e);


 586 
 587         // Process ACCELERATORS
 588         AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
 589         long accel_id = 0;
 590         boolean exists = false;
 591         synchronized(ACCEL_LOCK) {
 592             exists = accel_lookup.containsKey(stroke);
 593             if (exists) {
 594                 accel_id = accel_lookup.get(stroke).longValue();
 595             }
 596         }
 597         if (exists) {
 598             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Activating accelerator " + accel_id);


 599             xembed.sendMessage(xembed.handle, XEMBED_ACTIVATE_ACCELERATOR, accel_id, 0, 0); // FIXME: How about overloaded?
 600             result = true;
 601         }
 602 
 603         // Process Grabs, unofficial GTK feature
 604         exists = false;
 605         GrabbedKey key = new GrabbedKey(e);
 606         synchronized(GRAB_LOCK) {
 607             exists = grabbed_keys.contains(key);
 608         }
 609         if (exists) {
 610             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Forwarding grabbed key " + e);


 611             forwardKeyEvent(e);
 612             result = true;
 613         }
 614 
 615         return result;
 616     }
 617 
 618     public void modalityPushed(ModalityEvent ev) {
 619         xembed.sendMessage(xembed.handle, XEMBED_MODALITY_ON);
 620     }
 621 
 622     public void modalityPopped(ModalityEvent ev) {
 623         xembed.sendMessage(xembed.handle, XEMBED_MODALITY_OFF);
 624     }
 625 
 626     public void handleClientMessage(XEvent xev) {
 627         super.handleClientMessage(xev);
 628         XClientMessageEvent msg = xev.get_xclient();
 629         if (xembedLog.isLoggable(Level.FINER)) xembedLog.finer("Client message to embedder: " + msg);


 630         if (msg.get_message_type() == xembed.XEmbed.getAtom()) {
 631             if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine(xembed.XEmbedMessageToString(msg));


 632         }
 633         if (isXEmbedActive()) {
 634             switch ((int)msg.get_data(1)) {
 635               case _SUN_XEMBED_START:
 636                   // Child has finished initialization and waits for notify
 637                   xembed.processXEmbedInfo();
 638 
 639                   notifyChildEmbedded();
 640                   break;
 641               case XEMBED_REQUEST_FOCUS:
 642                   requestXEmbedFocus();
 643                   break;
 644               case XEMBED_FOCUS_NEXT:
 645                   focusNext();
 646                   break;
 647               case XEMBED_FOCUS_PREV:
 648                   focusPrev();
 649                   break;
 650               case XEMBED_REGISTER_ACCELERATOR:
 651                   registerAccelerator(msg.get_data(2), msg.get_data(3), msg.get_data(4));


 718         long handle; // Handle to XEmbed client
 719         long version;
 720         long flags;
 721 
 722         boolean processXEmbedInfo() {
 723             long xembed_info_data = Native.allocateLongArray(2);
 724             try {
 725                 if (!XEmbedInfo.getAtomData(handle, xembed_info_data, 2)) {
 726                     // No more XEMBED_INFO? This is not XEmbed client!
 727                     // Unfortunately this is the initial state of the most clients
 728                     // FIXME: add 5-state processing
 729                     //childDestroyed();
 730                     xembedLog.finer("Unable to get XEMBED_INFO atom data");
 731                     return false;
 732                 }
 733                 version = Native.getCard32(xembed_info_data, 0);
 734                 flags = Native.getCard32(xembed_info_data, 1);
 735                 boolean new_mapped = (flags & XEMBED_MAPPED) != 0;
 736                 boolean currently_mapped = XlibUtil.getWindowMapState(handle) != XlibWrapper.IsUnmapped;
 737                 if (new_mapped != currently_mapped) {
 738                     if (xembedLog.isLoggable(Level.FINER))
 739                         xembedLog.fine("Mapping state of the client has changed, old state: " + currently_mapped + ", new state: " + new_mapped);

 740                     if (new_mapped) {
 741                         XToolkit.awtLock();
 742                         try {
 743                             XlibWrapper.XMapWindow(XToolkit.getDisplay(), handle);
 744                         } finally {
 745                             XToolkit.awtUnlock();
 746                         }
 747                     } else {
 748                         XToolkit.awtLock();
 749                         try {
 750                             XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), handle);
 751                         } finally {
 752                             XToolkit.awtUnlock();
 753                         }
 754                     }
 755                 } else {

 756                     xembedLog.finer("Mapping state didn't change, mapped: " + currently_mapped);
 757                 }

 758                 return true;
 759             } finally {
 760                 XlibWrapper.unsafe.freeMemory(xembed_info_data);
 761             }
 762         }
 763 
 764         public void handlePropertyNotify(XEvent xev) {
 765             if (isXEmbedActive()) {
 766                 XPropertyEvent ev = xev.get_xproperty();
 767                 if (xembedLog.isLoggable(Level.FINER)) xembedLog.finer("Property change on client: " + ev);


 768                 if (ev.get_atom() == XAtom.XA_WM_NORMAL_HINTS) {
 769                     childResized();
 770                 } else if (ev.get_atom() == XEmbedInfo.getAtom()) {
 771                     processXEmbedInfo();
 772                 } else if (ev.get_atom() ==
 773                            XDnDConstants.XA_XdndAware.getAtom()) {
 774                     XDropTargetRegistry.getRegistry().unregisterXEmbedClient(getWindow(),
 775                                                                              xembed.handle);
 776                     if (ev.get_state() == XConstants.PropertyNewValue) {
 777                         XDropTargetRegistry.getRegistry().registerXEmbedClient(getWindow(),
 778                                                                                 xembed.handle);
 779                     }
 780                 }
 781             } else {
 782                 xembedLog.finer("XEmbed is not active");
 783             }
 784         }
 785         void handleConfigureNotify(XEvent xev) {
 786             if (isXEmbedActive()) {
 787                 XConfigureEvent ev = xev.get_xconfigure();
 788                 if (xembedLog.isLoggable(Level.FINER)) xembedLog.finer("Bounds change on client: " + ev);


 789                 if (xev.get_xany().get_window() == handle) {
 790                     childResized();
 791                 }
 792             }
 793         }
 794         public void dispatchEvent(XEvent xev) {
 795             int type = xev.get_type();
 796             switch (type) {
 797               case PropertyNotify:
 798                   handlePropertyNotify(xev);
 799                   break;
 800               case ConfigureNotify:
 801                   handleConfigureNotify(xev);
 802                   break;
 803               case ClientMessage:
 804                   handleClientMessage(xev);
 805                   break;
 806             }
 807         }
 808     }


 819             init(ev);
 820         }
 821 
 822         private void init(KeyEvent e) {
 823             byte[] bdata = getBData(e);
 824             long data = Native.toData(bdata);
 825             if (data == 0) {
 826                 return;
 827             }
 828             try {
 829                 XToolkit.awtLock();
 830                 try {
 831                     keysym = XWindow.getKeySymForAWTKeyCode(e.getKeyCode());
 832                 } finally {
 833                     XToolkit.awtUnlock();
 834                 }
 835                 XKeyEvent ke = new XKeyEvent(data);
 836 
 837                 // We recognize only these masks
 838                 modifiers = ke.get_state() & (ShiftMask | ControlMask | LockMask);
 839                 if (xembedLog.isLoggable(Level.FINEST)) xembedLog.finest("Mapped " + e + " to " + this);


 840             } finally {
 841                 XlibWrapper.unsafe.freeMemory(data);
 842             }
 843         }
 844 
 845         public int hashCode() {
 846             return (int)keysym & 0xFFFFFFFF;
 847         }
 848 
 849         public boolean equals(Object o) {
 850             if (!(o instanceof GrabbedKey)) {
 851                 return false;
 852             }
 853             GrabbedKey key = (GrabbedKey)o;
 854             return (keysym == key.keysym && modifiers == key.modifiers);
 855         }
 856 
 857         public String toString() {
 858             return "Key combination[keysym=" + keysym + ", mods=" + modifiers + "]";
 859         }


 105             applicationActive = toplevel.isFocused();
 106         }
 107     }
 108 
 109     void deinstallActivateListener() {
 110         Window toplevel = getTopLevel(target);
 111         if (toplevel != null) {
 112             toplevel.removeWindowFocusListener(this);
 113         }
 114     }
 115 
 116     boolean isXEmbedActive() {
 117         return xembed.handle != 0;
 118     }
 119 
 120     boolean isApplicationActive() {
 121         return applicationActive;
 122     }
 123 
 124     void initDispatching() {
 125         if (xembedLog.isLoggable(Level.FINE)) {
 126             xembedLog.fine("Init embedding for " + Long.toHexString(xembed.handle));
 127         }
 128         XToolkit.awtLock();
 129         try {
 130             XToolkit.addEventDispatcher(xembed.handle, xembed);
 131             XlibWrapper.XSelectInput(XToolkit.getDisplay(), xembed.handle,
 132                                      XlibWrapper.StructureNotifyMask | XlibWrapper.PropertyChangeMask);
 133 
 134             XDropTargetRegistry.getRegistry().registerXEmbedClient(getWindow(), xembed.handle);
 135         } finally {
 136             XToolkit.awtUnlock();
 137         }
 138         xembed.processXEmbedInfo();
 139 
 140         notifyChildEmbedded();
 141     }
 142 
 143     void endDispatching() {
 144         if (xembedLog.isLoggable(Level.FINE)) {
 145             xembedLog.fine("End dispatching for " + Long.toHexString(xembed.handle));
 146         }
 147         XToolkit.awtLock();
 148         try {
 149             XDropTargetRegistry.getRegistry().unregisterXEmbedClient(getWindow(), xembed.handle);
 150             // We can't deselect input since someone else might be interested in it
 151             XToolkit.removeEventDispatcher(xembed.handle, xembed);
 152         } finally {
 153             XToolkit.awtUnlock();
 154         }
 155     }
 156 
 157     void embedChild(long child) {
 158         if (xembed.handle != 0) {
 159             detachChild();
 160         }
 161         xembed.handle = child;
 162         initDispatching();
 163     }
 164 
 165     void childDestroyed() {
 166         if (xembedLog.isLoggable(Level.FINE)) {
 167             xembedLog.fine("Child " + Long.toHexString(xembed.handle) + " has self-destroyed.");
 168         }
 169         endDispatching();
 170         xembed.handle = 0;
 171     }
 172 
 173     public void handleEvent(AWTEvent e) {
 174         super.handleEvent(e);
 175         if (isXEmbedActive()) {
 176             switch (e.getID()) {
 177               case FocusEvent.FOCUS_GAINED:
 178                   canvasFocusGained((FocusEvent)e);
 179                   break;
 180               case FocusEvent.FOCUS_LOST:
 181                   canvasFocusLost((FocusEvent)e);
 182                   break;
 183               case KeyEvent.KEY_PRESSED:
 184               case KeyEvent.KEY_RELEASED:
 185                   if (!((InputEvent)e).isConsumed()) {
 186                       forwardKeyEvent((KeyEvent)e);
 187                   }
 188                   break;


 307                 XToolkit.RESTORE_XERROR_HANDLER();
 308 
 309                 if (status == 0 ||
 310                     (XToolkit.saved_error != null &&
 311                      XToolkit.saved_error.get_error_code() != XlibWrapper.Success)) {
 312                     return null;
 313                 }
 314 
 315                 return new Rectangle(wattr.get_x(), wattr.get_y(), wattr.get_width(), wattr.get_height());
 316             } finally {
 317                 wattr.dispose();
 318             }
 319         } finally {
 320             XToolkit.awtUnlock();
 321         }
 322     }
 323 
 324     void childResized() {
 325         if (xembedLog.isLoggable(Level.FINER)) {
 326             Rectangle bounds = getClientBounds();
 327             if (xembedLog.isLoggable(Level.FINER)) {
 328                 xembedLog.finer("Child resized: " + bounds);
 329             }
 330             // It is not required to update embedder's size when client size changes
 331             // However, since there is no any means to get client size it seems to be the
 332             // only way to provide it. However, it contradicts with Java layout concept -
 333             // so it is disabled for now.
 334 //             Rectangle my_bounds = getBounds();
 335 //             setBounds(my_bounds.x, my_bounds.y, bounds.width, bounds.height, SET_BOUNDS);
 336         }
 337         XToolkit.postEvent(XToolkit.targetToAppContext(target), new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
 338     }
 339 
 340     void focusNext() {
 341         if (isXEmbedActive()) {
 342             xembedLog.fine("Requesting focus for the next component after embedder");
 343             postEvent(new InvocationEvent(target, new Runnable() {
 344                     public void run() {
 345                         KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(target);
 346                     }
 347                 }));
 348         } else {
 349             xembedLog.fine("XEmbed is not active - denying focus next");


 372                     }
 373                 }));
 374         } else {
 375             xembedLog.fine("XEmbed is not active - denying request focus");
 376         }
 377     }
 378 
 379     void notifyChildEmbedded() {
 380         xembed.sendMessage(xembed.handle, XEMBED_EMBEDDED_NOTIFY, getWindow(), Math.min(xembed.version, XEMBED_VERSION), 0);
 381         if (isApplicationActive()) {
 382             xembedLog.fine("Sending WINDOW_ACTIVATE during initialization");
 383             xembed.sendMessage(xembed.handle, XEMBED_WINDOW_ACTIVATE);
 384             if (hasFocus()) {
 385                 xembedLog.fine("Sending FOCUS_GAINED during initialization");
 386                 xembed.sendMessage(xembed.handle, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0);
 387             }
 388         }
 389     }
 390 
 391     void detachChild() {
 392         if (xembedLog.isLoggable(Level.FINE)) {
 393             xembedLog.fine("Detaching child " + Long.toHexString(xembed.handle));
 394         }
 395         /**
 396          *  XEmbed specification:
 397          *  "The embedder can unmap the client and reparent the client window to the root window. If the
 398          *  client receives an ReparentNotify event, it should check the parent field of the XReparentEvent
 399          *  structure. If this is the root window of the window's screen, then the protocol is finished and
 400          *  there is no further interaction. If it is a window other than the root window, then the protocol
 401          *  continues with the new parent acting as the embedder window."
 402          */
 403         XToolkit.awtLock();
 404         try {
 405             XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), xembed.handle);
 406             XlibWrapper.XReparentWindow(XToolkit.getDisplay(), xembed.handle, XToolkit.getDefaultRootWindow(), 0, 0);
 407         } finally {
 408             XToolkit.awtUnlock();
 409         }
 410         endDispatching();
 411         xembed.handle = 0;
 412     }
 413 
 414     public void windowGainedFocus(WindowEvent e) {


 455                 }
 456             }
 457             xembed.sendMessage(xembed.handle, XEMBED_FOCUS_OUT, num, 0, 0);
 458         }
 459     }
 460 
 461     static byte[] getBData(KeyEvent e) {
 462         return AWTAccessor.getAWTEventAccessor().getBData(e);
 463     }
 464 
 465     void forwardKeyEvent(KeyEvent e) {
 466         xembedLog.fine("Try to forward key event");
 467         byte[] bdata = getBData(e);
 468         long data = Native.toData(bdata);
 469         if (data == 0) {
 470             return;
 471         }
 472         try {
 473             XKeyEvent ke = new XKeyEvent(data);
 474             ke.set_window(xembed.handle);
 475             if (xembedLog.isLoggable(Level.FINE)) {
 476                 xembedLog.fine("Forwarding native key event: " + ke);
 477             }
 478             XToolkit.awtLock();
 479             try {
 480                 XlibWrapper.XSendEvent(XToolkit.getDisplay(), xembed.handle, false, XlibWrapper.NoEventMask, data);
 481             } finally {
 482                 XToolkit.awtUnlock();
 483             }
 484         } finally {
 485             XlibWrapper.unsafe.freeMemory(data);
 486         }
 487     }
 488 
 489 
 490     /**
 491      * Grab/ungrab key functionality is an unofficial API supported by
 492      * GTK.  Unfortunately, it doesn't support accelerator API, so,
 493      * since this is the ONLY shortcut-processing API available, we
 494      * must support it.  See XEmbed.NON_STANDARD_XEMBED_GTK_*
 495      * messages.  The format of these messages is as follows:
 496      * - request from client:
 497      * data[1] = NON_STANDARD_XEMBED_GTK_GRAB_KEY or NON_STANDARD_XEMBED_GTK_UNGRAB_KEY
 498      * data[3] = X keysym
 499      * data[4] = X modifiers
 500      *
 501      * - response from server (in case the grabbed key has been pressed):
 502      * forwarded XKeyEvent that matches keysym/modifiers pair
 503      */
 504     void grabKey(final long keysym, final long modifiers) {
 505         postEvent(new InvocationEvent(target, new Runnable() {
 506                 public void run() {
 507                     GrabbedKey grab = new GrabbedKey(keysym, modifiers);
 508                     if (xembedLog.isLoggable(Level.FINE)) {
 509                         xembedLog.fine("Grabbing key: " + grab);
 510                     }
 511                     synchronized(GRAB_LOCK) {
 512                         grabbed_keys.add(grab);
 513                     }
 514                 }
 515             }));
 516     }
 517 
 518     void ungrabKey(final long keysym, final long modifiers) {
 519         postEvent(new InvocationEvent(target, new Runnable() {
 520                 public void run() {
 521                     GrabbedKey grab = new GrabbedKey(keysym, modifiers);
 522                     if (xembedLog.isLoggable(Level.FINE)) {
 523                         xembedLog.fine("UnGrabbing key: " + grab);
 524                     }
 525                     synchronized(GRAB_LOCK) {
 526                         grabbed_keys.remove(grab);
 527                     }
 528                 }
 529             }));
 530     }
 531 
 532     void registerAccelerator(final long accel_id, final long keysym, final long modifiers) {
 533         postEvent(new InvocationEvent(target, new Runnable() {
 534                 public void run() {
 535                     AWTKeyStroke stroke = xembed.getKeyStrokeForKeySym(keysym, modifiers);
 536                     if (stroke != null) {
 537                         if (xembedLog.isLoggable(Level.FINE)) {
 538                             xembedLog.fine("Registering accelerator " + accel_id + " for " + stroke);
 539                         }
 540                         synchronized(ACCEL_LOCK) {
 541                             accelerators.put(accel_id, stroke);
 542                             accel_lookup.put(stroke, accel_id);
 543                         }
 544                     }
 545                     propogateRegisterAccelerator(stroke);
 546                 }
 547             }));
 548     }
 549 
 550     void unregisterAccelerator(final long accel_id) {
 551         postEvent(new InvocationEvent(target, new Runnable() {
 552                 public void run() {
 553                     AWTKeyStroke stroke = null;
 554                     synchronized(ACCEL_LOCK) {
 555                         stroke = accelerators.get(accel_id);
 556                         if (stroke != null) {
 557                             if (xembedLog.isLoggable(Level.FINE)) {
 558                                 xembedLog.fine("Unregistering accelerator: " + accel_id);
 559                             }
 560                             accelerators.remove(accel_id);
 561                             accel_lookup.remove(stroke); // FIXME: How about several accelerators with the same stroke?
 562                         }
 563                     }
 564                     propogateUnRegisterAccelerator(stroke);
 565                 }
 566             }));
 567     }
 568 
 569     void propogateRegisterAccelerator(AWTKeyStroke stroke) {
 570         // Find the top-level and see if it is XEmbed client. If so, ask him to
 571         // register the accelerator
 572         XWindowPeer parent = getToplevelXWindow();
 573         if (parent != null && parent instanceof XEmbeddedFramePeer) {
 574             XEmbeddedFramePeer embedded = (XEmbeddedFramePeer)parent;
 575             embedded.registerAccelerator(stroke);
 576         }
 577     }
 578 
 579     void propogateUnRegisterAccelerator(AWTKeyStroke stroke) {


 585             embedded.unregisterAccelerator(stroke);
 586         }
 587     }
 588 
 589     public boolean postProcessKeyEvent(KeyEvent e) {
 590         // Processing events only if we are in the focused window but
 591         // we are not focus owner since otherwise we will get
 592         // duplicate shortcut events in the client - one is from
 593         // activate_accelerator, another from forwarded event
 594         // FIXME: This is probably an incompatibility, protocol
 595         // doesn't say anything about disable accelerators when client
 596         // is focused.
 597 
 598         XWindowPeer parent = getToplevelXWindow();
 599         if (parent == null || !((Window)parent.getTarget()).isFocused() || target.isFocusOwner()) {
 600             return false;
 601         }
 602 
 603         boolean result = false;
 604 
 605         if (xembedLog.isLoggable(Level.FINER)) {
 606             xembedLog.finer("Post-processing event " + e);
 607         }
 608 
 609         // Process ACCELERATORS
 610         AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
 611         long accel_id = 0;
 612         boolean exists = false;
 613         synchronized(ACCEL_LOCK) {
 614             exists = accel_lookup.containsKey(stroke);
 615             if (exists) {
 616                 accel_id = accel_lookup.get(stroke).longValue();
 617             }
 618         }
 619         if (exists) {
 620             if (xembedLog.isLoggable(Level.FINE)) {
 621                 xembedLog.fine("Activating accelerator " + accel_id);
 622             }
 623             xembed.sendMessage(xembed.handle, XEMBED_ACTIVATE_ACCELERATOR, accel_id, 0, 0); // FIXME: How about overloaded?
 624             result = true;
 625         }
 626 
 627         // Process Grabs, unofficial GTK feature
 628         exists = false;
 629         GrabbedKey key = new GrabbedKey(e);
 630         synchronized(GRAB_LOCK) {
 631             exists = grabbed_keys.contains(key);
 632         }
 633         if (exists) {
 634             if (xembedLog.isLoggable(Level.FINE)) {
 635                 xembedLog.fine("Forwarding grabbed key " + e);
 636             }
 637             forwardKeyEvent(e);
 638             result = true;
 639         }
 640 
 641         return result;
 642     }
 643 
 644     public void modalityPushed(ModalityEvent ev) {
 645         xembed.sendMessage(xembed.handle, XEMBED_MODALITY_ON);
 646     }
 647 
 648     public void modalityPopped(ModalityEvent ev) {
 649         xembed.sendMessage(xembed.handle, XEMBED_MODALITY_OFF);
 650     }
 651 
 652     public void handleClientMessage(XEvent xev) {
 653         super.handleClientMessage(xev);
 654         XClientMessageEvent msg = xev.get_xclient();
 655         if (xembedLog.isLoggable(Level.FINER)) {
 656             xembedLog.finer("Client message to embedder: " + msg);
 657         }
 658         if (msg.get_message_type() == xembed.XEmbed.getAtom()) {
 659             if (xembedLog.isLoggable(Level.FINE)) {
 660                 xembedLog.fine(xembed.XEmbedMessageToString(msg));
 661             }
 662         }
 663         if (isXEmbedActive()) {
 664             switch ((int)msg.get_data(1)) {
 665               case _SUN_XEMBED_START:
 666                   // Child has finished initialization and waits for notify
 667                   xembed.processXEmbedInfo();
 668 
 669                   notifyChildEmbedded();
 670                   break;
 671               case XEMBED_REQUEST_FOCUS:
 672                   requestXEmbedFocus();
 673                   break;
 674               case XEMBED_FOCUS_NEXT:
 675                   focusNext();
 676                   break;
 677               case XEMBED_FOCUS_PREV:
 678                   focusPrev();
 679                   break;
 680               case XEMBED_REGISTER_ACCELERATOR:
 681                   registerAccelerator(msg.get_data(2), msg.get_data(3), msg.get_data(4));


 748         long handle; // Handle to XEmbed client
 749         long version;
 750         long flags;
 751 
 752         boolean processXEmbedInfo() {
 753             long xembed_info_data = Native.allocateLongArray(2);
 754             try {
 755                 if (!XEmbedInfo.getAtomData(handle, xembed_info_data, 2)) {
 756                     // No more XEMBED_INFO? This is not XEmbed client!
 757                     // Unfortunately this is the initial state of the most clients
 758                     // FIXME: add 5-state processing
 759                     //childDestroyed();
 760                     xembedLog.finer("Unable to get XEMBED_INFO atom data");
 761                     return false;
 762                 }
 763                 version = Native.getCard32(xembed_info_data, 0);
 764                 flags = Native.getCard32(xembed_info_data, 1);
 765                 boolean new_mapped = (flags & XEMBED_MAPPED) != 0;
 766                 boolean currently_mapped = XlibUtil.getWindowMapState(handle) != XlibWrapper.IsUnmapped;
 767                 if (new_mapped != currently_mapped) {
 768                     if (xembedLog.isLoggable(Level.FINER)) {
 769                         xembedLog.fine("Mapping state of the client has changed, old state: " + currently_mapped + ", new state: " + new_mapped);
 770                     }
 771                     if (new_mapped) {
 772                         XToolkit.awtLock();
 773                         try {
 774                             XlibWrapper.XMapWindow(XToolkit.getDisplay(), handle);
 775                         } finally {
 776                             XToolkit.awtUnlock();
 777                         }
 778                     } else {
 779                         XToolkit.awtLock();
 780                         try {
 781                             XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), handle);
 782                         } finally {
 783                             XToolkit.awtUnlock();
 784                         }
 785                     }
 786                 } else {
 787                     if (xembedLog.isLoggable(Level.FINER)) {
 788                         xembedLog.finer("Mapping state didn't change, mapped: " + currently_mapped);
 789                     }
 790                 }
 791                 return true;
 792             } finally {
 793                 XlibWrapper.unsafe.freeMemory(xembed_info_data);
 794             }
 795         }
 796 
 797         public void handlePropertyNotify(XEvent xev) {
 798             if (isXEmbedActive()) {
 799                 XPropertyEvent ev = xev.get_xproperty();
 800                 if (xembedLog.isLoggable(Level.FINER)) {
 801                     xembedLog.finer("Property change on client: " + ev);
 802                 }
 803                 if (ev.get_atom() == XAtom.XA_WM_NORMAL_HINTS) {
 804                     childResized();
 805                 } else if (ev.get_atom() == XEmbedInfo.getAtom()) {
 806                     processXEmbedInfo();
 807                 } else if (ev.get_atom() ==
 808                            XDnDConstants.XA_XdndAware.getAtom()) {
 809                     XDropTargetRegistry.getRegistry().unregisterXEmbedClient(getWindow(),
 810                                                                              xembed.handle);
 811                     if (ev.get_state() == XConstants.PropertyNewValue) {
 812                         XDropTargetRegistry.getRegistry().registerXEmbedClient(getWindow(),
 813                                                                                 xembed.handle);
 814                     }
 815                 }
 816             } else {
 817                 xembedLog.finer("XEmbed is not active");
 818             }
 819         }
 820         void handleConfigureNotify(XEvent xev) {
 821             if (isXEmbedActive()) {
 822                 XConfigureEvent ev = xev.get_xconfigure();
 823                 if (xembedLog.isLoggable(Level.FINER)) {
 824                     xembedLog.finer("Bounds change on client: " + ev);
 825                 }
 826                 if (xev.get_xany().get_window() == handle) {
 827                     childResized();
 828                 }
 829             }
 830         }
 831         public void dispatchEvent(XEvent xev) {
 832             int type = xev.get_type();
 833             switch (type) {
 834               case PropertyNotify:
 835                   handlePropertyNotify(xev);
 836                   break;
 837               case ConfigureNotify:
 838                   handleConfigureNotify(xev);
 839                   break;
 840               case ClientMessage:
 841                   handleClientMessage(xev);
 842                   break;
 843             }
 844         }
 845     }


 856             init(ev);
 857         }
 858 
 859         private void init(KeyEvent e) {
 860             byte[] bdata = getBData(e);
 861             long data = Native.toData(bdata);
 862             if (data == 0) {
 863                 return;
 864             }
 865             try {
 866                 XToolkit.awtLock();
 867                 try {
 868                     keysym = XWindow.getKeySymForAWTKeyCode(e.getKeyCode());
 869                 } finally {
 870                     XToolkit.awtUnlock();
 871                 }
 872                 XKeyEvent ke = new XKeyEvent(data);
 873 
 874                 // We recognize only these masks
 875                 modifiers = ke.get_state() & (ShiftMask | ControlMask | LockMask);
 876                 if (xembedLog.isLoggable(Level.FINEST)) {
 877                     xembedLog.finest("Mapped " + e + " to " + this);
 878                 }
 879             } finally {
 880                 XlibWrapper.unsafe.freeMemory(data);
 881             }
 882         }
 883 
 884         public int hashCode() {
 885             return (int)keysym & 0xFFFFFFFF;
 886         }
 887 
 888         public boolean equals(Object o) {
 889             if (!(o instanceof GrabbedKey)) {
 890                 return false;
 891             }
 892             GrabbedKey key = (GrabbedKey)o;
 893             return (keysym == key.keysym && modifiers == key.modifiers);
 894         }
 895 
 896         public String toString() {
 897             return "Key combination[keysym=" + keysym + ", mods=" + modifiers + "]";
 898         }
< prev index next >