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:
0026: package sun.awt.X11;
0027:
0028: import java.awt.*;
0029: import java.awt.event.*;
0030: import java.awt.peer.ComponentPeer;
0031: import java.awt.image.ColorModel;
0032:
0033: import java.lang.ref.WeakReference;
0034:
0035: import java.lang.reflect.Field;
0036: import java.lang.reflect.Method;
0037:
0038: import java.util.logging.Level;
0039: import java.util.logging.Logger;
0040:
0041: import sun.awt.*;
0042:
0043: import sun.awt.image.PixelConverter;
0044:
0045: import sun.java2d.SunGraphics2D;
0046: import sun.java2d.SurfaceData;
0047:
0048: public class XWindow extends XBaseWindow implements X11ComponentPeer {
0049: private static Logger log = Logger.getLogger("sun.awt.X11.XWindow");
0050: private static Logger insLog = Logger
0051: .getLogger("sun.awt.X11.insets.XWindow");
0052: private static Logger eventLog = Logger
0053: .getLogger("sun.awt.X11.event.XWindow");
0054: private static final Logger focusLog = Logger
0055: .getLogger("sun.awt.X11.focus.XWindow");
0056: private static Logger keyEventLog = Logger
0057: .getLogger("sun.awt.X11.kye.XWindow");
0058: /* If a motion comes in while a multi-click is pending,
0059: * allow a smudge factor so that moving the mouse by a small
0060: * amount does not wipe out the multi-click state variables.
0061: */
0062: private final static int AWT_MULTICLICK_SMUDGE = 4;
0063: // ButtonXXX events stuff
0064: static int rbutton = 0;
0065: static int lastX = 0, lastY = 0;
0066: static long lastTime = 0;
0067: static long lastButton = 0;
0068: static WeakReference lastWindowRef = null;
0069: static int clickCount = 0;
0070:
0071: // used to check if we need to re-create surfaceData.
0072: int oldWidth = -1;
0073: int oldHeight = -1;
0074:
0075: protected X11GraphicsConfig graphicsConfig;
0076: protected AwtGraphicsConfigData graphicsConfigData;
0077:
0078: private boolean reparented;
0079:
0080: XWindow parent;
0081:
0082: Component target;
0083:
0084: private static int JAWT_LOCK_ERROR = 0x00000001;
0085: private static int JAWT_LOCK_CLIP_CHANGED = 0x00000002;
0086: private static int JAWT_LOCK_BOUNDS_CHANGED = 0x00000004;
0087: private static int JAWT_LOCK_SURFACE_CHANGED = 0x00000008;
0088: private int drawState = JAWT_LOCK_CLIP_CHANGED
0089: | JAWT_LOCK_BOUNDS_CHANGED | JAWT_LOCK_SURFACE_CHANGED;
0090:
0091: public static final String TARGET = "target",
0092: REPARENTED = "reparented"; // whether it is reparented by default
0093:
0094: SurfaceData surfaceData;
0095:
0096: XRepaintArea paintArea;
0097: // fallback default font object
0098: final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN,
0099: 12);
0100:
0101: /*
0102: * Keeps all buttons which were pressed at the time of the last mouse
0103: * drag until all buttons will be released, contains state as bit masks
0104: * Button1Mask, Button2Mask, Button3Mask
0105: */
0106: private int mouseDragState = 0;
0107:
0108: native int getNativeColor(Color clr, GraphicsConfiguration gc);
0109:
0110: native void getWMInsets(long window, long left, long top,
0111: long right, long bottom, long border);
0112:
0113: native long getTopWindow(long window, long rootWin);
0114:
0115: native void getWindowBounds(long window, long x, long y,
0116: long width, long height);
0117:
0118: private native static void initIDs();
0119:
0120: private static Field isPostedField;
0121: static {
0122: initIDs();
0123: }
0124:
0125: XWindow(XCreateWindowParams params) {
0126: super (params);
0127: }
0128:
0129: XWindow() {
0130: }
0131:
0132: XWindow(long parentWindow, Rectangle bounds) {
0133: super (new XCreateWindowParams(new Object[] { BOUNDS, bounds,
0134: PARENT_WINDOW, Long.valueOf(parentWindow) }));
0135: }
0136:
0137: XWindow(Component target, long parentWindow, Rectangle bounds) {
0138: super (new XCreateWindowParams(new Object[] { BOUNDS, bounds,
0139: PARENT_WINDOW, Long.valueOf(parentWindow), TARGET,
0140: target }));
0141: }
0142:
0143: XWindow(Component target, long parentWindow) {
0144: this (target, parentWindow, target.getBounds());
0145: }
0146:
0147: XWindow(Component target) {
0148: this (target, (target.getParent() == null) ? 0
0149: : getParentWindowID(target), target.getBounds());
0150: }
0151:
0152: XWindow(Object target) {
0153: this (null, 0, null);
0154: }
0155:
0156: /* This create is used by the XEmbeddedFramePeer since it has to create the window
0157: as a child of the netscape window. This netscape window is passed in as wid */
0158: XWindow(long parentWindow) {
0159: super (new XCreateWindowParams(new Object[] { PARENT_WINDOW,
0160: Long.valueOf(parentWindow), REPARENTED, Boolean.TRUE,
0161: EMBEDDED, Boolean.TRUE }));
0162: }
0163:
0164: protected void initGraphicsConfiguration() {
0165: graphicsConfig = (X11GraphicsConfig) target
0166: .getGraphicsConfiguration();
0167: graphicsConfigData = new AwtGraphicsConfigData(graphicsConfig
0168: .getAData());
0169: }
0170:
0171: void preInit(XCreateWindowParams params) {
0172: super .preInit(params);
0173: reparented = Boolean.TRUE.equals(params.get(REPARENTED));
0174:
0175: target = (Component) params.get(TARGET);
0176:
0177: initGraphicsConfiguration();
0178:
0179: AwtGraphicsConfigData gData = getGraphicsConfigurationData();
0180: X11GraphicsConfig config = (X11GraphicsConfig) getGraphicsConfiguration();
0181: XVisualInfo visInfo = gData.get_awt_visInfo();
0182: params
0183: .putIfNull(EVENT_MASK, KeyPressMask | KeyReleaseMask
0184: | FocusChangeMask | ButtonPressMask
0185: | ButtonReleaseMask | EnterWindowMask
0186: | LeaveWindowMask | PointerMotionMask
0187: | ButtonMotionMask | ExposureMask
0188: | StructureNotifyMask);
0189:
0190: if (target != null) {
0191: params.putIfNull(BOUNDS, target.getBounds());
0192: } else {
0193: params.putIfNull(BOUNDS, new Rectangle(0, 0, MIN_SIZE,
0194: MIN_SIZE));
0195: }
0196: params.putIfNull(BORDER_PIXEL, Long.valueOf(0));
0197: getColorModel(); // fix 4948833: this call forces the color map to be initialized
0198: params.putIfNull(COLORMAP, gData.get_awt_cmap());
0199: params.putIfNull(DEPTH, gData.get_awt_depth());
0200: params.putIfNull(VISUAL_CLASS, Integer
0201: .valueOf((int) XlibWrapper.InputOutput));
0202: params.putIfNull(VISUAL, visInfo.get_visual());
0203: params.putIfNull(VALUE_MASK, XlibWrapper.CWBorderPixel
0204: | XlibWrapper.CWEventMask | XlibWrapper.CWColormap);
0205: Long parentWindow = (Long) params.get(PARENT_WINDOW);
0206: if (parentWindow == null || parentWindow.longValue() == 0) {
0207: XToolkit.awtLock();
0208: try {
0209: int screen = visInfo.get_screen();
0210: if (screen != -1) {
0211: params.add(PARENT_WINDOW, XlibWrapper.RootWindow(
0212: XToolkit.getDisplay(), screen));
0213: } else {
0214: params.add(PARENT_WINDOW, XToolkit
0215: .getDefaultRootWindow());
0216: }
0217: } finally {
0218: XToolkit.awtUnlock();
0219: }
0220: }
0221:
0222: paintArea = new XRepaintArea();
0223: if (target != null) {
0224: this .parent = getParentXWindowObject(target.getParent());
0225: }
0226:
0227: params.putIfNull(BACKING_STORE, XToolkit.getBackingStoreType());
0228: }
0229:
0230: void postInit(XCreateWindowParams params) {
0231: super .postInit(params);
0232:
0233: setWMClass(getWMClass());
0234:
0235: surfaceData = graphicsConfig.createSurfaceData(this );
0236: Color c;
0237: if (target != null && (c = target.getBackground()) != null) {
0238: // We need a version of setBackground that does not call repaint !!
0239: // and one that does not get overridden. The problem is that in postInit
0240: // we call setBackground and we dont have all the stuff initialized to
0241: // do a full paint for most peers. So we cannot call setBackground in postInit.
0242: // instead we need to call xSetBackground.
0243: xSetBackground(c);
0244: }
0245: }
0246:
0247: public GraphicsConfiguration getGraphicsConfiguration() {
0248: if (graphicsConfig == null) {
0249: initGraphicsConfiguration();
0250: }
0251: return graphicsConfig;
0252: }
0253:
0254: public AwtGraphicsConfigData getGraphicsConfigurationData() {
0255: if (graphicsConfigData == null) {
0256: initGraphicsConfiguration();
0257: }
0258: return graphicsConfigData;
0259: }
0260:
0261: protected String[] getWMClass() {
0262: return new String[] {
0263: XToolkit.getCorrectXIDString(getClass().getName()),
0264: XToolkit.getAWTAppClassName() };
0265: }
0266:
0267: void setReparented(boolean newValue) {
0268: reparented = newValue;
0269: }
0270:
0271: boolean isReparented() {
0272: return reparented;
0273: }
0274:
0275: static long getParentWindowID(Component target) {
0276:
0277: ComponentPeer peer = target.getParent().getPeer();
0278: Component temp = target.getParent();
0279: while (!(peer instanceof XWindow)) {
0280: temp = temp.getParent();
0281: peer = temp.getPeer();
0282: }
0283:
0284: if (peer != null && peer instanceof XWindow)
0285: return ((XWindow) peer).getContentWindow();
0286: else
0287: return 0;
0288: }
0289:
0290: static XWindow getParentXWindowObject(Component target) {
0291: if (target == null)
0292: return null;
0293: Component temp = target.getParent();
0294: if (temp == null)
0295: return null;
0296: ComponentPeer peer = temp.getPeer();
0297: if (peer == null)
0298: return null;
0299: while ((peer != null) && !(peer instanceof XWindow)) {
0300: temp = temp.getParent();
0301: peer = temp.getPeer();
0302: }
0303: if (peer != null && peer instanceof XWindow)
0304: return (XWindow) peer;
0305: else
0306: return null;
0307: }
0308:
0309: boolean isParentOf(XWindow win) {
0310: if (!(target instanceof Container) || win == null
0311: || win.getTarget() == null) {
0312: return false;
0313: }
0314: Container parent = ComponentAccessor
0315: .getParent_NoClientCode(win.target);
0316: while (parent != null && parent != target) {
0317: parent = ComponentAccessor.getParent_NoClientCode(parent);
0318: }
0319: return (parent == target);
0320: }
0321:
0322: public Object getTarget() {
0323: return target;
0324: }
0325:
0326: public Component getEventSource() {
0327: return target;
0328: }
0329:
0330: public ColorModel getColorModel(int transparency) {
0331: return graphicsConfig.getColorModel(transparency);
0332: }
0333:
0334: public ColorModel getColorModel() {
0335: if (graphicsConfig != null) {
0336: return graphicsConfig.getColorModel();
0337: } else {
0338: return XToolkit.getStaticColorModel();
0339: }
0340: }
0341:
0342: Graphics getGraphics(SurfaceData surfData, Color afore,
0343: Color aback, Font afont) {
0344: if (surfData == null)
0345: return null;
0346:
0347: Component target = (Component) this .target;
0348:
0349: /* Fix for bug 4746122. Color and Font shouldn't be null */
0350: Color bgColor = aback;
0351: if (bgColor == null) {
0352: bgColor = SystemColor.window;
0353: }
0354: Color fgColor = afore;
0355: if (fgColor == null) {
0356: fgColor = SystemColor.windowText;
0357: }
0358: Font font = afont;
0359: if (font == null) {
0360: font = defaultFont;
0361: }
0362: return new SunGraphics2D(surfData, fgColor, bgColor, font);
0363: }
0364:
0365: public Graphics getGraphics() {
0366: return getGraphics(surfaceData, target.getForeground(), target
0367: .getBackground(), target.getFont());
0368: }
0369:
0370: public FontMetrics getFontMetrics(Font font) {
0371: return Toolkit.getDefaultToolkit().getFontMetrics(font);
0372: }
0373:
0374: public Rectangle getTargetBounds() {
0375: return target.getBounds();
0376: }
0377:
0378: /**
0379: * Returns true if the event has been handled and should not be
0380: * posted to Java.
0381: */
0382: boolean prePostEvent(AWTEvent e) {
0383: return false;
0384: }
0385:
0386: static Method m_sendMessage;
0387:
0388: static void sendEvent(final AWTEvent e) {
0389: if (isPostedField == null) {
0390: isPostedField = SunToolkit.getField(AWTEvent.class,
0391: "isPosted");
0392: }
0393: PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(),
0394: new Runnable() {
0395: public void run() {
0396: try {
0397: isPostedField.setBoolean(e, true);
0398: } catch (IllegalArgumentException e) {
0399: assert (false);
0400: } catch (IllegalAccessException e) {
0401: assert (false);
0402: }
0403: ((Component) e.getSource()).dispatchEvent(e);
0404: }
0405: }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
0406: if (focusLog.isLoggable(Level.FINER)
0407: && (e instanceof FocusEvent))
0408: focusLog.finer("Sending " + e);
0409: XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()),
0410: pe);
0411: }
0412:
0413: /*
0414: * Post an event to the event queue.
0415: */
0416: // NOTE: This method may be called by privileged threads.
0417: // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0418: void postEvent(AWTEvent event) {
0419: XToolkit.postEvent(XToolkit.targetToAppContext(event
0420: .getSource()), event);
0421: }
0422:
0423: static void postEventStatic(AWTEvent event) {
0424: XToolkit.postEvent(XToolkit.targetToAppContext(event
0425: .getSource()), event);
0426: }
0427:
0428: public void postEventToEventQueue(final AWTEvent event) {
0429: //fix for 6239938 : Choice drop-down does not disappear when it loses focus, on XToolkit
0430: if (!prePostEvent(event)) {
0431: //event hasn't been handled and must be posted to EventQueue
0432: postEvent(event);
0433: }
0434: }
0435:
0436: // overriden in XCanvasPeer
0437: protected boolean doEraseBackground() {
0438: return true;
0439: }
0440:
0441: // We need a version of setBackground that does not call repaint !!
0442: // and one that does not get overridden. The problem is that in postInit
0443: // we call setBackground and we dont have all the stuff initialized to
0444: // do a full paint for most peers. So we cannot call setBackground in postInit.
0445: final public void xSetBackground(Color c) {
0446: XToolkit.awtLock();
0447: try {
0448: winBackground(c);
0449: // fix for 6558510: handle sun.awt.noerasebackground flag,
0450: // see doEraseBackground() and preInit() methods in XCanvasPeer
0451: if (!doEraseBackground()) {
0452: return;
0453: }
0454: // 6304250: XAWT: Items in choice show a blue border on OpenGL + Solaris10 when background color is set
0455: // Note: When OGL is enabled, surfaceData.pixelFor() will not
0456: // return a pixel value appropriate for passing to
0457: // XSetWindowBackground(). Therefore, we will use the ColorModel
0458: // for this component in order to calculate a pixel value from
0459: // the given RGB value.
0460: ColorModel cm = getColorModel();
0461: int pixel = PixelConverter.instance.rgbToPixel(c.getRGB(),
0462: cm);
0463: XlibWrapper.XSetWindowBackground(XToolkit.getDisplay(),
0464: getContentWindow(), pixel);
0465: } finally {
0466: XToolkit.awtUnlock();
0467: }
0468: }
0469:
0470: public void setBackground(Color c) {
0471: xSetBackground(c);
0472: }
0473:
0474: Color backgroundColor;
0475:
0476: void winBackground(Color c) {
0477: backgroundColor = c;
0478: }
0479:
0480: public Color getWinBackground() {
0481: Color c = null;
0482:
0483: if (backgroundColor != null) {
0484: c = backgroundColor;
0485: } else if (parent != null) {
0486: c = parent.getWinBackground();
0487: }
0488:
0489: if (c instanceof SystemColor) {
0490: c = new Color(c.getRGB());
0491: }
0492:
0493: return c;
0494: }
0495:
0496: public boolean isEmbedded() {
0497: return embedded;
0498: }
0499:
0500: public void repaint(int x, int y, int width, int height) {
0501: if (!isVisible()) {
0502: return;
0503: }
0504: Graphics g = getGraphics();
0505: if (g != null) {
0506: try {
0507: g.setClip(x, y, width, height);
0508: paint(g);
0509: } finally {
0510: g.dispose();
0511: }
0512: }
0513: }
0514:
0515: public void repaint() {
0516: if (!isVisible()) {
0517: return;
0518: }
0519: Graphics g = getGraphics();
0520: if (g != null) {
0521: try {
0522: paint(g);
0523: } finally {
0524: g.dispose();
0525: }
0526: }
0527: }
0528:
0529: void paint(Graphics g) {
0530: }
0531:
0532: //used by Peers to avoid flickering withing paint()
0533: protected void flush() {
0534: XToolkit.awtLock();
0535: try {
0536: XlibWrapper.XFlush(XToolkit.getDisplay());
0537: } finally {
0538: XToolkit.awtUnlock();
0539: }
0540: }
0541:
0542: public void popup(int x, int y, int width, int height) {
0543: // TBD: grab the pointer
0544: xSetBounds(x, y, width, height);
0545: }
0546:
0547: public void handleExposeEvent(XEvent xev) {
0548: super .handleExposeEvent(xev);
0549: XExposeEvent xe = xev.get_xexpose();
0550: if (isEventDisabled(xev)) {
0551: return;
0552: }
0553: int x = xe.get_x();
0554: int y = xe.get_y();
0555: int w = xe.get_width();
0556: int h = xe.get_height();
0557:
0558: Component target = (Component) getEventSource();
0559:
0560: if (!ComponentAccessor.getIgnoreRepaint(target)
0561: && ComponentAccessor.getWidth(target) != 0
0562: && ComponentAccessor.getHeight(target) != 0) {
0563: handleExposeEvent(target, x, y, w, h);
0564: }
0565: }
0566:
0567: public void handleExposeEvent(Component target, int x, int y,
0568: int w, int h) {
0569: PaintEvent event = PaintEventDispatcher
0570: .getPaintEventDispatcher().createPaintEvent(target, x,
0571: y, w, h);
0572: if (event != null) {
0573: postEventToEventQueue(event);
0574: }
0575: }
0576:
0577: static int getModifiers(int state, int button, int keyCode) {
0578: int modifiers = 0;
0579:
0580: if (((state & XlibWrapper.ShiftMask) != 0)
0581: ^ (keyCode == KeyEvent.VK_SHIFT)) {
0582: modifiers |= InputEvent.SHIFT_DOWN_MASK;
0583: }
0584: if (((state & XlibWrapper.ControlMask) != 0)
0585: ^ (keyCode == KeyEvent.VK_CONTROL)) {
0586: modifiers |= InputEvent.CTRL_DOWN_MASK;
0587: }
0588: if (((state & XToolkit.metaMask) != 0)
0589: ^ (keyCode == KeyEvent.VK_META)) {
0590: modifiers |= InputEvent.META_DOWN_MASK;
0591: }
0592: if (((state & XToolkit.altMask) != 0)
0593: ^ (keyCode == KeyEvent.VK_ALT)) {
0594: modifiers |= InputEvent.ALT_DOWN_MASK;
0595: }
0596: if (((state & XToolkit.modeSwitchMask) != 0)
0597: ^ (keyCode == KeyEvent.VK_ALT_GRAPH)) {
0598: modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
0599: }
0600: if (((state & XlibWrapper.Button1Mask) != 0)
0601: ^ (button == MouseEvent.BUTTON1)) {
0602: modifiers |= InputEvent.BUTTON1_DOWN_MASK;
0603: }
0604: if (((state & XlibWrapper.Button2Mask) != 0)
0605: ^ (button == MouseEvent.BUTTON2)) {
0606: modifiers |= InputEvent.BUTTON2_DOWN_MASK;
0607: }
0608: if (((state & XlibWrapper.Button3Mask) != 0)
0609: ^ (button == MouseEvent.BUTTON3)) {
0610: modifiers |= InputEvent.BUTTON3_DOWN_MASK;
0611: }
0612: return modifiers;
0613: }
0614:
0615: static int getXModifiers(AWTKeyStroke stroke) {
0616: int mods = stroke.getModifiers();
0617: int res = 0;
0618: if ((mods & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) {
0619: res |= XToolkit.ShiftMask;
0620: }
0621: if ((mods & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) {
0622: res |= XToolkit.ControlMask;
0623: }
0624: if ((mods & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) {
0625: res |= XToolkit.altMask;
0626: }
0627: if ((mods & (InputEvent.META_DOWN_MASK | InputEvent.META_MASK)) != 0) {
0628: res |= XToolkit.metaMask;
0629: }
0630: if ((mods & (InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.ALT_GRAPH_MASK)) != 0) {
0631: res |= XToolkit.modeSwitchMask;
0632: }
0633: return res;
0634: }
0635:
0636: private static int getButtonMask(long mouseButton) {
0637: if (mouseButton == XlibWrapper.Button1) {
0638: return XlibWrapper.Button1Mask;
0639: } else if (mouseButton == XlibWrapper.Button2) {
0640: return XlibWrapper.Button2Mask;
0641: } else if (mouseButton == XlibWrapper.Button3) {
0642: return XlibWrapper.Button3Mask;
0643: }
0644: return 0;
0645: }
0646:
0647: /**
0648: * Returns true if this event is disabled and shouldn't be passed to Java.
0649: * Default implementation returns false for all events.
0650: */
0651: static int getRightButtonNumber() {
0652: if (rbutton == 0) { // not initialized yet
0653: XToolkit.awtLock();
0654: try {
0655: rbutton = XlibWrapper.XGetPointerMapping(XToolkit
0656: .getDisplay(), XlibWrapper.ibuffer, 3);
0657: } finally {
0658: XToolkit.awtUnlock();
0659: }
0660: }
0661: return rbutton;
0662: }
0663:
0664: static int getMouseMovementSmudge() {
0665: //TODO: It's possible to read corresponding settings
0666: return AWT_MULTICLICK_SMUDGE;
0667: }
0668:
0669: public void handleButtonPressRelease(XEvent xev) {
0670: super .handleButtonPressRelease(xev);
0671: XButtonEvent xbe = xev.get_xbutton();
0672: if (isEventDisabled(xev)) {
0673: return;
0674: }
0675: if (eventLog.isLoggable(Level.FINE))
0676: eventLog.fine(xbe.toString());
0677: long when;
0678: int modifiers;
0679: boolean popupTrigger = false;
0680: int button = 0;
0681: boolean wheel_mouse = false;
0682: long lbutton = xbe.get_button();
0683: int type = xev.get_type();
0684: when = xbe.get_time();
0685: long jWhen = XToolkit.nowMillisUTC_offset(when);
0686:
0687: int x = xbe.get_x();
0688: int y = xbe.get_y();
0689: if (xev.get_xany().get_window() != window) {
0690: Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
0691: x = localXY.x;
0692: y = localXY.y;
0693: }
0694:
0695: if (type == XlibWrapper.ButtonPress) {
0696: XWindow lastWindow = (lastWindowRef != null) ? ((XWindow) lastWindowRef
0697: .get())
0698: : (null);
0699: /*
0700: multiclick checking
0701: */
0702: if (eventLog.isLoggable(Level.FINEST))
0703: eventLog.finest("lastWindow = " + lastWindow
0704: + ", lastButton " + lastButton + ", lastTime "
0705: + lastTime + ", multiClickTime "
0706: + XToolkit.getMultiClickTime());
0707: if (lastWindow == this && lastButton == lbutton
0708: && (when - lastTime) < XToolkit.getMultiClickTime()) {
0709: clickCount++;
0710: } else {
0711: clickCount = 1;
0712: lastWindowRef = new WeakReference(this );
0713: lastButton = lbutton;
0714: lastX = x;
0715: lastY = y;
0716: }
0717: lastTime = when;
0718:
0719: /*
0720: Check for popup trigger !!
0721: */
0722: if (lbutton == getRightButtonNumber() || lbutton > 2) {
0723: popupTrigger = true;
0724: } else {
0725: popupTrigger = false;
0726: }
0727: }
0728:
0729: if (lbutton == XlibWrapper.Button1)
0730: button = MouseEvent.BUTTON1;
0731: else if (lbutton == XlibWrapper.Button2)
0732: button = MouseEvent.BUTTON2;
0733: else if (lbutton == XlibWrapper.Button3)
0734: button = MouseEvent.BUTTON3;
0735: else if (lbutton == XlibWrapper.Button4) {
0736: button = 4;
0737: wheel_mouse = true;
0738: } else if (lbutton == XlibWrapper.Button5) {
0739: button = 5;
0740: wheel_mouse = true;
0741: }
0742:
0743: modifiers = getModifiers(xbe.get_state(), button, 0);
0744:
0745: if (!wheel_mouse) {
0746: MouseEvent me = new MouseEvent(
0747: (Component) getEventSource(),
0748: type == XlibWrapper.ButtonPress ? MouseEvent.MOUSE_PRESSED
0749: : MouseEvent.MOUSE_RELEASED, jWhen,
0750: modifiers, x, y, xbe.get_x_root(),
0751: xbe.get_y_root(), clickCount, popupTrigger, button);
0752:
0753: postEventToEventQueue(me);
0754:
0755: if (((mouseDragState & getButtonMask(lbutton)) == 0) && // No up-button in the drag-state
0756: (type == XlibWrapper.ButtonRelease)) {
0757: postEventToEventQueue(me = new MouseEvent(
0758: (Component) getEventSource(),
0759: MouseEvent.MOUSE_CLICKED, jWhen, modifiers, x,
0760: y, xbe.get_x_root(), xbe.get_y_root(),
0761: clickCount, false, button));
0762: }
0763:
0764: } else {
0765: if (xev.get_type() == XlibWrapper.ButtonPress) {
0766: MouseWheelEvent mwe = new MouseWheelEvent(
0767: (Component) getEventSource(),
0768: MouseEvent.MOUSE_WHEEL, jWhen, modifiers, x, y,
0769: xbe.get_x_root(), xbe.get_y_root(), clickCount,
0770: false, MouseWheelEvent.WHEEL_UNIT_SCROLL, 3,
0771: button == 4 ? -1 : 1);
0772: postEventToEventQueue(mwe);
0773: }
0774: }
0775:
0776: mouseDragState &= ~getButtonMask(lbutton); // Exclude the up-button from the drag-state
0777: }
0778:
0779: public void handleMotionNotify(XEvent xev) {
0780: super .handleMotionNotify(xev);
0781: XMotionEvent xme = xev.get_xmotion();
0782: if (isEventDisabled(xev)) {
0783: return;
0784: }
0785:
0786: int mouseKeyState = (xme.get_state() & (Button1Mask
0787: | Button2Mask | Button3Mask));
0788: boolean isDragging = (mouseKeyState != 0);
0789: int mouseEventType = 0;
0790:
0791: if (isDragging) {
0792: mouseEventType = MouseEvent.MOUSE_DRAGGED;
0793: } else {
0794: mouseEventType = MouseEvent.MOUSE_MOVED;
0795: }
0796:
0797: /*
0798: Fix for 6176814 . Add multiclick checking.
0799: */
0800: int x = xme.get_x();
0801: int y = xme.get_y();
0802: XWindow lastWindow = (lastWindowRef != null) ? ((XWindow) lastWindowRef
0803: .get())
0804: : (null);
0805:
0806: if (!(lastWindow == this
0807: && (xme.get_time() - lastTime) < XToolkit
0808: .getMultiClickTime() && (Math.abs(lastX - x) < AWT_MULTICLICK_SMUDGE && Math
0809: .abs(lastY - y) < AWT_MULTICLICK_SMUDGE))) {
0810: clickCount = 0;
0811: lastWindowRef = null;
0812: mouseDragState = mouseKeyState;
0813: lastTime = 0;
0814: lastX = 0;
0815: lastY = 0;
0816: }
0817:
0818: long jWhen = XToolkit.nowMillisUTC_offset(xme.get_time());
0819: int modifiers = getModifiers(xme.get_state(), 0, 0);
0820: boolean popupTrigger = false;
0821:
0822: Component source = (Component) getEventSource();
0823:
0824: if (xme.get_window() != window) {
0825: Point localXY = toLocal(xme.get_x_root(), xme.get_y_root());
0826: x = localXY.x;
0827: y = localXY.y;
0828: }
0829: /* Fix for 5039416.
0830: * According to canvas.c we shouldn't post any MouseEvent if mouse is dragging and clickCount!=0.
0831: */
0832: if ((isDragging && clickCount == 0) || !isDragging) {
0833: MouseEvent mme = new MouseEvent(source, mouseEventType,
0834: jWhen, modifiers, x, y, xme.get_x_root(), xme
0835: .get_y_root(), clickCount, popupTrigger,
0836: MouseEvent.NOBUTTON);
0837: postEventToEventQueue(mme);
0838: }
0839: }
0840:
0841: // REMIND: need to implement looking for disabled events
0842: public native boolean x11inputMethodLookupString(long event,
0843: long[] keysymArray);
0844:
0845: native boolean haveCurrentX11InputMethodInstance();
0846:
0847: public void handleXCrossingEvent(XEvent xev) {
0848: super .handleXCrossingEvent(xev);
0849: XCrossingEvent xce = xev.get_xcrossing();
0850:
0851: if (eventLog.isLoggable(Level.FINEST))
0852: eventLog.finest(xce.toString());
0853:
0854: // Skip event If it was caused by a grab
0855: // This is needed because on displays with focus-follows-mouse on MousePress X system generates
0856: // two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
0857: // current component. Second one notifies that it has entered into the same component.
0858: // This looks like the window under the mouse has actually changed and Java handle these events
0859: // accordingly. This leads to impossibility to make a double click on Component (6404708)
0860: XWindowPeer toplevel = getToplevelXWindow();
0861: if (toplevel != null && !toplevel.isModalBlocked()) {
0862: if (xce.get_mode() != NotifyNormal) {
0863: // 6404708 : need update cursor in accordance with skipping Leave/EnterNotify event
0864: // whereas it doesn't need to handled further.
0865: if (xce.get_type() == EnterNotify) {
0866: XAwtState
0867: .setComponentMouseEntered(getEventSource());
0868: XGlobalCursorManager
0869: .nativeUpdateCursor(getEventSource());
0870: } else { // LeaveNotify:
0871: XAwtState.setComponentMouseEntered(null);
0872: }
0873: return;
0874: }
0875: }
0876: // X sends XCrossing to all hierarchy so if the edge of child equals to
0877: // ancestor and mouse enters child, the ancestor will get an event too.
0878: // From java point the event is bogus as ancestor is obscured, so if
0879: // the child can get java event itself, we skip it on ancestor.
0880: long childWnd = xce.get_subwindow();
0881: if (childWnd != None) {
0882: XBaseWindow child = XToolkit.windowToXWindow(childWnd);
0883: if (child != null && child instanceof XWindow
0884: && !child.isEventDisabled(xev)) {
0885: return;
0886: }
0887: }
0888:
0889: // Remember old component with mouse to have the opportunity to send it MOUSE_EXITED.
0890: final Component compWithMouse = XAwtState
0891: .getComponentMouseEntered();
0892: if (toplevel != null) {
0893: if (!toplevel.isModalBlocked()) {
0894: if (xce.get_type() == EnterNotify) {
0895: // Change XAwtState's component mouse entered to the up-to-date one before requesting
0896: // to update the cursor since XAwtState.getComponentMouseEntered() is used when the
0897: // cursor is updated (in XGlobalCursorManager.findHeavyweightUnderCursor()).
0898: XAwtState
0899: .setComponentMouseEntered(getEventSource());
0900: XGlobalCursorManager
0901: .nativeUpdateCursor(getEventSource());
0902: } else { // LeaveNotify:
0903: XAwtState.setComponentMouseEntered(null);
0904: }
0905: } else {
0906: ((XComponentPeer) ComponentAccessor.getPeer(target))
0907: .pSetCursor(Cursor
0908: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
0909: }
0910: }
0911:
0912: if (isEventDisabled(xev)) {
0913: return;
0914: }
0915:
0916: long jWhen = XToolkit.nowMillisUTC_offset(xce.get_time());
0917: int modifiers = getModifiers(xce.get_state(), 0, 0);
0918: int clickCount = 0;
0919: boolean popupTrigger = false;
0920: int x = xce.get_x();
0921: int y = xce.get_y();
0922: if (xce.get_window() != window) {
0923: Point localXY = toLocal(xce.get_x_root(), xce.get_y_root());
0924: x = localXY.x;
0925: y = localXY.y;
0926: }
0927:
0928: // This code tracks boundary crossing and ensures MOUSE_ENTER/EXIT
0929: // are posted in alternate pairs
0930: if (compWithMouse != null) {
0931: MouseEvent me = new MouseEvent(compWithMouse,
0932: MouseEvent.MOUSE_EXITED, jWhen, modifiers, xce
0933: .get_x(), xce.get_y(), xce.get_x_root(),
0934: xce.get_y_root(), clickCount, popupTrigger,
0935: MouseEvent.NOBUTTON);
0936: postEventToEventQueue(me);
0937: eventLog.finest("Clearing last window ref");
0938: lastWindowRef = null;
0939: }
0940: if (xce.get_type() == EnterNotify) {
0941: MouseEvent me = new MouseEvent(getEventSource(),
0942: MouseEvent.MOUSE_ENTERED, jWhen, modifiers, xce
0943: .get_x(), xce.get_y(), xce.get_x_root(),
0944: xce.get_y_root(), clickCount, popupTrigger,
0945: MouseEvent.NOBUTTON);
0946: postEventToEventQueue(me);
0947: }
0948: }
0949:
0950: public void doLayout(int x, int y, int width, int height) {
0951: }
0952:
0953: public void handleConfigureNotifyEvent(XEvent xev) {
0954: Rectangle oldBounds = getBounds();
0955:
0956: super .handleConfigureNotifyEvent(xev);
0957: insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
0958: new Object[] { xev, isEventDisabled(xev) });
0959: if (isEventDisabled(xev)) {
0960: return;
0961: }
0962:
0963: long eventWindow = xev.get_xany().get_window();
0964:
0965: // if ( Check if it's a resize, a move, or a stacking order change )
0966: // {
0967: Rectangle bounds = getBounds();
0968: if (!bounds.getSize().equals(oldBounds.getSize())) {
0969: postEventToEventQueue(new ComponentEvent(getEventSource(),
0970: ComponentEvent.COMPONENT_RESIZED));
0971: }
0972: if (!bounds.getLocation().equals(oldBounds.getLocation())) {
0973: postEventToEventQueue(new ComponentEvent(getEventSource(),
0974: ComponentEvent.COMPONENT_MOVED));
0975: }
0976: // }
0977: }
0978:
0979: public void handleMapNotifyEvent(XEvent xev) {
0980: super .handleMapNotifyEvent(xev);
0981: log.log(Level.FINE, "Mapped {0}", new Object[] { this });
0982: if (isEventDisabled(xev)) {
0983: return;
0984: }
0985: ComponentEvent ce;
0986:
0987: ce = new ComponentEvent(getEventSource(),
0988: ComponentEvent.COMPONENT_SHOWN);
0989: postEventToEventQueue(ce);
0990: }
0991:
0992: public void handleUnmapNotifyEvent(XEvent xev) {
0993: super .handleUnmapNotifyEvent(xev);
0994: if (isEventDisabled(xev)) {
0995: return;
0996: }
0997: ComponentEvent ce;
0998:
0999: ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
1000: postEventToEventQueue(ce);
1001: }
1002:
1003: private void dumpKeysymArray(XKeyEvent ev) {
1004: keyEventLog.fine(" "
1005: + Long.toHexString(XlibWrapper.XKeycodeToKeysym(
1006: XToolkit.getDisplay(), ev.get_keycode(), 0))
1007: + "\n "
1008: + Long.toHexString(XlibWrapper.XKeycodeToKeysym(
1009: XToolkit.getDisplay(), ev.get_keycode(), 1))
1010: + "\n "
1011: + Long.toHexString(XlibWrapper.XKeycodeToKeysym(
1012: XToolkit.getDisplay(), ev.get_keycode(), 2))
1013: + "\n "
1014: + Long.toHexString(XlibWrapper.XKeycodeToKeysym(
1015: XToolkit.getDisplay(), ev.get_keycode(), 3)));
1016: }
1017:
1018: /**
1019: Return unicode character or 0 if no correspondent character found.
1020: Parameter is a keysym basically from keysymdef.h
1021: XXX: how about vendor keys? Is there some with Unicode value and not in the list?
1022: */
1023: char keysymToUnicode(long keysym, int state) {
1024: return XKeysym.convertKeysym(keysym, state);
1025: }
1026:
1027: int keyEventType2Id(int xEventType) {
1028: return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED
1029: : xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED
1030: : 0;
1031: }
1032:
1033: static private long xkeycodeToKeysym(XKeyEvent ev) {
1034: return XKeysym.getKeysym(ev);
1035: }
1036:
1037: void logIncomingKeyEvent(XKeyEvent ev) {
1038: keyEventLog.fine("--XWindow.java:handleKeyEvent:" + ev);
1039: dumpKeysymArray(ev);
1040: keyEventLog
1041: .fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"
1042: + Integer.toHexString(XKeysym
1043: .getJavaKeycodeOnly(ev)));
1044: }
1045:
1046: public void handleKeyPress(XEvent xev) {
1047: super .handleKeyPress(xev);
1048: XKeyEvent ev = xev.get_xkey();
1049: if (eventLog.isLoggable(Level.FINE))
1050: eventLog.fine(ev.toString());
1051: if (isEventDisabled(xev)) {
1052: return;
1053: }
1054: handleKeyPress(ev);
1055: }
1056:
1057: // called directly from this package, unlike handleKeyRelease.
1058: // un-final it if you need to override it in a subclass.
1059: final void handleKeyPress(XKeyEvent ev) {
1060: int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
1061: long keysym[] = new long[2];
1062: char unicodeKey = 0;
1063: keysym[0] = NoSymbol;
1064:
1065: if (keyEventLog.isLoggable(Level.FINE)) {
1066: logIncomingKeyEvent(ev);
1067: }
1068: if ( //TODO check if there's an active input method instance
1069: // without calling a native method. Is it necessary though?
1070: haveCurrentX11InputMethodInstance()) {
1071: if (x11inputMethodLookupString(ev.pData, keysym)) {
1072: if (keyEventLog.isLoggable(Level.FINE)) {
1073: keyEventLog
1074: .fine("--XWindow.java XIM did process event; return; dec keysym processed:"
1075: + (keysym[0])
1076: + "; hex keysym processed:"
1077: + Long.toHexString(keysym[0]));
1078: }
1079: return;
1080: } else {
1081: unicodeKey = keysymToUnicode(keysym[0], ev.get_state());
1082: if (keyEventLog.isLoggable(Level.FINE)) {
1083: keyEventLog
1084: .fine("--XWindow.java XIM did NOT process event, hex keysym:"
1085: + Long.toHexString(keysym[0])
1086: + "\n"
1087: + " unicode key:"
1088: + Integer
1089: .toHexString((int) unicodeKey));
1090: }
1091: }
1092: } else {
1093: // No input method instance found. For example, there's a Java Input Method.
1094: // Produce do-it-yourself keysym and perhaps unicode character.
1095: keysym[0] = xkeycodeToKeysym(ev);
1096: unicodeKey = keysymToUnicode(keysym[0], ev.get_state());
1097: if (keyEventLog.isLoggable(Level.FINE)) {
1098: keyEventLog
1099: .fine("--XWindow.java XIM is absent; hex keysym:"
1100: + Long.toHexString(keysym[0])
1101: + "\n"
1102: + " unicode key:"
1103: + Integer.toHexString((int) unicodeKey));
1104: }
1105: }
1106: // Keysym should be converted to Unicode, if possible and necessary,
1107: // and Java KeyEvent keycode should be calculated.
1108: // For press we should post pressed & typed Java events.
1109: //
1110: // Press event might be not processed to this time because
1111: // (1) either XIM could not handle it or
1112: // (2) it was Latin 1:1 mapping.
1113: //
1114: XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
1115: if (jkc == null) {
1116: jkc = new XKeysym.Keysym2JavaKeycode(
1117: java.awt.event.KeyEvent.VK_UNDEFINED,
1118: java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1119: }
1120: if (keyEventLog.isLoggable(Level.FINE)) {
1121: keyEventLog
1122: .fine(">>>Fire Event:"
1123: + (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; "
1124: : "KEY_RELEASED; ")
1125: + "jkeycode:decimal="
1126: + jkc.getJavaKeycode() + ", hex=0x"
1127: + Integer.toHexString(jkc.getJavaKeycode())
1128: + "; ");
1129: }
1130: postKeyEvent(
1131: java.awt.event.KeyEvent.KEY_PRESSED,
1132: ev.get_time(),
1133: jkc.getJavaKeycode(),
1134: (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED
1135: : unicodeKey), jkc.getKeyLocation(), ev
1136: .get_state(), ev.getPData(), XKeyEvent
1137: .getSize());
1138: if (unicodeKey > 0) {
1139: keyEventLog.fine("fire _TYPED on " + unicodeKey);
1140: postKeyEvent(java.awt.event.KeyEvent.KEY_TYPED, ev
1141: .get_time(), java.awt.event.KeyEvent.VK_UNDEFINED,
1142: unicodeKey,
1143: java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN, ev
1144: .get_state(), ev.getPData(), XKeyEvent
1145: .getSize());
1146: }
1147:
1148: }
1149:
1150: public void handleKeyRelease(XEvent xev) {
1151: super .handleKeyRelease(xev);
1152: XKeyEvent ev = xev.get_xkey();
1153: if (eventLog.isLoggable(Level.FINE))
1154: eventLog.fine(ev.toString());
1155: if (isEventDisabled(xev)) {
1156: return;
1157: }
1158: handleKeyRelease(ev);
1159: }
1160:
1161: // un-private it if you need to call it from elsewhere
1162: private void handleKeyRelease(XKeyEvent ev) {
1163: int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
1164: long keysym[] = new long[2];
1165: char unicodeKey = 0;
1166: keysym[0] = NoSymbol;
1167:
1168: if (keyEventLog.isLoggable(Level.FINE)) {
1169: logIncomingKeyEvent(ev);
1170: }
1171: // Keysym should be converted to Unicode, if possible and necessary,
1172: // and Java KeyEvent keycode should be calculated.
1173: // For release we should post released event.
1174: //
1175: XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);
1176: if (jkc == null) {
1177: jkc = new XKeysym.Keysym2JavaKeycode(
1178: java.awt.event.KeyEvent.VK_UNDEFINED,
1179: java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1180: }
1181: if (keyEventLog.isLoggable(Level.FINE)) {
1182: keyEventLog
1183: .fine(">>>Fire Event:"
1184: + (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; "
1185: : "KEY_RELEASED; ")
1186: + "jkeycode:decimal="
1187: + jkc.getJavaKeycode() + ", hex=0x"
1188: + Integer.toHexString(jkc.getJavaKeycode())
1189: + "; ");
1190: }
1191: // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1192: // We used to cache that value and retrieve it on KeyRelease,
1193: // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1194: // might never be cached before.
1195: // Also, switching between keyboard layouts, we might cache a wrong letter.
1196: // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1197: unicodeKey = keysymToUnicode(xkeycodeToKeysym(ev), ev
1198: .get_state());
1199:
1200: postKeyEvent(
1201: java.awt.event.KeyEvent.KEY_RELEASED,
1202: ev.get_time(),
1203: jkc.getJavaKeycode(),
1204: (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED
1205: : unicodeKey), jkc.getKeyLocation(), ev
1206: .get_state(), ev.getPData(), XKeyEvent
1207: .getSize());
1208:
1209: }
1210:
1211: public void reshape(Rectangle bounds) {
1212: reshape(bounds.x, bounds.y, bounds.width, bounds.height);
1213: }
1214:
1215: public void reshape(int x, int y, int width, int height) {
1216: if (width <= 0) {
1217: width = 1;
1218: }
1219: if (height <= 0) {
1220: height = 1;
1221: }
1222: this .x = x;
1223: this .y = y;
1224: this .width = width;
1225: this .height = height;
1226: xSetBounds(x, y, width, height);
1227: // Fixed 6322593, 6304251, 6315137:
1228: // XWindow's SurfaceData should be invalidated and recreated as part
1229: // of the process of resizing the window
1230: // see the evaluation of the bug 6304251 for more information
1231: validateSurface();
1232: layout();
1233: }
1234:
1235: public void layout() {
1236: }
1237:
1238: boolean isShowing() {
1239: return visible;
1240: }
1241:
1242: boolean isResizable() {
1243: return true;
1244: }
1245:
1246: boolean isLocationByPlatform() {
1247: return false;
1248: }
1249:
1250: void updateSizeHints() {
1251: updateSizeHints(x, y, width, height);
1252: }
1253:
1254: void updateSizeHints(int x, int y, int width, int height) {
1255: long flags = XlibWrapper.PSize
1256: | (isLocationByPlatform() ? 0
1257: : (XlibWrapper.PPosition | XlibWrapper.USPosition));
1258: if (!isResizable()) {
1259: log.log(Level.FINER, "Window {0} is not resizable",
1260: new Object[] { this });
1261: flags |= XlibWrapper.PMinSize | XlibWrapper.PMaxSize;
1262: } else {
1263: log.log(Level.FINER, "Window {0} is resizable",
1264: new Object[] { this });
1265: }
1266: setSizeHints(flags, x, y, width, height);
1267: }
1268:
1269: void updateSizeHints(int x, int y) {
1270: long flags = isLocationByPlatform() ? 0
1271: : (XlibWrapper.PPosition | XlibWrapper.USPosition);
1272: if (!isResizable()) {
1273: log.log(Level.FINER, "Window {0} is not resizable",
1274: new Object[] { this });
1275: flags |= XlibWrapper.PMinSize | XlibWrapper.PMaxSize
1276: | XlibWrapper.PSize;
1277: } else {
1278: log.log(Level.FINER, "Window {0} is resizable",
1279: new Object[] { this });
1280: }
1281: setSizeHints(flags, x, y, width, height);
1282: }
1283:
1284: void validateSurface() {
1285: if ((width != oldWidth) || (height != oldHeight)) {
1286: SurfaceData oldData = surfaceData;
1287: if (oldData != null) {
1288: surfaceData = graphicsConfig.createSurfaceData(this );
1289: oldData.invalidate();
1290: }
1291: oldWidth = width;
1292: oldHeight = height;
1293: }
1294: }
1295:
1296: public SurfaceData getSurfaceData() {
1297: return surfaceData;
1298: }
1299:
1300: public void dispose() {
1301: SurfaceData oldData = surfaceData;
1302: surfaceData = null;
1303: if (oldData != null) {
1304: oldData.invalidate();
1305: }
1306: XToolkit.targetDisposedPeer(target, this );
1307: destroy();
1308: }
1309:
1310: public Point getLocationOnScreen() {
1311: synchronized (target.getTreeLock()) {
1312: Component comp = target;
1313:
1314: while (comp != null && !(comp instanceof Window)) {
1315: comp = ComponentAccessor.getParent_NoClientCode(comp);
1316: }
1317:
1318: // applets, embedded, etc - translate directly
1319: // XXX: override in subclass?
1320: if (comp == null || comp instanceof sun.awt.EmbeddedFrame) {
1321: return toGlobal(0, 0);
1322: }
1323:
1324: XToolkit.awtLock();
1325: try {
1326: Object wpeer = XToolkit.targetToPeer(comp);
1327: if (wpeer == null || !(wpeer instanceof XDecoratedPeer)
1328: || ((XDecoratedPeer) wpeer).configure_seen) {
1329: return toGlobal(0, 0);
1330: }
1331:
1332: // wpeer is an XDecoratedPeer not yet fully adopted by WM
1333: Point pt = toOtherWindow(getContentWindow(),
1334: ((XDecoratedPeer) wpeer).getContentWindow(), 0,
1335: 0);
1336:
1337: if (pt == null) {
1338: pt = new Point(
1339: ((XBaseWindow) wpeer).getAbsoluteX(),
1340: ((XBaseWindow) wpeer).getAbsoluteY());
1341: }
1342: pt.x += comp.getX();
1343: pt.y += comp.getY();
1344: return pt;
1345: } finally {
1346: XToolkit.awtUnlock();
1347: }
1348: }
1349: }
1350:
1351: static Field bdata;
1352:
1353: static void setBData(KeyEvent e, byte[] data) {
1354: try {
1355: if (bdata == null) {
1356: bdata = SunToolkit.getField(java.awt.AWTEvent.class,
1357: "bdata");
1358: }
1359: bdata.set(e, data);
1360: } catch (IllegalAccessException ex) {
1361: assert false;
1362: }
1363: }
1364:
1365: public void postKeyEvent(int id, long when, int keyCode,
1366: char keyChar, int keyLocation, int state, long event,
1367: int eventSize) {
1368: long jWhen = XToolkit.nowMillisUTC_offset(when);
1369: int modifiers = getModifiers(state, 0, keyCode);
1370: KeyEvent ke = new KeyEvent((Component) getEventSource(), id,
1371: jWhen, modifiers, keyCode, keyChar, keyLocation);
1372: if (event != 0) {
1373: byte[] data = Native.toBytes(event, eventSize);
1374: setBData(ke, data);
1375: }
1376: postEventToEventQueue(ke);
1377: }
1378:
1379: static native int getAWTKeyCodeForKeySym(int keysym);
1380:
1381: static native int getKeySymForAWTKeyCode(int keycode);
1382: }
|