0001: /*
0002: * Copyright 1995-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:
0026: package sun.awt.motif;
0027:
0028: import java.awt.*;
0029: import java.awt.peer.*;
0030: import java.awt.event.PaintEvent;
0031: import java.awt.event.MouseEvent;
0032: import java.awt.event.InputEvent;
0033:
0034: import sun.awt.*;
0035: import sun.awt.image.ToolkitImage;
0036: import sun.awt.image.SunVolatileImage;
0037: import java.awt.image.ImageProducer;
0038: import java.awt.image.ImageObserver;
0039: import java.awt.image.ColorModel;
0040: import java.awt.image.VolatileImage;
0041:
0042: import java.awt.dnd.DropTarget;
0043: import java.awt.dnd.peer.DropTargetPeer;
0044:
0045: import sun.java2d.SunGraphics2D;
0046: import sun.java2d.SurfaceData;
0047:
0048: import java.lang.reflect.Method;
0049:
0050: import java.util.logging.*;
0051:
0052: public/* REMIND: should not be public */
0053: abstract class MComponentPeer implements ComponentPeer, DropTargetPeer,
0054: X11ComponentPeer {
0055: private static final Logger focusLog = Logger
0056: .getLogger("sun.awt.motif.focus.MComponentPeer");
0057:
0058: private static final DebugHelper dbg = DebugHelper
0059: .create(MComponentPeer.class);
0060:
0061: Component target;
0062: long pData;
0063: long jniGlobalRef;
0064: protected X11GraphicsConfig graphicsConfig;
0065: SurfaceData surfaceData;
0066: int oldWidth = -1;
0067: int oldHeight = -1;
0068:
0069: private RepaintArea paintArea;
0070:
0071: boolean isLayouting = false;
0072: boolean paintPending = false;
0073:
0074: protected boolean disposed = false;
0075: private static int JAWT_LOCK_ERROR = 0x00000001;
0076: private static int JAWT_LOCK_CLIP_CHANGED = 0x00000002;
0077: private static int JAWT_LOCK_BOUNDS_CHANGED = 0x00000004;
0078: private static int JAWT_LOCK_SURFACE_CHANGED = 0x00000008;
0079: private int drawState = JAWT_LOCK_CLIP_CHANGED
0080: | JAWT_LOCK_BOUNDS_CHANGED | JAWT_LOCK_SURFACE_CHANGED;
0081:
0082: /* These are the enumerated types in awt_p.h*/
0083: static final int MOTIF_NA = 0;
0084: static final int MOTIF_V1 = 1;
0085: static final int MOTIF_V2 = 2;
0086:
0087: private Font font;
0088: private long backBuffer = 0;
0089: private VolatileImage xBackBuffer = null;
0090:
0091: static {
0092: initIDs();
0093: }
0094:
0095: /* initialize the fieldIDs of fields that may be accessed from C */
0096: private native static void initIDs();
0097:
0098: /* This will return the last state of a window. ie the specific
0099: * "gotcha" is that if you iconify a window its obscurity remains
0100: * unchanged. Current use of this is just in user-initiated scrolling.
0101: * If that use expands to more cases you may need to "and" this with
0102: * the value of the iconic state of a Frame.
0103: * Note that de-iconifying an X11 window DOES generate a new event
0104: * correctly notifying you of the new visibility of the window
0105: */
0106: public boolean isObscured() {
0107:
0108: Container container = (target instanceof Container) ? (Container) target
0109: : target.getParent();
0110:
0111: if (container == null) {
0112: return true;
0113: }
0114:
0115: Container parent;
0116: while ((parent = container.getParent()) != null) {
0117: container = parent;
0118: }
0119:
0120: if (container instanceof Window) {
0121: MWindowPeer wpeer = (MWindowPeer) (container.getPeer());
0122: if (wpeer != null) {
0123: return (wpeer.winAttr.visibilityState != MWindowAttributes.AWT_UNOBSCURED);
0124: }
0125: }
0126: return true;
0127: }
0128:
0129: public boolean canDetermineObscurity() {
0130: return true;
0131: }
0132:
0133: abstract void create(MComponentPeer parent);
0134:
0135: void create(MComponentPeer parent, Object arg) {
0136: create(parent);
0137: }
0138:
0139: void EFcreate(MComponentPeer parent, int x) {
0140: }
0141:
0142: native void pInitialize();
0143:
0144: native void pShow();
0145:
0146: native void pHide();
0147:
0148: native void pEnable();
0149:
0150: native void pDisable();
0151:
0152: native void pReshape(int x, int y, int width, int height);
0153:
0154: native void pDispose();
0155:
0156: native void pMakeCursorVisible();
0157:
0158: native Point pGetLocationOnScreen();
0159:
0160: native Point pGetLocationOnScreen2(Window win, MWindowPeer wpeer);
0161:
0162: native void pSetForeground(Color c);
0163:
0164: native void pSetBackground(Color c);
0165:
0166: private native void pSetFont(Font f);
0167:
0168: //Added for bug 4175560
0169: //Returns the native representation for the Color argument,
0170: //using the given GraphicsConfiguration.
0171: native int getNativeColor(Color clr, GraphicsConfiguration gc);
0172:
0173: // Returns the parent of the component, without invoking client
0174: // code. This must go through native code, because it invokes
0175: // private methods in the java.awt package, which we cannot
0176: // do from this package.
0177: static native Container getParent_NoClientCode(Component component);
0178:
0179: // Returns the parent of the component, without invoking client
0180: // code. This must go through native code, because it invokes
0181: // private methods in the java.awt package, which we cannot
0182: // do from this package.
0183: static native Component[] getComponents_NoClientCode(
0184: Container container);
0185:
0186: void initialize() {
0187: if (!target.isVisible()) {
0188: hide();
0189: }
0190: Color c;
0191: Font f;
0192: Cursor cursor;
0193:
0194: pInitialize();
0195:
0196: if ((c = target.getForeground()) != null) {
0197: setForeground(c);
0198: }
0199: if ((c = target.getBackground()) != null) {
0200: setBackground(c);
0201: }
0202: if ((f = target.getFont()) != null) {
0203: setFont(f);
0204: }
0205: pSetCursor(target.getCursor());
0206: if (!target.isEnabled()) {
0207: disable();
0208: }
0209: Rectangle r = target.getBounds();
0210: reshape(r.x, r.y, r.width, r.height);
0211: if (target.isVisible()) {
0212: show();
0213: }
0214:
0215: surfaceData = graphicsConfig.createSurfaceData(this );
0216: }
0217:
0218: public void init(Component target, Object arg) {
0219: this .target = target;
0220: this .paintArea = new RepaintArea();
0221:
0222: Container parent = MToolkit.getNativeContainer(target);
0223: MComponentPeer parentPeer = (MComponentPeer) MToolkit
0224: .targetToPeer(parent);
0225: create(parentPeer, arg);
0226:
0227: initialize();
0228: }
0229:
0230: MComponentPeer(Component target, Object arg) {
0231: init(target, arg);
0232: }
0233:
0234: MComponentPeer() {
0235: }
0236:
0237: public void init(Component target) {
0238: this .target = target;
0239: this .paintArea = new RepaintArea();
0240:
0241: Container parent = MToolkit.getNativeContainer(target);
0242: MComponentPeer parentPeer = (MComponentPeer) MToolkit
0243: .targetToPeer(parent);
0244: create(parentPeer);
0245:
0246: if (parent != null && parent instanceof ScrollPane) {
0247: MScrollPanePeer speer = (MScrollPanePeer) parentPeer;
0248: speer.setScrollChild(this );
0249: }
0250: initialize();
0251: }
0252:
0253: MComponentPeer(Component target) {
0254: init(target);
0255: }
0256:
0257: protected void finalize() throws Throwable {
0258: dispose();
0259: super .finalize();
0260: }
0261:
0262: public void setForeground(Color c) {
0263: pSetForeground(c);
0264: }
0265:
0266: public void setBackground(Color c) {
0267: pSetBackground(c);
0268: }
0269:
0270: public void updateCursorImmediately() {
0271: MGlobalCursorManager.getCursorManager()
0272: .updateCursorImmediately();
0273: }
0274:
0275: public void setFont(Font f) {
0276: ComponentPeer peer;
0277: if (f == null) {
0278: f = defaultFont;
0279: }
0280: pSetFont(f);
0281: if (target instanceof Container) {
0282: Container container = (Container) target;
0283: int count = container.getComponentCount();
0284: Component[] children = container.getComponents();
0285: for (int i = 0; i < count; i++) {
0286: if (children[i] != null) {
0287: /*
0288: ** note: recursion in the widget in pSetFont() has by now broken any
0289: ** children with different Fonts - so fix now:
0290: */
0291: peer = children[i].getPeer();
0292: if (peer != null) {
0293: Font rightFont = children[i].getFont();
0294: if (!f.equals(rightFont)) {
0295: peer.setFont(rightFont);
0296: } else if (children[i] instanceof Container) {
0297: peer.setFont(f);
0298: }
0299: }
0300: }
0301: }
0302: }
0303:
0304: /*
0305: * Keep a reference to the java.awt.Font object in order to
0306: * preserve the XFontStructs which underlying widgets are using.
0307: * Save this AFTER changing the widgets in order to keep the
0308: * previous reference (if any) alive.
0309: */
0310: font = f;
0311: }
0312:
0313: public native void setTargetBackground(Color c);
0314:
0315: public native void pSetCursor(Cursor c);
0316:
0317: public native void pSetScrollbarBackground(Color c);
0318:
0319: public native void pSetInnerForeground(Color c);
0320:
0321: public boolean isFocusable() {
0322: return false;
0323: }
0324:
0325: public SurfaceData getSurfaceData() {
0326: return surfaceData;
0327: }
0328:
0329: public ColorModel getColorModel() {
0330: return graphicsConfig.getColorModel();
0331: }
0332:
0333: public ColorModel getColorModel(int transparency) {
0334: return graphicsConfig.getColorModel(transparency);
0335: }
0336:
0337: public int updatePriority() {
0338: return Thread.NORM_PRIORITY;
0339: }
0340:
0341: public void repaint(long tm, int x, int y, int width, int height) {
0342: }
0343:
0344: public void paint(Graphics g) {
0345: Dimension d = target.getSize();
0346: if (g instanceof Graphics2D
0347: || g instanceof sun.awt.Graphics2Delegate) {
0348: // background color is setup correctly, so just use clearRect
0349: g.clearRect(0, 0, d.width, d.height);
0350: } else {
0351: // emulate clearRect
0352: g.setColor(target.getBackground());
0353: g.fillRect(0, 0, d.width, d.height);
0354: g.setColor(target.getForeground());
0355: }
0356:
0357: target.paint(g);
0358: }
0359:
0360: public void print(Graphics g) {
0361: Dimension d = target.getSize();
0362: if (g instanceof Graphics2D
0363: || g instanceof sun.awt.Graphics2Delegate) {
0364: // background color is setup correctly, so just use clearRect
0365: g.clearRect(0, 0, d.width, d.height);
0366: } else {
0367: // emulate clearRect
0368: g.setColor(target.getBackground());
0369: g.fillRect(0, 0, d.width, d.height);
0370: g.setColor(target.getForeground());
0371: }
0372:
0373: target.print(g);
0374: }
0375:
0376: public void coalescePaintEvent(PaintEvent e) {
0377: Rectangle r = e.getUpdateRect();
0378: paintArea.add(r, e.getID());
0379:
0380: if (dbg.on) {
0381: switch (e.getID()) {
0382: case PaintEvent.UPDATE:
0383: dbg
0384: .println("MCP coalescePaintEvent : UPDATE : add : x = "
0385: + r.x
0386: + ", y = "
0387: + r.y
0388: + ", width = "
0389: + r.width + ",height = " + r.height);
0390: return;
0391: case PaintEvent.PAINT:
0392: dbg
0393: .println("MCP coalescePaintEvent : PAINT : add : x = "
0394: + r.x
0395: + ", y = "
0396: + r.y
0397: + ", width = "
0398: + r.width + ",height = " + r.height);
0399: return;
0400: }
0401: }
0402: }
0403:
0404: native void nativeHandleEvent(AWTEvent e);
0405:
0406: /**
0407: * Returns whether or not this component should be given focus on mouse click.
0408: * Default implementation return whether or not this peer is "focusable"
0409: * Descendants might want to override it to extend/restrict conditions at which this
0410: * component should be focused by click (see MCanvasPeer and MPanelPeer)
0411: */
0412: protected boolean shouldFocusOnClick() {
0413: return isFocusable();
0414: }
0415:
0416: /**
0417: * Checks whether or not this component would be focused by native system if it would be allowed to do so.
0418: * Currently it checks that it displayable, visible, enabled and focusable.
0419: */
0420: static boolean canBeFocusedByClick(Component component) {
0421: if (component == null) {
0422: return false;
0423: } else {
0424: return component.isDisplayable() && component.isVisible()
0425: && component.isEnabled() && component.isFocusable();
0426: }
0427: }
0428:
0429: static Method requestFocusWithCause;
0430:
0431: static void callRequestFocusInWindow(Component target,
0432: CausedFocusEvent.Cause cause) {
0433: if (requestFocusWithCause == null) {
0434: requestFocusWithCause = SunToolkit.getMethod(
0435: Component.class, "requestFocusInWindow",
0436: new Class[] { CausedFocusEvent.Cause.class });
0437: }
0438: if (requestFocusWithCause != null) {
0439: try {
0440: requestFocusWithCause.invoke(target,
0441: new Object[] { cause });
0442: } catch (Exception e) {
0443: e.printStackTrace();
0444: }
0445: }
0446: }
0447:
0448: public void handleEvent(AWTEvent e) {
0449: int id = e.getID();
0450:
0451: switch (id) {
0452: case PaintEvent.PAINT:
0453: // Got native painting
0454: paintPending = false;
0455: // Fallthrough to next statement
0456: case PaintEvent.UPDATE:
0457: // Skip all painting while layouting and all UPDATEs
0458: // while waiting for native paint
0459: if (!isLayouting && !paintPending) {
0460: paintArea.paint(target, false);
0461: }
0462: return;
0463: case MouseEvent.MOUSE_PRESSED:
0464: if (target == e.getSource()
0465: && !((InputEvent) e).isConsumed()
0466: && shouldFocusOnClick() && !target.isFocusOwner()
0467: && canBeFocusedByClick(target)) {
0468: callRequestFocusInWindow(target,
0469: CausedFocusEvent.Cause.MOUSE_EVENT);
0470: }
0471: break;
0472: default:
0473: break;
0474: }
0475:
0476: // Call the native code
0477: nativeHandleEvent(e);
0478: }
0479:
0480: /* New API for 1.1 */
0481: public Dimension getMinimumSize() {
0482: return target.getSize();
0483: }
0484:
0485: /* New API for 1.1 */
0486: public Dimension getPreferredSize() {
0487: return getMinimumSize();
0488: }
0489:
0490: // Do nothing for heavyweight implementation
0491: public void layout() {
0492: }
0493:
0494: public Rectangle getBounds() {
0495: return ((Component) target).getBounds();
0496: }
0497:
0498: public Object getTarget() {
0499: return target;
0500: }
0501:
0502: public java.awt.Toolkit getToolkit() {
0503: // XXX: bogus
0504: return Toolkit.getDefaultToolkit();
0505: }
0506:
0507: // fallback default font object
0508: final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN,
0509: 12);
0510:
0511: public synchronized Graphics getGraphics() {
0512: if (!disposed) {
0513: Component target = (Component) this .target;
0514:
0515: /* Fix for bug 4746122. Color and Font shouldn't be null */
0516: Color bgColor = target.getBackground();
0517: if (bgColor == null) {
0518: bgColor = SystemColor.window;
0519: }
0520: Color fgColor = target.getForeground();
0521: if (fgColor == null) {
0522: fgColor = SystemColor.windowText;
0523: }
0524: Font font = target.getFont();
0525: if (font == null) {
0526: font = defaultFont;
0527: }
0528: return new SunGraphics2D(surfaceData, fgColor, bgColor,
0529: font);
0530: }
0531:
0532: return null;
0533: }
0534:
0535: public Image createImage(ImageProducer producer) {
0536: return new ToolkitImage(producer);
0537: }
0538:
0539: public Image createImage(int width, int height) {
0540: return graphicsConfig.createAcceleratedImage(target, width,
0541: height);
0542: }
0543:
0544: public VolatileImage createVolatileImage(int width, int height) {
0545: return new SunVolatileImage(target, width, height);
0546: }
0547:
0548: public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
0549: return getToolkit().prepareImage(img, w, h, o);
0550: }
0551:
0552: public int checkImage(Image img, int w, int h, ImageObserver o) {
0553: return getToolkit().checkImage(img, w, h, o);
0554: }
0555:
0556: public FontMetrics getFontMetrics(Font font) {
0557: return X11FontMetrics.getFontMetrics(font);
0558: }
0559:
0560: /*
0561: * Subclasses should override disposeImpl() instead of dispose(). Client
0562: * code should always invoke dispose(), never disposeImpl().
0563: */
0564: protected void disposeImpl() {
0565: SurfaceData oldData = surfaceData;
0566: surfaceData = null;
0567: oldData.invalidate();
0568: MToolkit.targetDisposedPeer(target, this );
0569: pDispose();
0570: }
0571:
0572: public final void dispose() {
0573: boolean call_disposeImpl = false;
0574:
0575: if (!disposed) {
0576: synchronized (this ) {
0577: SunToolkit.awtLock();
0578: try {
0579: if (!disposed) {
0580: disposed = call_disposeImpl = true;
0581: }
0582: } finally {
0583: SunToolkit.awtUnlock();
0584: }
0585: }
0586: }
0587:
0588: if (call_disposeImpl) {
0589: disposeImpl();
0590: }
0591: }
0592:
0593: native static boolean processSynchronousLightweightTransfer(
0594: Component heavyweight, Component descendant,
0595: boolean temporary, boolean focusedWindowChangeAllowed,
0596: long time);
0597:
0598: public boolean requestFocus(Component lightweightChild,
0599: boolean temporary, boolean focusedWindowChangeAllowed,
0600: long time, CausedFocusEvent.Cause cause) {
0601: if (processSynchronousLightweightTransfer((Component) target,
0602: lightweightChild, temporary,
0603: focusedWindowChangeAllowed, time)) {
0604: return true;
0605: } else {
0606: if (focusLog.isLoggable(Level.FINER))
0607: focusLog.finer("Current native focused window "
0608: + getNativeFocusedWindow());
0609: /**
0610: * The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight
0611: * checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet
0612: * been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record
0613: * in requests list - and it breaks our requests sequence as first record on WGF should be the last focus
0614: * owner which had focus before WLF. So, we should not add request record for such requests
0615: * but store this component in mostRecent - and return true as before for compatibility.
0616: */
0617: Container parent = (target instanceof Container) ? ((Container) target)
0618: : (target.getParent());
0619: // Search for parent window
0620: while (parent != null && !(parent instanceof Window)) {
0621: parent = getParent_NoClientCode(parent);
0622: }
0623: if (parent != null) {
0624: Window parentWindow = (Window) parent;
0625: // and check that it is focused
0626: if (focusLog.isLoggable(Level.FINER))
0627: focusLog.finer("Parent window " + parentWindow);
0628: if (!parentWindow.isFocused()
0629: && getNativeFocusedWindow() == parentWindow) {
0630: // if it is not - skip requesting focus on Solaris
0631: // but return true for compatibility.
0632: return true;
0633: } else if (getNativeFocusedWindow() != parentWindow) {
0634: WindowPeer wpeer = (WindowPeer) parentWindow
0635: .getPeer();
0636: boolean res = wpeer.requestWindowFocus();
0637: if (focusLog.isLoggable(Level.FINER))
0638: focusLog
0639: .finer("Requested window focus: " + res);
0640: // If parent window can be made focused and has been made focused(synchronously)
0641: // then we can proceed with children, otherwise we retreat.
0642: if (!(res && parentWindow.isFocused())) {
0643: focusLog
0644: .finer("Waiting for asynchronous processing of window focus request");
0645: KeyboardFocusManagerPeerImpl
0646: .removeLastFocusRequest(target);
0647: return false;
0648: }
0649: }
0650: }
0651: return _requestFocus(lightweightChild, temporary,
0652: focusedWindowChangeAllowed, time, cause);
0653: }
0654: }
0655:
0656: native boolean _requestFocus(Component lightweightChild,
0657: boolean temporary, boolean focusedWindowChangeAllowed,
0658: long time, CausedFocusEvent.Cause cause);
0659:
0660: static native Window getNativeFocusedWindow();
0661:
0662: /*
0663: * Post an event to the event queue.
0664: */
0665: // NOTE: This method may be called by privileged threads.
0666: // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0667: void postEvent(AWTEvent event) {
0668: MToolkit.postEvent(MToolkit.targetToAppContext(target), event);
0669: }
0670:
0671: /* Callbacks for window-system events to the frame
0672: *
0673: * NOTE: This method may be called by privileged threads.
0674: * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0675: */
0676: void handleExpose(int x, int y, int w, int h) {
0677: if (!ComponentAccessor.getIgnoreRepaint(target)) {
0678: postEvent(new PaintEvent(target, PaintEvent.PAINT,
0679: new Rectangle(x, y, w, h)));
0680: }
0681: }
0682:
0683: /* Callbacks for window-system events to the frame
0684: *
0685: * NOTE: This method may be called by privileged threads.
0686: * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0687: */
0688: void handleRepaint(int x, int y, int w, int h) {
0689: if (!ComponentAccessor.getIgnoreRepaint(target)) {
0690: postEvent(new PaintEvent(target, PaintEvent.UPDATE,
0691: new Rectangle(x, y, w, h)));
0692: }
0693: }
0694:
0695: /* Return the component's z-order position relative to
0696: * other peer'd siblings (don't count lightweight siblings
0697: * or siblings who don't yet have valid peers).
0698: *
0699: * NOTE: This method may be called by privileged threads.
0700: * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0701: */
0702: public int getZOrderPosition_NoClientCode() {
0703: // SECURITY: use _NoClientCode() methods, because we may
0704: // be running on a privileged thread
0705: Container p = getParent_NoClientCode(target);
0706: if (p != null) {
0707: // SECURITY: use _NoClientCode() methods, because we may
0708: // be running on a privileged thread
0709: Component children[] = getComponents_NoClientCode(p);
0710: int i;
0711: int index = 0;
0712: for (i = 0; i < children.length; i++) {
0713: if (children[i] == target) {
0714: return index;
0715: } else {
0716: Object cpeer = MToolkit.targetToPeer(children[i]);
0717: if (cpeer != null
0718: && !(cpeer instanceof java.awt.peer.LightweightPeer)) {
0719: index++;
0720: }
0721: }
0722: }
0723: }
0724: return -1;
0725: }
0726:
0727: /*
0728: * drawXXX() methods are used to print the native components by
0729: * rendering the Motif look ourselves.
0730: * ToDo(aim): needs to query native motif for more accurate color
0731: * information.
0732: */
0733: void draw3DOval(Graphics g, Color bg, int x, int y, int w, int h,
0734: boolean raised) {
0735: Color c = g.getColor();
0736: Color shadow = bg.darker();
0737: Color highlight = bg.brighter();
0738:
0739: g.setColor(raised ? highlight : shadow);
0740: g.drawArc(x, y, w, h, 45, 180);
0741: g.setColor(raised ? shadow : highlight);
0742: g.drawArc(x, y, w, h, 225, 180);
0743: g.setColor(c);
0744: }
0745:
0746: void draw3DRect(Graphics g, Color bg, int x, int y, int width,
0747: int height, boolean raised) {
0748: Color c = g.getColor();
0749: Color shadow = bg.darker();
0750: Color highlight = bg.brighter();
0751:
0752: g.setColor(raised ? highlight : shadow);
0753: g.drawLine(x, y, x, y + height);
0754: g.drawLine(x + 1, y, x + width - 1, y);
0755: g.setColor(raised ? shadow : highlight);
0756: g.drawLine(x + 1, y + height, x + width, y + height);
0757: g.drawLine(x + width, y, x + width, y + height - 1);
0758: g.setColor(c);
0759: }
0760:
0761: void drawScrollbar(Graphics g, Color bg, int thickness, int length,
0762: int min, int max, int val, int vis, boolean horizontal) {
0763: Color c = g.getColor();
0764: double f = (double) (length - 2 * (thickness - 1))
0765: / Math.max(1, ((max - min) + vis));
0766: int v1 = thickness + (int) (f * (val - min));
0767: int v2 = (int) (f * vis);
0768: int w2 = thickness - 4;
0769: int tpts_x[] = new int[3];
0770: int tpts_y[] = new int[3];
0771:
0772: if (length < 3 * w2) {
0773: v1 = v2 = 0;
0774: if (length < 2 * w2 + 2) {
0775: w2 = (length - 2) / 2;
0776: }
0777: } else if (v2 < 7) {
0778: // enforce a minimum handle size
0779: v1 = Math.max(0, v1 - ((7 - v2) >> 1));
0780: v2 = 7;
0781: }
0782:
0783: int ctr = thickness / 2;
0784: int sbmin = ctr - w2 / 2;
0785: int sbmax = ctr + w2 / 2;
0786:
0787: // paint the background slightly darker
0788: {
0789: Color d = new Color((int) (bg.getRed() * 0.85), (int) (bg
0790: .getGreen() * 0.85), (int) (bg.getBlue() * 0.85));
0791:
0792: g.setColor(d);
0793: if (horizontal) {
0794: g.fillRect(0, 0, length, thickness);
0795: } else {
0796: g.fillRect(0, 0, thickness, length);
0797: }
0798: }
0799:
0800: // paint the thumb and arrows in the normal background color
0801: g.setColor(bg);
0802: if (v1 > 0) {
0803: if (horizontal) {
0804: g.fillRect(v1, 3, v2, thickness - 3);
0805: } else {
0806: g.fillRect(3, v1, thickness - 3, v2);
0807: }
0808: }
0809:
0810: tpts_x[0] = ctr;
0811: tpts_y[0] = 2;
0812: tpts_x[1] = sbmin;
0813: tpts_y[1] = w2;
0814: tpts_x[2] = sbmax;
0815: tpts_y[2] = w2;
0816: if (horizontal) {
0817: g.fillPolygon(tpts_y, tpts_x, 3);
0818: } else {
0819: g.fillPolygon(tpts_x, tpts_y, 3);
0820: }
0821:
0822: tpts_y[0] = length - 2;
0823: tpts_y[1] = length - w2;
0824: tpts_y[2] = length - w2;
0825: if (horizontal) {
0826: g.fillPolygon(tpts_y, tpts_x, 3);
0827: } else {
0828: g.fillPolygon(tpts_x, tpts_y, 3);
0829: }
0830:
0831: Color highlight = bg.brighter();
0832:
0833: // // // // draw the "highlighted" edges
0834: g.setColor(highlight);
0835:
0836: // outline & arrows
0837: if (horizontal) {
0838: g.drawLine(1, thickness, length - 1, thickness);
0839: g.drawLine(length - 1, 1, length - 1, thickness);
0840:
0841: // arrows
0842: g.drawLine(1, ctr, w2, sbmin);
0843: g.drawLine(length - w2, sbmin, length - w2, sbmax);
0844: g.drawLine(length - w2, sbmin, length - 2, ctr);
0845:
0846: } else {
0847: g.drawLine(thickness, 1, thickness, length - 1);
0848: g.drawLine(1, length - 1, thickness, length - 1);
0849:
0850: // arrows
0851: g.drawLine(ctr, 1, sbmin, w2);
0852: g.drawLine(sbmin, length - w2, sbmax, length - w2);
0853: g.drawLine(sbmin, length - w2, ctr, length - 2);
0854: }
0855:
0856: // thumb
0857: if (v1 > 0) {
0858: if (horizontal) {
0859: g.drawLine(v1, 2, v1 + v2, 2);
0860: g.drawLine(v1, 2, v1, thickness - 3);
0861: } else {
0862: g.drawLine(2, v1, 2, v1 + v2);
0863: g.drawLine(2, v1, thickness - 3, v1);
0864: }
0865: }
0866:
0867: Color shadow = bg.darker();
0868:
0869: // // // // draw the "shadowed" edges
0870: g.setColor(shadow);
0871:
0872: // outline && arrows
0873: if (horizontal) {
0874: g.drawLine(0, 0, 0, thickness);
0875: g.drawLine(0, 0, length - 1, 0);
0876:
0877: // arrows
0878: g.drawLine(w2, sbmin, w2, sbmax);
0879: g.drawLine(w2, sbmax, 1, ctr);
0880: g.drawLine(length - 2, ctr, length - w2, sbmax);
0881:
0882: } else {
0883: g.drawLine(0, 0, thickness, 0);
0884: g.drawLine(0, 0, 0, length - 1);
0885:
0886: // arrows
0887: g.drawLine(sbmin, w2, sbmax, w2);
0888: g.drawLine(sbmax, w2, ctr, 1);
0889: g.drawLine(ctr, length - 2, sbmax, length - w2);
0890: }
0891:
0892: // thumb
0893: if (v1 > 0) {
0894: if (horizontal) {
0895: g.drawLine(v1 + v2, 2, v1 + v2, thickness - 2);
0896: g.drawLine(v1, thickness - 2, v1 + v2, thickness - 2);
0897: } else {
0898: g.drawLine(2, v1 + v2, thickness - 2, v1 + v2);
0899: g.drawLine(thickness - 2, v1, thickness - 2, v1 + v2);
0900: }
0901: }
0902: g.setColor(c);
0903: }
0904:
0905: public String toString() {
0906: return getClass().getName() + "[" + target + "]";
0907: }
0908:
0909: /* New 1.1 API */
0910: public void setVisible(boolean b) {
0911: if (b) {
0912: Dimension s = target.getSize();
0913: oldWidth = s.width;
0914: oldHeight = s.height;
0915: pShow();
0916: } else {
0917: pHide();
0918: }
0919: }
0920:
0921: /* New 1.1 API */
0922: public void setEnabled(boolean b) {
0923: if (b) {
0924: pEnable();
0925: } else {
0926: pDisable();
0927: }
0928: }
0929:
0930: /* New 1.1 API */
0931: public Point getLocationOnScreen() {
0932: synchronized (target.getTreeLock()) {
0933: Component comp = target;
0934: while (comp != null && !(comp instanceof Window)) {
0935: comp = getParent_NoClientCode(comp);
0936: }
0937:
0938: // applets, embedded, etc - translate directly
0939: if (comp == null || comp instanceof sun.awt.EmbeddedFrame) {
0940: return pGetLocationOnScreen();
0941: }
0942:
0943: MWindowPeer wpeer = (MWindowPeer) (MToolkit
0944: .targetToPeer(comp));
0945: if (wpeer == null) {
0946: return pGetLocationOnScreen();
0947: }
0948: return pGetLocationOnScreen2((Window) comp, wpeer);
0949: }
0950: }
0951:
0952: public int serialNum = 0;
0953:
0954: /* Returns the native paint should be posted after setting new size
0955: */
0956: public boolean checkNativePaintOnSetBounds(int width, int height) {
0957: return (width != oldWidth) || (height != oldHeight);
0958: }
0959:
0960: void setBounds(int x, int y, int width, int height) {
0961: setBounds(x, y, width, height, SET_BOUNDS);
0962: }
0963:
0964: /* New 1.1 API */
0965: public void setBounds(int x, int y, int width, int height, int op) {
0966: if (disposed)
0967: return;
0968:
0969: Container parent = getParent_NoClientCode(target);
0970:
0971: // Should set paintPending before reshape to prevent
0972: // thread race between PaintEvent and setBounds
0973: // This part of the 4267393 fix proved to be unstable under solaris,
0974: // dissabled due to regressions 4418155, 4486762, 4490079
0975: paintPending = false; //checkNativePaintOnSetBounds(width, height);
0976:
0977: // Note: it would be ideal to NOT execute this if it's
0978: // merely a Move which is occurring.
0979: if (parent != null && parent instanceof ScrollPane) {
0980: MScrollPanePeer speer = (MScrollPanePeer) parent.getPeer();
0981: if (!speer.ignore) {
0982: pReshape(x, y, width, height);
0983: speer.childResized(width, height);
0984: }
0985: } else {
0986: pReshape(x, y, width, height);
0987: }
0988:
0989: if ((width != oldWidth) || (height != oldHeight)) {
0990: SurfaceData oldData = surfaceData;
0991: if (oldData != null) {
0992: surfaceData = graphicsConfig.createSurfaceData(this );
0993: oldData.invalidate();
0994: }
0995: oldWidth = width;
0996: oldHeight = height;
0997: }
0998: validateSurface(width, height);
0999: serialNum++;
1000: }
1001:
1002: void validateSurface(int width, int height) {
1003: SunToolkit.awtLock();
1004: try {
1005: if (!disposed && (width != oldWidth || height != oldHeight)) {
1006: SurfaceData oldData = surfaceData;
1007: if (oldData != null) {
1008: surfaceData = graphicsConfig
1009: .createSurfaceData(this );
1010: oldData.invalidate();
1011: }
1012: oldWidth = width;
1013: oldHeight = height;
1014: }
1015: } finally {
1016: SunToolkit.awtUnlock();
1017: }
1018: }
1019:
1020: public void beginValidate() {
1021: }
1022:
1023: native void restoreFocus();
1024:
1025: public void endValidate() {
1026: restoreFocus();
1027: }
1028:
1029: public void beginLayout() {
1030: // Skip all painting till endLayout
1031: isLayouting = true;
1032: }
1033:
1034: public void endLayout() {
1035: if (!paintPending && !paintArea.isEmpty()
1036: && !((Component) target).getIgnoreRepaint()) {
1037: // if not waiting for native painting repaint damaged area
1038: postEvent(new PaintEvent((Component) target,
1039: PaintEvent.PAINT, new Rectangle()));
1040: }
1041: isLayouting = false;
1042: }
1043:
1044: /**
1045: * DEPRECATED: Replaced by setVisible(boolean).
1046: */
1047: public void show() {
1048: setVisible(true);
1049: }
1050:
1051: /**
1052: * DEPRECATED: Replaced by setVisible(boolean).
1053: */
1054: public void hide() {
1055: setVisible(false);
1056: }
1057:
1058: /**
1059: * DEPRECATED: Replaced by setEnabled(boolean).
1060: */
1061: public void enable() {
1062: setEnabled(true);
1063: }
1064:
1065: /**
1066: * DEPRECATED: Replaced by setEnabled(boolean).
1067: */
1068: public void disable() {
1069: setEnabled(false);
1070: }
1071:
1072: /**
1073: * DEPRECATED: Replaced by setBounds(int, int, int, int).
1074: */
1075: public void reshape(int x, int y, int width, int height) {
1076: setBounds(x, y, width, height);
1077: }
1078:
1079: /**
1080: * DEPRECATED: Replaced by getMinimumSize().
1081: */
1082: public Dimension minimumSize() {
1083: return getMinimumSize();
1084: }
1085:
1086: /**
1087: * DEPRECATED: Replaced by getPreferredSize().
1088: */
1089: public Dimension preferredSize() {
1090: return getPreferredSize();
1091: }
1092:
1093: /**
1094: *
1095: */
1096:
1097: public void addDropTarget(DropTarget dt) {
1098: if (MToolkit.useMotifDnD()) {
1099: addNativeDropTarget(dt);
1100: } else {
1101: Component comp = target;
1102: while (!(comp == null || comp instanceof java.awt.Window)) {
1103: comp = getParent_NoClientCode(comp);
1104: }
1105:
1106: if (comp instanceof Window) {
1107: MWindowPeer wpeer = (MWindowPeer) (comp.getPeer());
1108: if (wpeer != null) {
1109: wpeer.addDropTarget();
1110: }
1111: }
1112: }
1113: }
1114:
1115: /**
1116: *
1117: */
1118:
1119: public void removeDropTarget(DropTarget dt) {
1120: if (MToolkit.useMotifDnD()) {
1121: removeNativeDropTarget(dt);
1122: } else {
1123: Component comp = target;
1124: while (!(comp == null || comp instanceof java.awt.Window)) {
1125: comp = getParent_NoClientCode(comp);
1126: }
1127:
1128: if (comp instanceof Window) {
1129: MWindowPeer wpeer = (MWindowPeer) (comp.getPeer());
1130: if (wpeer != null) {
1131: wpeer.removeDropTarget();
1132: }
1133: }
1134: }
1135: }
1136:
1137: public void notifyTextComponentChange(boolean add) {
1138: Container parent = getParent_NoClientCode(target);
1139: while (!(parent == null || parent instanceof java.awt.Frame || parent instanceof java.awt.Dialog)) {
1140: parent = getParent_NoClientCode(parent);
1141: }
1142:
1143: if (parent instanceof java.awt.Frame
1144: || parent instanceof java.awt.Dialog) {
1145: if (add)
1146: ((MInputMethodControl) parent.getPeer())
1147: .addTextComponent((MComponentPeer) this );
1148: else
1149: ((MInputMethodControl) parent.getPeer())
1150: .removeTextComponent((MComponentPeer) this );
1151: }
1152: }
1153:
1154: native void addNativeDropTarget(DropTarget dt);
1155:
1156: native void removeNativeDropTarget(DropTarget dt);
1157:
1158: public GraphicsConfiguration getGraphicsConfiguration() {
1159: GraphicsConfiguration ret = graphicsConfig;
1160: if (ret == null) {
1161: ret = target.getGraphicsConfiguration();
1162: }
1163: return ret;
1164: }
1165:
1166: // Returns true if we are inside begin/endLayout and
1167: // are waiting for native painting
1168: public boolean isPaintPending() {
1169: return paintPending && isLayouting;
1170: }
1171:
1172: public boolean handlesWheelScrolling() {
1173: return false;
1174: }
1175:
1176: /**
1177: * The following multibuffering-related methods delegate to our
1178: * associated GraphicsConfig (X11 or GLX) to handle the appropriate
1179: * native windowing system specific actions.
1180: */
1181:
1182: private native long getWindow(long pData);
1183:
1184: public long getContentWindow() {
1185: return getWindow(pData);
1186: }
1187:
1188: public void createBuffers(int numBuffers, BufferCapabilities caps)
1189: throws AWTException {
1190: backBuffer = graphicsConfig.createBackBuffer(this , numBuffers,
1191: caps);
1192: xBackBuffer = graphicsConfig.createBackBufferImage(target,
1193: backBuffer);
1194: }
1195:
1196: public void flip(BufferCapabilities.FlipContents flipAction) {
1197: if (backBuffer == 0) {
1198: throw new IllegalStateException(
1199: "Buffers have not been created");
1200: }
1201: graphicsConfig.flip(this , target, xBackBuffer, flipAction);
1202: }
1203:
1204: public Image getBackBuffer() {
1205: if (backBuffer == 0) {
1206: throw new IllegalStateException(
1207: "Buffers have not been created");
1208: }
1209: return xBackBuffer;
1210: }
1211:
1212: public void destroyBuffers() {
1213: graphicsConfig.destroyBackBuffer(backBuffer);
1214: backBuffer = 0;
1215: xBackBuffer = null;
1216: }
1217:
1218: /**
1219: * @see java.awt.peer.ComponentPeer#isReparentSupported
1220: */
1221: public boolean isReparentSupported() {
1222: return false;
1223: }
1224:
1225: /**
1226: * @see java.awt.peer.ComponentPeer#reparent
1227: */
1228: public void reparent(ContainerPeer newNativeParent) {
1229: throw new UnsupportedOperationException();
1230: }
1231: }
|