0001: /*
0002: * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025: package sun.awt.X11;
0026:
0027: import java.awt.AWTEvent;
0028: import java.awt.AWTException;
0029: import java.awt.BufferCapabilities;
0030: import java.awt.Color;
0031: import java.awt.Component;
0032: import java.awt.Container;
0033: import java.awt.Cursor;
0034: import java.awt.DefaultKeyboardFocusManager;
0035: import java.awt.Dimension;
0036: import java.awt.Event;
0037: import java.awt.Font;
0038: import java.awt.FontMetrics;
0039: import java.awt.Graphics;
0040: import java.awt.Image;
0041: import java.awt.Insets;
0042: import java.awt.KeyboardFocusManager;
0043: import java.awt.MenuBar;
0044: import java.awt.Point;
0045: import java.awt.Rectangle;
0046: import java.awt.SystemColor;
0047: import java.awt.Toolkit;
0048: import java.awt.Window;
0049: import java.awt.dnd.DropTarget;
0050: import java.awt.dnd.peer.DropTargetPeer;
0051: import java.awt.event.FocusEvent;
0052: import java.awt.event.InputEvent;
0053: import java.awt.event.InputMethodEvent;
0054: import java.awt.event.KeyEvent;
0055: import java.awt.event.MouseEvent;
0056: import java.awt.event.MouseWheelEvent;
0057: import java.awt.event.PaintEvent;
0058: import java.awt.event.WindowEvent;
0059: import java.awt.event.InvocationEvent;
0060: import java.awt.image.ImageObserver;
0061: import java.awt.image.ImageProducer;
0062: import java.awt.image.VolatileImage;
0063: import java.awt.peer.CanvasPeer;
0064: import java.awt.peer.ComponentPeer;
0065: import java.awt.peer.ContainerPeer;
0066: import java.awt.peer.LightweightPeer;
0067: import java.awt.peer.PanelPeer;
0068: import java.awt.peer.WindowPeer;
0069: import java.lang.reflect.*;
0070: import java.security.*;
0071: import java.util.Collection;
0072: import java.util.HashSet;
0073: import java.util.Set;
0074: import java.util.Vector;
0075: import java.util.logging.*;
0076: import sun.awt.*;
0077: import sun.awt.event.IgnorePaintEvent;
0078: import sun.awt.image.SunVolatileImage;
0079: import sun.awt.image.ToolkitImage;
0080:
0081: public class XComponentPeer extends XWindow implements ComponentPeer,
0082: DropTargetPeer, XConstants {
0083: /* FIX ME: these constants copied from java.awt.KeyboardFocusManager */
0084: static final int SNFH_FAILURE = 0;
0085: static final int SNFH_SUCCESS_HANDLED = 1;
0086: static final int SNFH_SUCCESS_PROCEED = 2;
0087:
0088: private static final Logger log = Logger
0089: .getLogger("sun.awt.X11.XComponentPeer");
0090: private static final Logger buffersLog = Logger
0091: .getLogger("sun.awt.X11.XComponentPeer.multibuffer");
0092: private static final Logger focusLog = Logger
0093: .getLogger("sun.awt.X11.focus.XComponentPeer");
0094: private static final Logger fontLog = Logger
0095: .getLogger("sun.awt.X11.font.XComponentPeer");
0096: private static final Logger enableLog = Logger
0097: .getLogger("sun.awt.X11.enable.XComponentPeer");
0098:
0099: boolean paintPending = false;
0100: boolean isLayouting = false;
0101: boolean enabled;
0102:
0103: // Actually used only by XDecoratedPeer
0104: protected int boundsOperation;
0105:
0106: Color foreground;
0107: Color background;
0108:
0109: // Colors calculated as on Motif using MotifColorUtilties.
0110: // If you use these, call updateMotifColors() in the peer's Constructor and
0111: // setBackground(). Examples are XCheckboxPeer and XButtonPeer.
0112: Color darkShadow;
0113: Color lightShadow;
0114: Color selectColor;
0115:
0116: Font font;
0117: private long backBuffer = 0;
0118: private VolatileImage xBackBuffer = null;
0119:
0120: static Color[] systemColors;
0121:
0122: XComponentPeer() {
0123: }
0124:
0125: XComponentPeer(XCreateWindowParams params) {
0126: super (params);
0127: }
0128:
0129: XComponentPeer(Component target, long parentWindow, Rectangle bounds) {
0130: super (target, parentWindow, bounds);
0131: }
0132:
0133: /**
0134: * Standard peer constructor, with corresponding Component
0135: */
0136: XComponentPeer(Component target) {
0137: super (target);
0138: }
0139:
0140: void preInit(XCreateWindowParams params) {
0141: super .preInit(params);
0142: boundsOperation = DEFAULT_OPERATION;
0143: }
0144:
0145: void postInit(XCreateWindowParams params) {
0146: super .postInit(params);
0147: Color c;
0148: Font f;
0149: Cursor cursor;
0150:
0151: pSetCursor(target.getCursor());
0152:
0153: foreground = target.getForeground();
0154: background = target.getBackground();
0155: font = target.getFont();
0156:
0157: if (isInitialReshape()) {
0158: Rectangle r = target.getBounds();
0159: reshape(r.x, r.y, r.width, r.height);
0160: }
0161:
0162: enabled = target.isEnabled();
0163:
0164: // If any of our heavyweight ancestors are disable, we should be too
0165: // See 6176875 for more information
0166: Component comp = target;
0167: while (!(comp == null || comp instanceof Window)) {
0168: comp = comp.getParent();
0169: if (comp != null && !comp.isEnabled()
0170: && !comp.isLightweight()) {
0171: setEnabled(false);
0172: break;
0173: }
0174: }
0175: enableLog.log(Level.FINE, "Initial enable state: {0}",
0176: new Object[] { Boolean.valueOf(enabled) });
0177:
0178: if (target.isVisible()) {
0179: show();
0180: }
0181: }
0182:
0183: protected boolean isInitialReshape() {
0184: return true;
0185: }
0186:
0187: public void reparent(ContainerPeer newNativeParent) {
0188: XComponentPeer newPeer = (XComponentPeer) newNativeParent;
0189: XToolkit.awtLock();
0190: try {
0191: XlibWrapper.XReparentWindow(XToolkit.getDisplay(),
0192: getWindow(), newPeer.getContentWindow(), x, y);
0193: parentWindow = newPeer;
0194: } finally {
0195: XToolkit.awtUnlock();
0196: }
0197: }
0198:
0199: public boolean isReparentSupported() {
0200: return System.getProperty(
0201: "sun.awt.X11.XComponentPeer.reparentNotSupported",
0202: "false").equals("false");
0203: }
0204:
0205: public boolean isObscured() {
0206: Container container = (target instanceof Container) ? (Container) target
0207: : target.getParent();
0208:
0209: if (container == null) {
0210: return true;
0211: }
0212:
0213: Container parent;
0214: while ((parent = container.getParent()) != null) {
0215: container = parent;
0216: }
0217:
0218: if (container instanceof Window) {
0219: XWindowPeer wpeer = (XWindowPeer) (container.getPeer());
0220: if (wpeer != null) {
0221: return (wpeer.winAttr.visibilityState != wpeer.winAttr.AWT_UNOBSCURED);
0222: }
0223: }
0224: return true;
0225: }
0226:
0227: public boolean canDetermineObscurity() {
0228: return true;
0229: }
0230:
0231: static XComponentPeer getNativeContainer(Component comp) {
0232: if (comp == null) {
0233: return null;
0234: }
0235:
0236: synchronized (comp.getTreeLock()) {
0237: while (comp != null
0238: && (ComponentAccessor.getPeer(comp) instanceof LightweightPeer)) {
0239: comp = ComponentAccessor.getParent_NoClientCode(comp);
0240: }
0241:
0242: if (comp != null) {
0243: ComponentPeer peer = ComponentAccessor.getPeer(comp);
0244: if (peer != null && peer instanceof XComponentPeer) {
0245: return (XComponentPeer) peer;
0246: }
0247: }
0248: }
0249:
0250: return null;
0251: }
0252:
0253: /*************************************************
0254: * FOCUS STUFF
0255: *************************************************/
0256:
0257: /**
0258: * Keeps the track of focused state of the _NATIVE_ window
0259: */
0260: boolean bHasFocus = false;
0261:
0262: /**
0263: * Descendants should use this method to determine whether or not native window
0264: * has focus.
0265: */
0266: final public boolean hasFocus() {
0267: return bHasFocus;
0268: }
0269:
0270: /**
0271: * Called when component receives focus
0272: */
0273: public void focusGained(FocusEvent e) {
0274: focusLog.log(Level.FINE, "{0}", new Object[] { e });
0275: bHasFocus = true;
0276: }
0277:
0278: /**
0279: * Called when component loses focus
0280: */
0281: public void focusLost(FocusEvent e) {
0282: focusLog.log(Level.FINE, "{0}", new Object[] { e });
0283: bHasFocus = false;
0284: }
0285:
0286: public boolean isFocusable() {
0287: /* should be implemented by other sub-classes */
0288: return false;
0289: }
0290:
0291: private static Class seClass;
0292: private static Constructor seCtor;
0293:
0294: final static AWTEvent wrapInSequenced(AWTEvent event) {
0295: try {
0296: if (seClass == null) {
0297: seClass = Class.forName("java.awt.SequencedEvent");
0298: }
0299:
0300: if (seCtor == null) {
0301: seCtor = (Constructor) AccessController
0302: .doPrivileged(new PrivilegedExceptionAction() {
0303: public Object run() throws Exception {
0304: Constructor ctor = seClass
0305: .getConstructor(new Class[] { AWTEvent.class });
0306: ctor.setAccessible(true);
0307: return ctor;
0308: }
0309: });
0310: }
0311:
0312: return (AWTEvent) seCtor
0313: .newInstance(new Object[] { event });
0314: } catch (ClassNotFoundException e) {
0315: throw new NoClassDefFoundError("java.awt.SequencedEvent.");
0316: } catch (PrivilegedActionException ex) {
0317: throw new NoClassDefFoundError("java.awt.SequencedEvent.");
0318: } catch (InstantiationException e) {
0319: assert false;
0320: } catch (IllegalAccessException e) {
0321: assert false;
0322: } catch (InvocationTargetException e) {
0323: assert false;
0324: }
0325:
0326: return null;
0327: }
0328:
0329: /**
0330: * Returns whether or not this component should be given focus on mouse click.
0331: * Default implementation return whether or not this peer is "focusable"
0332: * Descendants might want to override it to extend/restrict conditions at which this
0333: * component should be focused by click (see MCanvasPeer and MPanelPeer)
0334: */
0335: protected boolean shouldFocusOnClick() {
0336: return isFocusable();
0337: }
0338:
0339: /**
0340: * Checks whether or not this component would be focused by native system if it would be allowed to do so.
0341: * Currently it checks that it displayable, visible, enabled and focusable.
0342: */
0343: static boolean canBeFocusedByClick(Component component) {
0344: if (component == null) {
0345: return false;
0346: } else {
0347: return component.isDisplayable() && component.isVisible()
0348: && component.isEnabled() && component.isFocusable();
0349: }
0350: }
0351:
0352: static Window getContainingWindow(Component comp) {
0353: while (comp != null && !(comp instanceof Window)) {
0354: comp = comp.getParent();
0355: }
0356:
0357: return (Window) comp;
0358: }
0359:
0360: static Method processSynchronousLightweightTransferMethod;
0361:
0362: static boolean processSynchronousLightweightTransfer(
0363: Component heavyweight, Component descendant,
0364: boolean temporary, boolean focusedWindowChangeAllowed,
0365: long time) {
0366: try {
0367: if (processSynchronousLightweightTransferMethod == null) {
0368: processSynchronousLightweightTransferMethod = (Method) AccessController
0369: .doPrivileged(new PrivilegedExceptionAction() {
0370: public Object run()
0371: throws IllegalAccessException,
0372: NoSuchMethodException {
0373: Method m = KeyboardFocusManager.class
0374: .getDeclaredMethod(
0375: "processSynchronousLightweightTransfer",
0376: new Class[] {
0377: Component.class,
0378: Component.class,
0379: Boolean.TYPE,
0380: Boolean.TYPE,
0381: Long.TYPE });
0382: m.setAccessible(true);
0383: return m;
0384: }
0385: });
0386: }
0387: Object[] params = new Object[] { heavyweight, descendant,
0388: Boolean.valueOf(temporary),
0389: Boolean.valueOf(focusedWindowChangeAllowed),
0390: Long.valueOf(time) };
0391: return ((Boolean) processSynchronousLightweightTransferMethod
0392: .invoke(null, params)).booleanValue();
0393: } catch (PrivilegedActionException pae) {
0394: pae.printStackTrace();
0395: return false;
0396: } catch (IllegalAccessException iae) {
0397: iae.printStackTrace();
0398: return false;
0399: } catch (IllegalArgumentException iaee) {
0400: iaee.printStackTrace();
0401: return false;
0402: } catch (InvocationTargetException ite) {
0403: ite.printStackTrace();
0404: return false;
0405: }
0406: }
0407:
0408: static Method requestFocusWithCause;
0409:
0410: static void callRequestFocus(Component target,
0411: CausedFocusEvent.Cause cause) {
0412: if (requestFocusWithCause == null) {
0413: requestFocusWithCause = SunToolkit.getMethod(
0414: Component.class, "requestFocus",
0415: new Class[] { CausedFocusEvent.Cause.class });
0416: }
0417: if (requestFocusWithCause != null) {
0418: try {
0419: requestFocusWithCause.invoke(target,
0420: new Object[] { cause });
0421: } catch (Exception e) {
0422: e.printStackTrace();
0423: }
0424: }
0425: }
0426:
0427: final public boolean requestFocus(Component lightweightChild,
0428: boolean temporary, boolean focusedWindowChangeAllowed,
0429: long time, CausedFocusEvent.Cause cause) {
0430: if (processSynchronousLightweightTransfer(target,
0431: lightweightChild, temporary,
0432: focusedWindowChangeAllowed, time)) {
0433: return true;
0434: }
0435:
0436: int result = XKeyboardFocusManagerPeer
0437: .shouldNativelyFocusHeavyweight(target,
0438: lightweightChild, temporary,
0439: focusedWindowChangeAllowed, time, cause);
0440:
0441: switch (result) {
0442: case SNFH_FAILURE:
0443: return false;
0444: case SNFH_SUCCESS_PROCEED:
0445: // Currently we just generate focus events like we deal with lightweight instead of calling
0446: // XSetInputFocus on native window
0447: if (focusLog.isLoggable(Level.FINER))
0448: focusLog.finer("Proceeding with request to "
0449: + lightweightChild + " in " + target);
0450: /**
0451: * The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight
0452: * checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet
0453: * been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record
0454: * in requests list - and it breaks our requests sequence as first record on WGF should be the last focus
0455: * owner which had focus before WLF. So, we should not add request record for such requests
0456: * but store this component in mostRecent - and return true as before for compatibility.
0457: */
0458: Window parentWindow = getContainingWindow(target);
0459: if (parentWindow != null) {
0460: // and check that it is focused
0461: if (!parentWindow.isFocused()) {
0462: XWindowPeer wpeer = (XWindowPeer) parentWindow
0463: .getPeer();
0464: /*
0465: * Fix for 6314575.
0466: * Shouldn't restore focus on 'actualFocusedWindow'
0467: * when a component inside a Frame is requesting it.
0468: */
0469: wpeer.setActualFocusedWindow(null);
0470:
0471: boolean res = wpeer.requestWindowFocus();
0472: if (focusLog.isLoggable(Level.FINER))
0473: focusLog
0474: .finer("Requested window focus: " + res);
0475: // If parent window can be made focused and has been made focused(synchronously)
0476: // then we can proceed with children, otherwise we retreat.
0477: if (!(res && parentWindow.isFocused())) {
0478: focusLog
0479: .finer("Waiting for asynchronous processing of window focus request");
0480: KeyboardFocusManagerPeerImpl
0481: .removeLastFocusRequest(target);
0482: return false;
0483: }
0484: }
0485: } else {
0486: if (focusLog.isLoggable(Level.FINER))
0487: focusLog.finer("WARNING: Parent window is null");
0488: return false;
0489: }
0490:
0491: // NOTE: We simulate heavyweight behavior of Motif - component receives focus right
0492: // after request, not after event. Normally, we should better listen for event
0493: // by listeners.
0494: return XKeyboardFocusManagerPeer.simulateMotifRequestFocus(
0495: lightweightChild, target, temporary,
0496: focusedWindowChangeAllowed, time, cause);
0497: // Motif compatibility code
0498: case SNFH_SUCCESS_HANDLED:
0499: // Either lightweight or excessive request - all events are generated.
0500: return true;
0501: }
0502: return false;
0503: }
0504:
0505: void handleJavaFocusEvent(AWTEvent e) {
0506: if (focusLog.isLoggable(Level.FINER))
0507: focusLog.finer(e.toString());
0508: if (e.getID() == FocusEvent.FOCUS_GAINED) {
0509: focusGained((FocusEvent) e);
0510: } else {
0511: focusLost((FocusEvent) e);
0512: }
0513: }
0514:
0515: void handleJavaWindowFocusEvent(AWTEvent e) {
0516: }
0517:
0518: /*************************************************
0519: * END OF FOCUS STUFF
0520: *************************************************/
0521:
0522: public void setVisible(boolean b) {
0523: xSetVisible(b);
0524: }
0525:
0526: public void show() {
0527: setVisible(true);
0528: }
0529:
0530: public void hide() {
0531: setVisible(false);
0532: }
0533:
0534: /**
0535: * @see java.awt.peer.ComponentPeer
0536: */
0537: public void setEnabled(boolean value) {
0538: enableLog.log(Level.FINE, "{0}ing {1}", new Object[] {
0539: (value ? "Enabl" : "Disabl"), this });
0540: boolean repaintNeeded = (enabled != value);
0541: enabled = value;
0542: if (target instanceof Container) {
0543: Component list[] = ((Container) target).getComponents();
0544: for (int i = 0; i < list.length; ++i) {
0545: boolean childEnabled = list[i].isEnabled();
0546: ComponentPeer p = list[i].getPeer();
0547: if (p != null) {
0548: p.setEnabled(value && childEnabled);
0549: }
0550: }
0551: }
0552: if (repaintNeeded) {
0553: repaint();
0554: }
0555: }
0556:
0557: //
0558: // public so aw/Window can call it
0559: //
0560: public boolean isEnabled() {
0561: return enabled;
0562: }
0563:
0564: public void enable() {
0565: setEnabled(true);
0566: }
0567:
0568: public void disable() {
0569: setEnabled(false);
0570: }
0571:
0572: public void paint(Graphics g) {
0573: }
0574:
0575: public void repaint(long tm, int x, int y, int width, int height) {
0576: repaint();
0577: }
0578:
0579: public Graphics getGraphics() {
0580: return getGraphics(surfaceData, getPeerForeground(),
0581: getPeerBackground(), getPeerFont());
0582: }
0583:
0584: public void print(Graphics g) {
0585: // clear rect here to emulate X clears rect before Expose
0586: g.setColor(target.getBackground());
0587: g.fillRect(0, 0, target.getWidth(), target.getHeight());
0588: g.setColor(target.getForeground());
0589: // paint peer
0590: paint(g);
0591: // allow target to change the picture
0592: target.print(g);
0593: }
0594:
0595: public void setBounds(int x, int y, int width, int height, int op) {
0596: this .x = x;
0597: this .y = y;
0598: this .width = width;
0599: this .height = height;
0600: xSetBounds(x, y, width, height);
0601: validateSurface();
0602: layout();
0603: }
0604:
0605: public void reshape(int x, int y, int width, int height) {
0606: setBounds(x, y, width, height, SET_BOUNDS);
0607: }
0608:
0609: public void coalescePaintEvent(PaintEvent e) {
0610: Rectangle r = e.getUpdateRect();
0611: if (!(e instanceof IgnorePaintEvent)) {
0612: paintArea.add(r, e.getID());
0613: }
0614: if (true) {
0615: switch (e.getID()) {
0616: case PaintEvent.UPDATE:
0617: log
0618: .finer("XCP coalescePaintEvent : UPDATE : add : x = "
0619: + r.x
0620: + ", y = "
0621: + r.y
0622: + ", width = "
0623: + r.width + ",height = " + r.height);
0624: return;
0625: case PaintEvent.PAINT:
0626: log.finer("XCP coalescePaintEvent : PAINT : add : x = "
0627: + r.x + ", y = " + r.y + ", width = " + r.width
0628: + ",height = " + r.height);
0629: return;
0630: }
0631: }
0632: }
0633:
0634: XWindowPeer getParentTopLevel() {
0635: Container parent = (target instanceof Container) ? ((Container) target)
0636: : (ComponentAccessor.getParent_NoClientCode(target));
0637: // Search for parent window
0638: while (parent != null && !(parent instanceof Window)) {
0639: parent = ComponentAccessor.getParent_NoClientCode(parent);
0640: }
0641: if (parent != null) {
0642: return (XWindowPeer) ComponentAccessor.getPeer(parent);
0643: } else {
0644: return null;
0645: }
0646: }
0647:
0648: /* This method is intended to be over-ridden by peers to perform user interaction */
0649: void handleJavaMouseEvent(MouseEvent e) {
0650: switch (e.getID()) {
0651: case MouseEvent.MOUSE_PRESSED:
0652: if (target == e.getSource() && shouldFocusOnClick()
0653: && !target.isFocusOwner()
0654: && canBeFocusedByClick(target)) {
0655: XWindowPeer parentXWindow = getParentTopLevel();
0656: Window parentWindow = ((Window) parentXWindow
0657: .getTarget());
0658: // Simple windows are non-focusable in X terms but focusable in Java terms.
0659: // As X-non-focusable they don't receive any focus events - we should generate them
0660: // by ourselfves.
0661: // if (parentXWindow.isFocusableWindow() /*&& parentXWindow.isSimpleWindow()*/ &&
0662: // !(getCurrentNativeFocusedWindow() == parentWindow))
0663: // {
0664: // setCurrentNativeFocusedWindow(parentWindow);
0665: // WindowEvent wfg = new WindowEvent(parentWindow, WindowEvent.WINDOW_GAINED_FOCUS);
0666: // parentWindow.dispatchEvent(wfg);
0667: // }
0668: callRequestFocus(target,
0669: CausedFocusEvent.Cause.MOUSE_EVENT);
0670: }
0671: break;
0672: }
0673: }
0674:
0675: /* This method is intended to be over-ridden by peers to perform user interaction */
0676: void handleJavaKeyEvent(KeyEvent e) {
0677: }
0678:
0679: /* This method is intended to be over-ridden by peers to perform user interaction */
0680: void handleJavaMouseWheelEvent(MouseWheelEvent e) {
0681: }
0682:
0683: /* This method is intended to be over-ridden by peers to perform user interaction */
0684: void handleJavaInputMethodEvent(InputMethodEvent e) {
0685: }
0686:
0687: void handleF10JavaKeyEvent(KeyEvent e) {
0688: if (e.getID() == KeyEvent.KEY_PRESSED
0689: && e.getKeyCode() == KeyEvent.VK_F10) {
0690: XWindowPeer winPeer = this .getToplevelXWindow();
0691: if (winPeer instanceof XFramePeer) {
0692: XMenuBarPeer mPeer = ((XFramePeer) winPeer)
0693: .getMenubarPeer();
0694: if (mPeer != null) {
0695: mPeer.handleF10KeyPress(e);
0696: }
0697: }
0698: }
0699: }
0700:
0701: public void handleEvent(java.awt.AWTEvent e) {
0702: if ((e instanceof InputEvent) && !((InputEvent) e).isConsumed()
0703: && target.isEnabled()) {
0704: if (e instanceof MouseEvent) {
0705: if (e instanceof MouseWheelEvent) {
0706: handleJavaMouseWheelEvent((MouseWheelEvent) e);
0707: } else
0708: handleJavaMouseEvent((MouseEvent) e);
0709: } else if (e instanceof KeyEvent) {
0710: handleF10JavaKeyEvent((KeyEvent) e);
0711: handleJavaKeyEvent((KeyEvent) e);
0712: }
0713: } else if (e instanceof KeyEvent
0714: && !((InputEvent) e).isConsumed()) {
0715: // even if target is disabled.
0716: handleF10JavaKeyEvent((KeyEvent) e);
0717: } else if (e instanceof InputMethodEvent) {
0718: handleJavaInputMethodEvent((InputMethodEvent) e);
0719: }
0720:
0721: int id = e.getID();
0722:
0723: switch (id) {
0724: case PaintEvent.PAINT:
0725: // Got native painting
0726: paintPending = false;
0727: // Fallthrough to next statement
0728: case PaintEvent.UPDATE:
0729: // Skip all painting while layouting and all UPDATEs
0730: // while waiting for native paint
0731: if (!isLayouting && !paintPending) {
0732: paintArea.paint(target, false);
0733: }
0734: return;
0735: case FocusEvent.FOCUS_LOST:
0736: case FocusEvent.FOCUS_GAINED:
0737: handleJavaFocusEvent(e);
0738: break;
0739: case WindowEvent.WINDOW_LOST_FOCUS:
0740: case WindowEvent.WINDOW_GAINED_FOCUS:
0741: handleJavaWindowFocusEvent(e);
0742: break;
0743: default:
0744: break;
0745: }
0746:
0747: }
0748:
0749: public void handleButtonPressRelease(XEvent xev) {
0750: /*
0751: * Fix for 6385277.
0752: * We request focus on simple Window by click in order
0753: * to make it behave like Frame/Dialog in this case and also to unify
0754: * the behaviour with what we have on MS Windows.
0755: * handleJavaMouseEvent() would be more suitable place to do this
0756: * but we want Swing to have this functionality also.
0757: */
0758: if (xev.get_type() == ButtonPress) {
0759: final XWindowPeer parentXWindow = getParentTopLevel();
0760: Window parentWindow = (Window) parentXWindow.getTarget();
0761: if (parentXWindow.isFocusableWindow()
0762: && parentXWindow.isSimpleWindow()
0763: && XKeyboardFocusManagerPeer
0764: .getCurrentNativeFocusedWindow() != parentWindow) {
0765: postEvent(new InvocationEvent(parentWindow,
0766: new Runnable() {
0767: public void run() {
0768: // Request focus on the EDT of 'parentWindow' because
0769: // XDecoratedPeer.requestWindowFocus() calls client code.
0770: parentXWindow.requestXFocus();
0771: }
0772: }));
0773: }
0774: }
0775: super .handleButtonPressRelease(xev);
0776: }
0777:
0778: public Dimension getMinimumSize() {
0779: return target.getSize();
0780: }
0781:
0782: public Dimension getPreferredSize() {
0783: return getMinimumSize();
0784: }
0785:
0786: public void layout() {
0787: }
0788:
0789: public java.awt.Toolkit getToolkit() {
0790: return Toolkit.getDefaultToolkit();
0791: }
0792:
0793: void updateMotifColors(Color bg) {
0794: int red = bg.getRed();
0795: int green = bg.getGreen();
0796: int blue = bg.getBlue();
0797:
0798: darkShadow = new Color(MotifColorUtilities
0799: .calculateBottomShadowFromBackground(red, green, blue));
0800: lightShadow = new Color(MotifColorUtilities
0801: .calculateTopShadowFromBackground(red, green, blue));
0802: selectColor = new Color(MotifColorUtilities
0803: .calculateSelectFromBackground(red, green, blue));
0804: }
0805:
0806: /*
0807: * Draw a 3D rectangle using the Motif colors.
0808: * "Normal" rectangles have shadows on the bottom.
0809: * "Depressed" rectangles (such as pressed buttons) have shadows on the top,
0810: * in which case true should be passed for topShadow.
0811: */
0812: public void drawMotif3DRect(Graphics g, int x, int y, int width,
0813: int height, boolean topShadow) {
0814: g.setColor(topShadow ? darkShadow : lightShadow);
0815: g.drawLine(x, y, x + width, y); // top
0816: g.drawLine(x, y + height, x, y); // left
0817:
0818: g.setColor(topShadow ? lightShadow : darkShadow);
0819: g.drawLine(x + 1, y + height, x + width, y + height); // bottom
0820: g.drawLine(x + width, y + height, x + width, y + 1); // right
0821: }
0822:
0823: public void setBackground(Color c) {
0824: if (log.isLoggable(Level.FINE))
0825: log.fine("Set background to " + c);
0826: synchronized (getStateLock()) {
0827: background = c;
0828: }
0829: super .setBackground(c);
0830: repaint();
0831: }
0832:
0833: public void setForeground(Color c) {
0834: if (log.isLoggable(Level.FINE))
0835: log.fine("Set foreground to " + c);
0836: synchronized (getStateLock()) {
0837: foreground = c;
0838: }
0839: repaint();
0840: }
0841:
0842: /**
0843: * Gets the font metrics for the specified font.
0844: * @param font the font for which font metrics is to be
0845: * obtained
0846: * @return the font metrics for <code>font</code>
0847: * @see #getFont
0848: * @see #getPeer
0849: * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
0850: * @see Toolkit#getFontMetrics(Font)
0851: * @since JDK1.0
0852: */
0853: public FontMetrics getFontMetrics(Font font) {
0854: if (fontLog.isLoggable(Level.FINE))
0855: fontLog.fine("Getting font metrics for " + font);
0856: return sun.font.FontDesignMetrics.getMetrics(font);
0857: }
0858:
0859: public void setFont(Font f) {
0860: synchronized (getStateLock()) {
0861: if (f == null) {
0862: f = defaultFont;
0863: }
0864: font = f;
0865: }
0866: // as it stands currently we dont need to do layout or repaint since
0867: // layout is done in the Component upon setFont.
0868: //layout();
0869: // target.repaint();
0870: //repaint()?
0871: }
0872:
0873: public Font getFont() {
0874: return font;
0875: }
0876:
0877: public void updateCursorImmediately() {
0878: XGlobalCursorManager.getCursorManager()
0879: .updateCursorImmediately();
0880: }
0881:
0882: public void pSetCursor(Cursor cursor) {
0883: XToolkit.awtLock();
0884: try {
0885: long xcursor = XGlobalCursorManager.getCursor(cursor);
0886:
0887: XSetWindowAttributes xwa = new XSetWindowAttributes();
0888: xwa.set_cursor(xcursor);
0889:
0890: long valuemask = XlibWrapper.CWCursor;
0891:
0892: XlibWrapper.XChangeWindowAttributes(XToolkit.getDisplay(),
0893: getWindow(), valuemask, xwa.pData);
0894: XlibWrapper.XFlush(XToolkit.getDisplay());
0895: xwa.dispose();
0896: } finally {
0897: XToolkit.awtUnlock();
0898: }
0899: }
0900:
0901: public Image createImage(ImageProducer producer) {
0902: return new ToolkitImage(producer);
0903: }
0904:
0905: public Image createImage(int width, int height) {
0906: return graphicsConfig.createAcceleratedImage(target, width,
0907: height);
0908: }
0909:
0910: public VolatileImage createVolatileImage(int width, int height) {
0911: return new SunVolatileImage(target, width, height);
0912: }
0913:
0914: public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
0915: return getToolkit().prepareImage(img, w, h, o);
0916: }
0917:
0918: public int checkImage(Image img, int w, int h, ImageObserver o) {
0919: return getToolkit().checkImage(img, w, h, o);
0920: }
0921:
0922: public Dimension preferredSize() {
0923: return getPreferredSize();
0924: }
0925:
0926: public Dimension minimumSize() {
0927: return getMinimumSize();
0928: }
0929:
0930: public Insets getInsets() {
0931: return new Insets(0, 0, 0, 0);
0932: }
0933:
0934: public void beginValidate() {
0935: }
0936:
0937: public void endValidate() {
0938: }
0939:
0940: /**
0941: * DEPRECATED: Replaced by getInsets().
0942: */
0943:
0944: public Insets insets() {
0945: return getInsets();
0946: }
0947:
0948: // Returns true if we are inside begin/endLayout and
0949: // are waiting for native painting
0950: public boolean isPaintPending() {
0951: return paintPending && isLayouting;
0952: }
0953:
0954: public boolean handlesWheelScrolling() {
0955: return false;
0956: }
0957:
0958: public void beginLayout() {
0959: // Skip all painting till endLayout
0960: isLayouting = true;
0961:
0962: }
0963:
0964: public void endLayout() {
0965: if (!paintPending && !paintArea.isEmpty()
0966: && !ComponentAccessor.getIgnoreRepaint(target)) {
0967: // if not waiting for native painting repaint damaged area
0968: postEvent(new PaintEvent(target, PaintEvent.PAINT,
0969: new Rectangle()));
0970: }
0971: isLayouting = false;
0972: }
0973:
0974: public Color getWinBackground() {
0975: return getPeerBackground();
0976: }
0977:
0978: static int[] getRGBvals(Color c) {
0979:
0980: int rgbvals[] = new int[3];
0981:
0982: rgbvals[0] = c.getRed();
0983: rgbvals[1] = c.getGreen();
0984: rgbvals[2] = c.getBlue();
0985:
0986: return rgbvals;
0987: }
0988:
0989: static final int BACKGROUND_COLOR = 0;
0990: static final int HIGHLIGHT_COLOR = 1;
0991: static final int SHADOW_COLOR = 2;
0992: static final int FOREGROUND_COLOR = 3;
0993:
0994: public Color[] getGUIcolors() {
0995: Color c[] = new Color[4];
0996: float backb, highb, shadowb, hue, saturation;
0997: c[BACKGROUND_COLOR] = getWinBackground();
0998: if (c[BACKGROUND_COLOR] == null) {
0999: c[BACKGROUND_COLOR] = super .getWinBackground();
1000: }
1001: if (c[BACKGROUND_COLOR] == null) {
1002: c[BACKGROUND_COLOR] = Color.lightGray;
1003: }
1004:
1005: int[] rgb = getRGBvals(c[BACKGROUND_COLOR]);
1006:
1007: float[] hsb = Color.RGBtoHSB(rgb[0], rgb[1], rgb[2], null);
1008:
1009: hue = hsb[0];
1010: saturation = hsb[1];
1011: backb = hsb[2];
1012:
1013: /* Calculate Highlight Brightness */
1014:
1015: highb = backb + 0.2f;
1016: shadowb = backb - 0.4f;
1017: if ((highb > 1.0)) {
1018: if ((1.0 - backb) < 0.05) {
1019: highb = shadowb + 0.25f;
1020: } else {
1021: highb = 1.0f;
1022: }
1023: } else {
1024: if (shadowb < 0.0) {
1025: if ((backb - 0.0) < 0.25) {
1026: highb = backb + 0.75f;
1027: shadowb = highb - 0.2f;
1028: } else {
1029: shadowb = 0.0f;
1030: }
1031: }
1032: }
1033: c[HIGHLIGHT_COLOR] = Color.getHSBColor(hue, saturation, highb);
1034: c[SHADOW_COLOR] = Color.getHSBColor(hue, saturation, shadowb);
1035:
1036: /*
1037: c[SHADOW_COLOR] = c[BACKGROUND_COLOR].darker();
1038: int r2 = c[SHADOW_COLOR].getRed();
1039: int g2 = c[SHADOW_COLOR].getGreen();
1040: int b2 = c[SHADOW_COLOR].getBlue();
1041: */
1042:
1043: c[FOREGROUND_COLOR] = getPeerForeground();
1044: if (c[FOREGROUND_COLOR] == null) {
1045: c[FOREGROUND_COLOR] = Color.black;
1046: }
1047: /*
1048: if ((c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR]))
1049: && (c[BACKGROUND_COLOR].equals(c[SHADOW_COLOR]))) {
1050: c[SHADOW_COLOR] = new Color(c[BACKGROUND_COLOR].getRed() + 75,
1051: c[BACKGROUND_COLOR].getGreen() + 75,
1052: c[BACKGROUND_COLOR].getBlue() + 75);
1053: c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR].brighter();
1054: } else if (c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) {
1055: c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR];
1056: c[SHADOW_COLOR] = c[SHADOW_COLOR].darker();
1057: }
1058: */
1059: if (!isEnabled()) {
1060: c[BACKGROUND_COLOR] = c[BACKGROUND_COLOR].darker();
1061: // Reduce the contrast
1062: // Calculate the NTSC gray (NB: REC709 L* might be better!)
1063: // for foreground and background; then multiply the foreground
1064: // by the average lightness
1065:
1066: Color tc = c[BACKGROUND_COLOR];
1067: int bg = tc.getRed() * 30 + tc.getGreen() * 59
1068: + tc.getBlue() * 11;
1069:
1070: tc = c[FOREGROUND_COLOR];
1071: int fg = tc.getRed() * 30 + tc.getGreen() * 59
1072: + tc.getBlue() * 11;
1073:
1074: float ave = (float) ((fg + bg) / 51000.0);
1075: // 255 * 100 * 2
1076:
1077: Color newForeground = new Color((int) (tc.getRed() * ave),
1078: (int) (tc.getGreen() * ave),
1079: (int) (tc.getBlue() * ave));
1080:
1081: if (newForeground.equals(c[FOREGROUND_COLOR])) {
1082: // This probably means the foreground color is black or white
1083: newForeground = new Color(ave, ave, ave);
1084: }
1085: c[FOREGROUND_COLOR] = newForeground;
1086:
1087: }
1088:
1089: return c;
1090: }
1091:
1092: /**
1093: * Returns an array of Colors similar to getGUIcolors(), but using the
1094: * System colors. This is useful if pieces of a Component (such as
1095: * the integrated scrollbars of a List) should retain the System color
1096: * instead of the background color set by Component.setBackground().
1097: */
1098: static Color[] getSystemColors() {
1099: if (systemColors == null) {
1100: systemColors = new Color[4];
1101: systemColors[BACKGROUND_COLOR] = SystemColor.window;
1102: systemColors[HIGHLIGHT_COLOR] = SystemColor.controlLtHighlight;
1103: systemColors[SHADOW_COLOR] = SystemColor.controlShadow;
1104: systemColors[FOREGROUND_COLOR] = SystemColor.windowText;
1105: }
1106: return systemColors;
1107: }
1108:
1109: /**
1110: * Draw a 3D oval.
1111: */
1112: public void draw3DOval(Graphics g, Color colors[], int x, int y,
1113: int w, int h, boolean raised) {
1114: Color c = g.getColor();
1115: g.setColor(raised ? colors[HIGHLIGHT_COLOR]
1116: : colors[SHADOW_COLOR]);
1117: g.drawArc(x, y, w, h, 45, 180);
1118: g.setColor(raised ? colors[SHADOW_COLOR]
1119: : colors[HIGHLIGHT_COLOR]);
1120: g.drawArc(x, y, w, h, 225, 180);
1121: g.setColor(c);
1122: }
1123:
1124: public void draw3DRect(Graphics g, Color colors[], int x, int y,
1125: int width, int height, boolean raised) {
1126: Color c = g.getColor();
1127: g.setColor(raised ? colors[HIGHLIGHT_COLOR]
1128: : colors[SHADOW_COLOR]);
1129: g.drawLine(x, y, x, y + height);
1130: g.drawLine(x + 1, y, x + width - 1, y);
1131: g.setColor(raised ? colors[SHADOW_COLOR]
1132: : colors[HIGHLIGHT_COLOR]);
1133: g.drawLine(x + 1, y + height, x + width, y + height);
1134: g.drawLine(x + width, y, x + width, y + height - 1);
1135: g.setColor(c);
1136: }
1137:
1138: /*
1139: * drawXXX() methods are used to print the native components by
1140: * rendering the Motif look ourselves.
1141: * ToDo(aim): needs to query native motif for more accurate color
1142: * information.
1143: */
1144: void draw3DOval(Graphics g, Color bg, int x, int y, int w, int h,
1145: boolean raised) {
1146: Color c = g.getColor();
1147: Color shadow = bg.darker();
1148: Color highlight = bg.brighter();
1149:
1150: g.setColor(raised ? highlight : shadow);
1151: g.drawArc(x, y, w, h, 45, 180);
1152: g.setColor(raised ? shadow : highlight);
1153: g.drawArc(x, y, w, h, 225, 180);
1154: g.setColor(c);
1155: }
1156:
1157: void draw3DRect(Graphics g, Color bg, int x, int y, int width,
1158: int height, boolean raised) {
1159: Color c = g.getColor();
1160: Color shadow = bg.darker();
1161: Color highlight = bg.brighter();
1162:
1163: g.setColor(raised ? highlight : shadow);
1164: g.drawLine(x, y, x, y + height);
1165: g.drawLine(x + 1, y, x + width - 1, y);
1166: g.setColor(raised ? shadow : highlight);
1167: g.drawLine(x + 1, y + height, x + width, y + height);
1168: g.drawLine(x + width, y, x + width, y + height - 1);
1169: g.setColor(c);
1170: }
1171:
1172: void drawScrollbar(Graphics g, Color bg, int thickness, int length,
1173: int min, int max, int val, int vis, boolean horizontal) {
1174: Color c = g.getColor();
1175: double f = (double) (length - 2 * (thickness - 1))
1176: / Math.max(1, ((max - min) + vis));
1177: int v1 = thickness + (int) (f * (val - min));
1178: int v2 = (int) (f * vis);
1179: int w2 = thickness - 4;
1180: int tpts_x[] = new int[3];
1181: int tpts_y[] = new int[3];
1182:
1183: if (length < 3 * w2) {
1184: v1 = v2 = 0;
1185: if (length < 2 * w2 + 2) {
1186: w2 = (length - 2) / 2;
1187: }
1188: } else if (v2 < 7) {
1189: // enforce a minimum handle size
1190: v1 = Math.max(0, v1 - ((7 - v2) >> 1));
1191: v2 = 7;
1192: }
1193:
1194: int ctr = thickness / 2;
1195: int sbmin = ctr - w2 / 2;
1196: int sbmax = ctr + w2 / 2;
1197:
1198: // paint the background slightly darker
1199: {
1200: Color d = new Color((int) (bg.getRed() * 0.85), (int) (bg
1201: .getGreen() * 0.85), (int) (bg.getBlue() * 0.85));
1202:
1203: g.setColor(d);
1204: if (horizontal) {
1205: g.fillRect(0, 0, length, thickness);
1206: } else {
1207: g.fillRect(0, 0, thickness, length);
1208: }
1209: }
1210:
1211: // paint the thumb and arrows in the normal background color
1212: g.setColor(bg);
1213: if (v1 > 0) {
1214: if (horizontal) {
1215: g.fillRect(v1, 3, v2, thickness - 3);
1216: } else {
1217: g.fillRect(3, v1, thickness - 3, v2);
1218: }
1219: }
1220:
1221: tpts_x[0] = ctr;
1222: tpts_y[0] = 2;
1223: tpts_x[1] = sbmin;
1224: tpts_y[1] = w2;
1225: tpts_x[2] = sbmax;
1226: tpts_y[2] = w2;
1227: if (horizontal) {
1228: g.fillPolygon(tpts_y, tpts_x, 3);
1229: } else {
1230: g.fillPolygon(tpts_x, tpts_y, 3);
1231: }
1232:
1233: tpts_y[0] = length - 2;
1234: tpts_y[1] = length - w2;
1235: tpts_y[2] = length - w2;
1236: if (horizontal) {
1237: g.fillPolygon(tpts_y, tpts_x, 3);
1238: } else {
1239: g.fillPolygon(tpts_x, tpts_y, 3);
1240: }
1241:
1242: Color highlight = bg.brighter();
1243:
1244: // // // // draw the "highlighted" edges
1245: g.setColor(highlight);
1246:
1247: // outline & arrows
1248: if (horizontal) {
1249: g.drawLine(1, thickness, length - 1, thickness);
1250: g.drawLine(length - 1, 1, length - 1, thickness);
1251:
1252: // arrows
1253: g.drawLine(1, ctr, w2, sbmin);
1254: g.drawLine(length - w2, sbmin, length - w2, sbmax);
1255: g.drawLine(length - w2, sbmin, length - 2, ctr);
1256:
1257: } else {
1258: g.drawLine(thickness, 1, thickness, length - 1);
1259: g.drawLine(1, length - 1, thickness, length - 1);
1260:
1261: // arrows
1262: g.drawLine(ctr, 1, sbmin, w2);
1263: g.drawLine(sbmin, length - w2, sbmax, length - w2);
1264: g.drawLine(sbmin, length - w2, ctr, length - 2);
1265: }
1266:
1267: // thumb
1268: if (v1 > 0) {
1269: if (horizontal) {
1270: g.drawLine(v1, 2, v1 + v2, 2);
1271: g.drawLine(v1, 2, v1, thickness - 3);
1272: } else {
1273: g.drawLine(2, v1, 2, v1 + v2);
1274: g.drawLine(2, v1, thickness - 3, v1);
1275: }
1276: }
1277:
1278: Color shadow = bg.darker();
1279:
1280: // // // // draw the "shadowed" edges
1281: g.setColor(shadow);
1282:
1283: // outline && arrows
1284: if (horizontal) {
1285: g.drawLine(0, 0, 0, thickness);
1286: g.drawLine(0, 0, length - 1, 0);
1287:
1288: // arrows
1289: g.drawLine(w2, sbmin, w2, sbmax);
1290: g.drawLine(w2, sbmax, 1, ctr);
1291: g.drawLine(length - 2, ctr, length - w2, sbmax);
1292:
1293: } else {
1294: g.drawLine(0, 0, thickness, 0);
1295: g.drawLine(0, 0, 0, length - 1);
1296:
1297: // arrows
1298: g.drawLine(sbmin, w2, sbmax, w2);
1299: g.drawLine(sbmax, w2, ctr, 1);
1300: g.drawLine(ctr, length - 2, sbmax, length - w2);
1301: }
1302:
1303: // thumb
1304: if (v1 > 0) {
1305: if (horizontal) {
1306: g.drawLine(v1 + v2, 2, v1 + v2, thickness - 2);
1307: g.drawLine(v1, thickness - 2, v1 + v2, thickness - 2);
1308: } else {
1309: g.drawLine(2, v1 + v2, thickness - 2, v1 + v2);
1310: g.drawLine(thickness - 2, v1, thickness - 2, v1 + v2);
1311: }
1312: }
1313: g.setColor(c);
1314: }
1315:
1316: /**
1317: * The following multibuffering-related methods delegate to our
1318: * associated GraphicsConfig (X11 or GLX) to handle the appropriate
1319: * native windowing system specific actions.
1320: */
1321:
1322: public void createBuffers(int numBuffers, BufferCapabilities caps)
1323: throws AWTException {
1324: if (buffersLog.isLoggable(Level.FINE)) {
1325: buffersLog.fine("createBuffers(" + numBuffers + ", " + caps
1326: + ")");
1327: }
1328: backBuffer = graphicsConfig.createBackBuffer(this , numBuffers,
1329: caps);
1330: xBackBuffer = graphicsConfig.createBackBufferImage(target,
1331: backBuffer);
1332: }
1333:
1334: public void flip(BufferCapabilities.FlipContents flipAction) {
1335: if (buffersLog.isLoggable(Level.FINE)) {
1336: buffersLog.fine("flip(" + flipAction + ")");
1337: }
1338: if (backBuffer == 0) {
1339: throw new IllegalStateException(
1340: "Buffers have not been created");
1341: }
1342: graphicsConfig.flip(this , target, xBackBuffer, flipAction);
1343: }
1344:
1345: public Image getBackBuffer() {
1346: if (buffersLog.isLoggable(Level.FINE)) {
1347: buffersLog.fine("getBackBuffer()");
1348: }
1349: if (backBuffer == 0) {
1350: throw new IllegalStateException(
1351: "Buffers have not been created");
1352: }
1353: return xBackBuffer;
1354: }
1355:
1356: public void destroyBuffers() {
1357: if (buffersLog.isLoggable(Level.FINE)) {
1358: buffersLog.fine("destroyBuffers()");
1359: }
1360: graphicsConfig.destroyBackBuffer(backBuffer);
1361: backBuffer = 0;
1362: xBackBuffer = null;
1363: }
1364:
1365: // End of multi-buffering
1366:
1367: public void notifyTextComponentChange(boolean add) {
1368: Container parent = ComponentAccessor
1369: .getParent_NoClientCode(target);
1370: while (!(parent == null || parent instanceof java.awt.Frame || parent instanceof java.awt.Dialog)) {
1371: parent = ComponentAccessor.getParent_NoClientCode(parent);
1372: }
1373:
1374: /* FIX ME - FIX ME need to implement InputMethods
1375: if (parent instanceof java.awt.Frame ||
1376: parent instanceof java.awt.Dialog) {
1377: if (add)
1378: ((MInputMethodControl)parent.getPeer()).addTextComponent((MComponentPeer)this);
1379: else
1380: ((MInputMethodControl)parent.getPeer()).removeTextComponent((MComponentPeer)this);
1381: }
1382: */
1383: }
1384:
1385: /**
1386: * Returns true if this event is disabled and shouldn't be processed by window
1387: * Currently if target component is disabled the following event will be disabled on window:
1388: * ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify
1389: */
1390: protected boolean isEventDisabled(XEvent e) {
1391: enableLog
1392: .log(
1393: Level.FINEST,
1394: "Component is {1}, checking for disabled event {0}",
1395: new Object[] { e,
1396: (isEnabled() ? "enabled" : "disable") });
1397: if (!isEnabled()) {
1398: switch (e.get_type()) {
1399: case ButtonPress:
1400: case ButtonRelease:
1401: case KeyPress:
1402: case KeyRelease:
1403: case EnterNotify:
1404: case LeaveNotify:
1405: case MotionNotify:
1406: enableLog.log(Level.FINER, "Event {0} is disable",
1407: new Object[] { e });
1408: return true;
1409: }
1410: }
1411: switch (e.get_type()) {
1412: case MapNotify:
1413: case UnmapNotify:
1414: return true;
1415: }
1416: return super .isEventDisabled(e);
1417: }
1418:
1419: Color getPeerBackground() {
1420: return background;
1421: }
1422:
1423: Color getPeerForeground() {
1424: return foreground;
1425: }
1426:
1427: Font getPeerFont() {
1428: return font;
1429: }
1430:
1431: Dimension getPeerSize() {
1432: return new Dimension(width, height);
1433: }
1434:
1435: public void setBoundsOperation(int operation) {
1436: synchronized (getStateLock()) {
1437: if (boundsOperation == DEFAULT_OPERATION) {
1438: boundsOperation = operation;
1439: } else if (operation == RESET_OPERATION) {
1440: boundsOperation = DEFAULT_OPERATION;
1441: }
1442: }
1443: }
1444:
1445: static String operationToString(int operation) {
1446: switch (operation) {
1447: case SET_LOCATION:
1448: return "SET_LOCATION";
1449: case SET_SIZE:
1450: return "SET_SIZE";
1451: case SET_CLIENT_SIZE:
1452: return "SET_CLIENT_SIZE";
1453: default:
1454: case SET_BOUNDS:
1455: return "SET_BOUNDS";
1456: }
1457: }
1458:
1459: public void restack() {
1460: synchronized (target.getTreeLock()) {
1461: // Build the list of X windows in the window corresponding to this container
1462: // This list is already in correct Java stacking order
1463: Container cont = (Container) target;
1464: Vector order = new Vector(cont.getComponentCount());
1465: HashSet set = new HashSet();
1466:
1467: addTree(order, set, cont);
1468:
1469: XToolkit.awtLock();
1470: try {
1471: // Get the current list of X window in X window. Some of the windows
1472: // might be only native
1473: XQueryTree qt = new XQueryTree(getContentWindow());
1474: try {
1475: if (qt.execute() != 0) {
1476: if (qt.get_nchildren() != 0) {
1477: long pchildren = qt.get_children();
1478: int j = 0; // index to insert
1479: for (int i = 0; i < qt.get_nchildren(); i++) {
1480: Long w = Long.valueOf(Native.getLong(
1481: pchildren, i));
1482: if (!set.contains(w)) {
1483: set.add(w);
1484: order.add(j++, w);
1485: }
1486: }
1487: }
1488: }
1489:
1490: if (order.size() != 0) {
1491: // Create native array of the windows
1492: long windows = Native.allocateLongArray(order
1493: .size());
1494: Native.putLong(windows, order);
1495:
1496: // Restack native window according to the new order
1497: XlibWrapper.XRestackWindows(XToolkit
1498: .getDisplay(), windows, order.size());
1499:
1500: XlibWrapper.unsafe.freeMemory(windows);
1501: }
1502: } finally {
1503: qt.dispose();
1504: }
1505: } finally {
1506: XToolkit.awtUnlock();
1507: }
1508: }
1509: }
1510:
1511: public boolean isRestackSupported() {
1512: return true;
1513: }
1514:
1515: private void addTree(Collection order, Set set, Container cont) {
1516: for (int i = 0; i < cont.getComponentCount(); i++) {
1517: Component comp = cont.getComponent(i);
1518: ComponentPeer peer = comp.getPeer();
1519: if (peer instanceof XComponentPeer) {
1520: Long window = Long.valueOf(((XComponentPeer) peer)
1521: .getWindow());
1522: if (!set.contains(window)) {
1523: set.add(window);
1524: order.add(window);
1525: }
1526: } else if (comp instanceof Container) {
1527: // It is lightweight container, it might contain heavyweight components attached to this
1528: // peer
1529: addTree(order, set, (Container) comp);
1530: }
1531: }
1532: }
1533:
1534: /****** DropTargetPeer implementation ********************/
1535:
1536: public void addDropTarget(DropTarget dt) {
1537: Component comp = target;
1538: while (!(comp == null || comp instanceof Window)) {
1539: comp = comp.getParent();
1540: }
1541:
1542: if (comp instanceof Window) {
1543: XWindowPeer wpeer = (XWindowPeer) (comp.getPeer());
1544: if (wpeer != null) {
1545: wpeer.addDropTarget();
1546: }
1547: }
1548: }
1549:
1550: public void removeDropTarget(DropTarget dt) {
1551: Component comp = target;
1552: while (!(comp == null || comp instanceof Window)) {
1553: comp = comp.getParent();
1554: }
1555:
1556: if (comp instanceof Window) {
1557: XWindowPeer wpeer = (XWindowPeer) (comp.getPeer());
1558: if (wpeer != null) {
1559: wpeer.removeDropTarget();
1560: }
1561: }
1562: }
1563: }
|