33 import java.lang.ref.WeakReference; |
33 import java.lang.ref.WeakReference; |
34 |
34 |
35 import java.lang.reflect.Field; |
35 import java.lang.reflect.Field; |
36 import java.lang.reflect.Method; |
36 import java.lang.reflect.Method; |
37 |
37 |
38 import java.util.logging.Level; |
38 import sun.util.logging.PlatformLogger; |
39 import java.util.logging.Logger; |
|
40 |
39 |
41 import sun.awt.*; |
40 import sun.awt.*; |
42 |
41 |
43 import sun.awt.image.PixelConverter; |
42 import sun.awt.image.PixelConverter; |
44 |
43 |
45 import sun.java2d.SunGraphics2D; |
44 import sun.java2d.SunGraphics2D; |
46 import sun.java2d.SurfaceData; |
45 import sun.java2d.SurfaceData; |
47 |
46 |
48 public class XWindow extends XBaseWindow implements X11ComponentPeer { |
47 public class XWindow extends XBaseWindow implements X11ComponentPeer { |
49 private static Logger log = Logger.getLogger("sun.awt.X11.XWindow"); |
48 private static PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XWindow"); |
50 private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWindow"); |
49 private static PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XWindow"); |
51 private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XWindow"); |
50 private static PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XWindow"); |
52 private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XWindow"); |
51 private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XWindow"); |
53 private static Logger keyEventLog = Logger.getLogger("sun.awt.X11.kye.XWindow"); |
52 private static PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XWindow"); |
54 /* If a motion comes in while a multi-click is pending, |
53 /* If a motion comes in while a multi-click is pending, |
55 * allow a smudge factor so that moving the mouse by a small |
54 * allow a smudge factor so that moving the mouse by a small |
56 * amount does not wipe out the multi-click state variables. |
55 * amount does not wipe out the multi-click state variables. |
57 */ |
56 */ |
58 private final static int AWT_MULTICLICK_SMUDGE = 4; |
57 private final static int AWT_MULTICLICK_SMUDGE = 4; |
668 super.handleButtonPressRelease(xev); |
667 super.handleButtonPressRelease(xev); |
669 XButtonEvent xbe = xev.get_xbutton(); |
668 XButtonEvent xbe = xev.get_xbutton(); |
670 if (isEventDisabled(xev)) { |
669 if (isEventDisabled(xev)) { |
671 return; |
670 return; |
672 } |
671 } |
673 if (eventLog.isLoggable(Level.FINE)) eventLog.fine(xbe.toString()); |
672 if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(xbe.toString()); |
674 long when; |
673 long when; |
675 int modifiers; |
674 int modifiers; |
676 boolean popupTrigger = false; |
675 boolean popupTrigger = false; |
677 int button=0; |
676 int button=0; |
678 boolean wheel_mouse = false; |
677 boolean wheel_mouse = false; |
702 mouseButtonClickAllowed |= XConstants.buttonsMask[lbutton]; |
701 mouseButtonClickAllowed |= XConstants.buttonsMask[lbutton]; |
703 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null); |
702 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null); |
704 /* |
703 /* |
705 multiclick checking |
704 multiclick checking |
706 */ |
705 */ |
707 if (eventLog.isLoggable(Level.FINEST)) eventLog.finest("lastWindow = " + lastWindow + ", lastButton " |
706 if (eventLog.isLoggable(PlatformLogger.FINEST)) eventLog.finest("lastWindow = " + lastWindow + ", lastButton " |
708 + lastButton + ", lastTime " + lastTime + ", multiClickTime " |
707 + lastButton + ", lastTime " + lastTime + ", multiClickTime " |
709 + XToolkit.getMultiClickTime()); |
708 + XToolkit.getMultiClickTime()); |
710 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) { |
709 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) { |
711 clickCount++; |
710 clickCount++; |
712 } else { |
711 } else { |
893 |
892 |
894 public void handleXCrossingEvent(XEvent xev) { |
893 public void handleXCrossingEvent(XEvent xev) { |
895 super.handleXCrossingEvent(xev); |
894 super.handleXCrossingEvent(xev); |
896 XCrossingEvent xce = xev.get_xcrossing(); |
895 XCrossingEvent xce = xev.get_xcrossing(); |
897 |
896 |
898 if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString()); |
897 if (eventLog.isLoggable(PlatformLogger.FINEST)) eventLog.finest(xce.toString()); |
899 |
898 |
900 if (xce.get_type() == XConstants.EnterNotify) { |
899 if (xce.get_type() == XConstants.EnterNotify) { |
901 enterNotify(xce.get_window()); |
900 enterNotify(xce.get_window()); |
902 } else { // LeaveNotify: |
901 } else { // LeaveNotify: |
903 leaveNotify(xce.get_window()); |
902 leaveNotify(xce.get_window()); |
995 |
994 |
996 public void handleConfigureNotifyEvent(XEvent xev) { |
995 public void handleConfigureNotifyEvent(XEvent xev) { |
997 Rectangle oldBounds = getBounds(); |
996 Rectangle oldBounds = getBounds(); |
998 |
997 |
999 super.handleConfigureNotifyEvent(xev); |
998 super.handleConfigureNotifyEvent(xev); |
1000 insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}", |
999 insLog.finer("Configure, {0}, event disabled: {1}", |
1001 new Object[] {xev.get_xconfigure(), isEventDisabled(xev)}); |
1000 xev.get_xconfigure(), isEventDisabled(xev)); |
1002 if (isEventDisabled(xev)) { |
1001 if (isEventDisabled(xev)) { |
1003 return; |
1002 return; |
1004 } |
1003 } |
1005 |
1004 |
1006 // if ( Check if it's a resize, a move, or a stacking order change ) |
1005 // if ( Check if it's a resize, a move, or a stacking order change ) |
1072 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev))); |
1071 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev))); |
1073 } |
1072 } |
1074 public void handleKeyPress(XEvent xev) { |
1073 public void handleKeyPress(XEvent xev) { |
1075 super.handleKeyPress(xev); |
1074 super.handleKeyPress(xev); |
1076 XKeyEvent ev = xev.get_xkey(); |
1075 XKeyEvent ev = xev.get_xkey(); |
1077 if (eventLog.isLoggable(Level.FINE)) eventLog.fine(ev.toString()); |
1076 if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(ev.toString()); |
1078 if (isEventDisabled(xev)) { |
1077 if (isEventDisabled(xev)) { |
1079 return; |
1078 return; |
1080 } |
1079 } |
1081 handleKeyPress(ev); |
1080 handleKeyPress(ev); |
1082 } |
1081 } |
1085 final void handleKeyPress(XKeyEvent ev) { |
1084 final void handleKeyPress(XKeyEvent ev) { |
1086 long keysym[] = new long[2]; |
1085 long keysym[] = new long[2]; |
1087 int unicodeKey = 0; |
1086 int unicodeKey = 0; |
1088 keysym[0] = XConstants.NoSymbol; |
1087 keysym[0] = XConstants.NoSymbol; |
1089 |
1088 |
1090 if (keyEventLog.isLoggable(Level.FINE)) { |
1089 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1091 logIncomingKeyEvent( ev ); |
1090 logIncomingKeyEvent( ev ); |
1092 } |
1091 } |
1093 if ( //TODO check if there's an active input method instance |
1092 if ( //TODO check if there's an active input method instance |
1094 // without calling a native method. Is it necessary though? |
1093 // without calling a native method. Is it necessary though? |
1095 haveCurrentX11InputMethodInstance()) { |
1094 haveCurrentX11InputMethodInstance()) { |
1096 if (x11inputMethodLookupString(ev.pData, keysym)) { |
1095 if (x11inputMethodLookupString(ev.pData, keysym)) { |
1097 if (keyEventLog.isLoggable(Level.FINE)) { |
1096 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1098 keyEventLog.fine("--XWindow.java XIM did process event; return; dec keysym processed:"+(keysym[0])+ |
1097 keyEventLog.fine("--XWindow.java XIM did process event; return; dec keysym processed:"+(keysym[0])+ |
1099 "; hex keysym processed:"+Long.toHexString(keysym[0]) |
1098 "; hex keysym processed:"+Long.toHexString(keysym[0]) |
1100 ); |
1099 ); |
1101 } |
1100 } |
1102 return; |
1101 return; |
1103 }else { |
1102 }else { |
1104 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() ); |
1103 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() ); |
1105 if (keyEventLog.isLoggable(Level.FINE)) { |
1104 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1106 keyEventLog.fine("--XWindow.java XIM did NOT process event, hex keysym:"+Long.toHexString(keysym[0])+"\n"+ |
1105 keyEventLog.fine("--XWindow.java XIM did NOT process event, hex keysym:"+Long.toHexString(keysym[0])+"\n"+ |
1107 " unicode key:"+Integer.toHexString((int)unicodeKey)); |
1106 " unicode key:"+Integer.toHexString((int)unicodeKey)); |
1108 } |
1107 } |
1109 } |
1108 } |
1110 }else { |
1109 }else { |
1111 // No input method instance found. For example, there's a Java Input Method. |
1110 // No input method instance found. For example, there's a Java Input Method. |
1112 // Produce do-it-yourself keysym and perhaps unicode character. |
1111 // Produce do-it-yourself keysym and perhaps unicode character. |
1113 keysym[0] = xkeycodeToKeysym(ev); |
1112 keysym[0] = xkeycodeToKeysym(ev); |
1114 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() ); |
1113 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() ); |
1115 if (keyEventLog.isLoggable(Level.FINE)) { |
1114 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1116 keyEventLog.fine("--XWindow.java XIM is absent; hex keysym:"+Long.toHexString(keysym[0])+"\n"+ |
1115 keyEventLog.fine("--XWindow.java XIM is absent; hex keysym:"+Long.toHexString(keysym[0])+"\n"+ |
1117 " unicode key:"+Integer.toHexString((int)unicodeKey)); |
1116 " unicode key:"+Integer.toHexString((int)unicodeKey)); |
1118 } |
1117 } |
1119 } |
1118 } |
1120 // Keysym should be converted to Unicode, if possible and necessary, |
1119 // Keysym should be converted to Unicode, if possible and necessary, |
1133 // Take the first keysym from a keysym array associated with the XKeyevent |
1132 // Take the first keysym from a keysym array associated with the XKeyevent |
1134 // and convert it to Unicode. Then, even if a Java keycode for the keystroke |
1133 // and convert it to Unicode. Then, even if a Java keycode for the keystroke |
1135 // is undefined, we still have a guess of what has been engraved on a keytop. |
1134 // is undefined, we still have a guess of what has been engraved on a keytop. |
1136 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0); |
1135 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0); |
1137 |
1136 |
1138 if (keyEventLog.isLoggable(Level.FINE)) { |
1137 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1139 keyEventLog.fine(">>>Fire Event:"+ |
1138 keyEventLog.fine(">>>Fire Event:"+ |
1140 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+ |
1139 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+ |
1141 "jkeycode:decimal="+jkc.getJavaKeycode()+ |
1140 "jkeycode:decimal="+jkc.getJavaKeycode()+ |
1142 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+ |
1141 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+ |
1143 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+ |
1142 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+ |
1188 private void handleKeyRelease(XKeyEvent ev) { |
1187 private void handleKeyRelease(XKeyEvent ev) { |
1189 long keysym[] = new long[2]; |
1188 long keysym[] = new long[2]; |
1190 int unicodeKey = 0; |
1189 int unicodeKey = 0; |
1191 keysym[0] = XConstants.NoSymbol; |
1190 keysym[0] = XConstants.NoSymbol; |
1192 |
1191 |
1193 if (keyEventLog.isLoggable(Level.FINE)) { |
1192 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1194 logIncomingKeyEvent( ev ); |
1193 logIncomingKeyEvent( ev ); |
1195 } |
1194 } |
1196 // Keysym should be converted to Unicode, if possible and necessary, |
1195 // Keysym should be converted to Unicode, if possible and necessary, |
1197 // and Java KeyEvent keycode should be calculated. |
1196 // and Java KeyEvent keycode should be calculated. |
1198 // For release we should post released event. |
1197 // For release we should post released event. |
1199 // |
1198 // |
1200 XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev); |
1199 XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev); |
1201 if( jkc == null ) { |
1200 if( jkc == null ) { |
1202 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); |
1201 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); |
1203 } |
1202 } |
1204 if (keyEventLog.isLoggable(Level.FINE)) { |
1203 if (keyEventLog.isLoggable(PlatformLogger.FINE)) { |
1205 keyEventLog.fine(">>>Fire Event:"+ |
1204 keyEventLog.fine(">>>Fire Event:"+ |
1206 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+ |
1205 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+ |
1207 "jkeycode:decimal="+jkc.getJavaKeycode()+ |
1206 "jkeycode:decimal="+jkc.getJavaKeycode()+ |
1208 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+ |
1207 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+ |
1209 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+ |
1208 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+ |
1331 } |
1330 } |
1332 |
1331 |
1333 void updateSizeHints(int x, int y, int width, int height) { |
1332 void updateSizeHints(int x, int y, int width, int height) { |
1334 long flags = XUtilConstants.PSize | (isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition)); |
1333 long flags = XUtilConstants.PSize | (isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition)); |
1335 if (!isResizable()) { |
1334 if (!isResizable()) { |
1336 log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this}); |
1335 log.finer("Window {0} is not resizable", this); |
1337 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize; |
1336 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize; |
1338 } else { |
1337 } else { |
1339 log.log(Level.FINER, "Window {0} is resizable", new Object[] {this}); |
1338 log.finer("Window {0} is resizable", this); |
1340 } |
1339 } |
1341 setSizeHints(flags, x, y, width, height); |
1340 setSizeHints(flags, x, y, width, height); |
1342 } |
1341 } |
1343 |
1342 |
1344 void updateSizeHints(int x, int y) { |
1343 void updateSizeHints(int x, int y) { |
1345 long flags = isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition); |
1344 long flags = isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition); |
1346 if (!isResizable()) { |
1345 if (!isResizable()) { |
1347 log.log(Level.FINER, "Window {0} is not resizable", new Object[] {this}); |
1346 log.finer("Window {0} is not resizable", this); |
1348 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize | XUtilConstants.PSize; |
1347 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize | XUtilConstants.PSize; |
1349 } else { |
1348 } else { |
1350 log.log(Level.FINER, "Window {0} is resizable", new Object[] {this}); |
1349 log.finer("Window {0} is resizable", this); |
1351 } |
1350 } |
1352 setSizeHints(flags, x, y, width, height); |
1351 setSizeHints(flags, x, y, width, height); |
1353 } |
1352 } |
1354 |
1353 |
1355 void validateSurface() { |
1354 void validateSurface() { |