385 }
386
387 /**
388 * Returns true if the event has been handled and should not be
389 * posted to Java.
390 */
391 boolean prePostEvent(AWTEvent e) {
392 return false;
393 }
394
395 static Method m_sendMessage;
396 static void sendEvent(final AWTEvent e) {
397 // The uses of this method imply that the incoming event is system-generated
398 SunToolkit.setSystemGenerated(e);
399 PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
400 public void run() {
401 AWTAccessor.getAWTEventAccessor().setPosted(e);
402 ((Component)e.getSource()).dispatchEvent(e);
403 }
404 }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
405 if (focusLog.isLoggable(PlatformLogger.FINER) && (e instanceof FocusEvent)) {
406 focusLog.finer("Sending " + e);
407 }
408 XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), pe);
409 }
410
411
412 /*
413 * Post an event to the event queue.
414 */
415 // NOTE: This method may be called by privileged threads.
416 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
417 void postEvent(AWTEvent event) {
418 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
419 }
420
421 static void postEventStatic(AWTEvent event) {
422 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
423 }
424
425 public void postEventToEventQueue(final AWTEvent event) {
645 rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
646 }
647 finally {
648 XToolkit.awtUnlock();
649 }
650 }
651 return rbutton;
652 }
653
654 static int getMouseMovementSmudge() {
655 //TODO: It's possible to read corresponding settings
656 return AWT_MULTICLICK_SMUDGE;
657 }
658
659 public void handleButtonPressRelease(XEvent xev) {
660 super.handleButtonPressRelease(xev);
661 XButtonEvent xbe = xev.get_xbutton();
662 if (isEventDisabled(xev)) {
663 return;
664 }
665 if (eventLog.isLoggable(PlatformLogger.FINE)) {
666 eventLog.fine(xbe.toString());
667 }
668 long when;
669 int modifiers;
670 boolean popupTrigger = false;
671 int button=0;
672 boolean wheel_mouse = false;
673 int lbutton = xbe.get_button();
674 /*
675 * Ignore the buttons above 20 due to the bit limit for
676 * InputEvent.BUTTON_DOWN_MASK.
677 * One more bit is reserved for FIRST_HIGH_BIT.
678 */
679 if (lbutton > SunToolkit.MAX_BUTTONS_SUPPORTED) {
680 return;
681 }
682 int type = xev.get_type();
683 when = xbe.get_time();
684 long jWhen = XToolkit.nowMillisUTC_offset(when);
685
686 int x = xbe.get_x();
687 int y = xbe.get_y();
688 if (xev.get_xany().get_window() != window) {
689 Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
690 x = localXY.x;
691 y = localXY.y;
692 }
693
694 if (type == XConstants.ButtonPress) {
695 //Allow this mouse button to generate CLICK event on next ButtonRelease
696 mouseButtonClickAllowed |= XlibUtil.getButtonMask(lbutton);
697 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
698 /*
699 multiclick checking
700 */
701 if (eventLog.isLoggable(PlatformLogger.FINEST)) {
702 eventLog.finest("lastWindow = " + lastWindow + ", lastButton "
703 + lastButton + ", lastTime " + lastTime + ", multiClickTime "
704 + XToolkit.getMultiClickTime());
705 }
706 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) {
707 clickCount++;
708 } else {
709 clickCount = 1;
710 lastWindowRef = new WeakReference(this);
711 lastButton = lbutton;
712 lastX = x;
713 lastY = y;
714 }
715 lastTime = when;
716
717
718 /*
719 Check for popup trigger !!
720 */
721 if (lbutton == getRightButtonNumber() || lbutton > 2) {
874 synchronized (getStateLock()) {
875 mouseAboveMe = above;
876 }
877 }
878
879 protected void enterNotify(long window) {
880 if (window == getWindow()) {
881 setMouseAbove(true);
882 }
883 }
884 protected void leaveNotify(long window) {
885 if (window == getWindow()) {
886 setMouseAbove(false);
887 }
888 }
889
890 public void handleXCrossingEvent(XEvent xev) {
891 super.handleXCrossingEvent(xev);
892 XCrossingEvent xce = xev.get_xcrossing();
893
894 if (eventLog.isLoggable(PlatformLogger.FINEST)) {
895 eventLog.finest(xce.toString());
896 }
897
898 if (xce.get_type() == XConstants.EnterNotify) {
899 enterNotify(xce.get_window());
900 } else { // LeaveNotify:
901 leaveNotify(xce.get_window());
902 }
903
904 // Skip event If it was caused by a grab
905 // This is needed because on displays with focus-follows-mouse on MousePress X system generates
906 // two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
907 // current component. Second one notifies that it has entered into the same component.
908 // This looks like the window under the mouse has actually changed and Java handle these events
909 // accordingly. This leads to impossibility to make a double click on Component (6404708)
910 XWindowPeer toplevel = getToplevelXWindow();
911 if (toplevel != null && !toplevel.isModalBlocked()){
912 if (xce.get_mode() != XConstants.NotifyNormal) {
913 // 6404708 : need update cursor in accordance with skipping Leave/EnterNotify event
914 // whereas it doesn't need to handled further.
978 xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount, popupTrigger,
979 MouseEvent.NOBUTTON);
980 postEventToEventQueue(me);
981 eventLog.finest("Clearing last window ref");
982 lastWindowRef = null;
983 }
984 if (xce.get_type() == XConstants.EnterNotify) {
985 MouseEvent me = new MouseEvent(getEventSource(), MouseEvent.MOUSE_ENTERED,
986 jWhen, modifiers, xce.get_x(), xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount,
987 popupTrigger, MouseEvent.NOBUTTON);
988 postEventToEventQueue(me);
989 }
990 }
991
992 public void doLayout(int x, int y, int width, int height) {}
993
994 public void handleConfigureNotifyEvent(XEvent xev) {
995 Rectangle oldBounds = getBounds();
996
997 super.handleConfigureNotifyEvent(xev);
998 if (insLog.isLoggable(PlatformLogger.FINER)) {
999 insLog.finer("Configure, {0}, event disabled: {1}",
1000 xev.get_xconfigure(), isEventDisabled(xev));
1001 }
1002 if (isEventDisabled(xev)) {
1003 return;
1004 }
1005
1006 // if ( Check if it's a resize, a move, or a stacking order change )
1007 // {
1008 Rectangle bounds = getBounds();
1009 if (!bounds.getSize().equals(oldBounds.getSize())) {
1010 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
1011 }
1012 if (!bounds.getLocation().equals(oldBounds.getLocation())) {
1013 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
1014 }
1015 // }
1016 }
1017
1018 public void handleMapNotifyEvent(XEvent xev) {
1019 super.handleMapNotifyEvent(xev);
1020 if (log.isLoggable(PlatformLogger.FINE)) {
1021 log.fine("Mapped {0}", this);
1022 }
1023 if (isEventDisabled(xev)) {
1024 return;
1025 }
1026 ComponentEvent ce;
1027
1028 ce = new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_SHOWN);
1029 postEventToEventQueue(ce);
1030 }
1031
1032 public void handleUnmapNotifyEvent(XEvent xev) {
1033 super.handleUnmapNotifyEvent(xev);
1034 if (isEventDisabled(xev)) {
1035 return;
1036 }
1037 ComponentEvent ce;
1038
1039 ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
1040 postEventToEventQueue(ce);
1041 }
1042
1043 private void dumpKeysymArray(XKeyEvent ev) {
1044 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1045 keyEventLog.fine(" "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 0))+
1046 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 1))+
1047 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 2))+
1048 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 3)));
1049 }
1050 }
1051 /**
1052 Return unicode character or 0 if no correspondent character found.
1053 Parameter is a keysym basically from keysymdef.h
1054 XXX: how about vendor keys? Is there some with Unicode value and not in the list?
1055 */
1056 int keysymToUnicode( long keysym, int state ) {
1057 return XKeysym.convertKeysym( keysym, state );
1058 }
1059 int keyEventType2Id( int xEventType ) {
1060 return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED :
1061 xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED : 0;
1062 }
1063 static private long xkeycodeToKeysym(XKeyEvent ev) {
1064 return XKeysym.getKeysym( ev );
1065 }
1066 private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
1067 return XKeysym.xkeycode2primary_keysym( ev );
1068 }
1069 static private int primaryUnicode2JavaKeycode(int uni) {
1070 return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
1071 //return (uni > 0? uni + 0x01000000 : 0);
1072 }
1073 void logIncomingKeyEvent(XKeyEvent ev) {
1074 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1075 keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
1076 }
1077 dumpKeysymArray(ev);
1078 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1079 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev)));
1080 }
1081 }
1082 public void handleKeyPress(XEvent xev) {
1083 super.handleKeyPress(xev);
1084 XKeyEvent ev = xev.get_xkey();
1085 if (eventLog.isLoggable(PlatformLogger.FINE)) {
1086 eventLog.fine(ev.toString());
1087 }
1088 if (isEventDisabled(xev)) {
1089 return;
1090 }
1091 handleKeyPress(ev);
1092 }
1093 // called directly from this package, unlike handleKeyRelease.
1094 // un-final it if you need to override it in a subclass.
1095 final void handleKeyPress(XKeyEvent ev) {
1096 long keysym[] = new long[2];
1097 int unicodeKey = 0;
1098 keysym[0] = XConstants.NoSymbol;
1099
1100 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1101 logIncomingKeyEvent( ev );
1102 }
1103 if ( //TODO check if there's an active input method instance
1104 // without calling a native method. Is it necessary though?
1105 haveCurrentX11InputMethodInstance()) {
1106 if (x11inputMethodLookupString(ev.pData, keysym)) {
1107 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1108 keyEventLog.fine("--XWindow.java XIM did process event; return; dec keysym processed:"+(keysym[0])+
1109 "; hex keysym processed:"+Long.toHexString(keysym[0])
1110 );
1111 }
1112 return;
1113 }else {
1114 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1115 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1116 keyEventLog.fine("--XWindow.java XIM did NOT process event, hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1117 " unicode key:"+Integer.toHexString((int)unicodeKey));
1118 }
1119 }
1120 }else {
1121 // No input method instance found. For example, there's a Java Input Method.
1122 // Produce do-it-yourself keysym and perhaps unicode character.
1123 keysym[0] = xkeycodeToKeysym(ev);
1124 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1125 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1126 keyEventLog.fine("--XWindow.java XIM is absent; hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1127 " unicode key:"+Integer.toHexString((int)unicodeKey));
1128 }
1129 }
1130 // Keysym should be converted to Unicode, if possible and necessary,
1131 // and Java KeyEvent keycode should be calculated.
1132 // For press we should post pressed & typed Java events.
1133 //
1134 // Press event might be not processed to this time because
1135 // (1) either XIM could not handle it or
1136 // (2) it was Latin 1:1 mapping.
1137 //
1138 // Preserve modifiers to get Java key code for dead keys
1139 boolean isDeadKey = isDeadKey(keysym[0]);
1140 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym[0])
1141 : XKeysym.getJavaKeycode(ev);
1142 if( jkc == null ) {
1143 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1144 }
1145
1146 // Take the first keysym from a keysym array associated with the XKeyevent
1147 // and convert it to Unicode. Then, even if a Java keycode for the keystroke
1148 // is undefined, we still have a guess of what has been engraved on a keytop.
1149 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1150
1151 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1152 keyEventLog.fine(">>>Fire Event:"+
1153 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1154 "jkeycode:decimal="+jkc.getJavaKeycode()+
1155 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1156 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1157 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1158 );
1159 }
1160
1161 int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1162 int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1163 primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1164 jkc.getJavaKeycode();
1165 postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1166 ev.get_time(),
1167 isDeadKey ? jkeyExtended : jkeyToReturn,
1168 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1169 jkc.getKeyLocation(),
1170 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1171 unicodeFromPrimaryKeysym,
1172 jkeyExtended);
1173
1174
1175 if (unicodeKey > 0 && !isDeadKey) {
1176 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1177 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1178 }
1179 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1180 ev.get_time(),
1181 java.awt.event.KeyEvent.VK_UNDEFINED,
1182 unicodeKey,
1183 java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1184 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
1185 unicodeFromPrimaryKeysym,
1186 java.awt.event.KeyEvent.VK_UNDEFINED);
1187
1188 }
1189
1190
1191 }
1192
1193 public void handleKeyRelease(XEvent xev) {
1194 super.handleKeyRelease(xev);
1195 XKeyEvent ev = xev.get_xkey();
1196 if (eventLog.isLoggable(PlatformLogger.FINE)) {
1197 eventLog.fine(ev.toString());
1198 }
1199 if (isEventDisabled(xev)) {
1200 return;
1201 }
1202 handleKeyRelease(ev);
1203 }
1204 // un-private it if you need to call it from elsewhere
1205 private void handleKeyRelease(XKeyEvent ev) {
1206 int unicodeKey = 0;
1207
1208 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1209 logIncomingKeyEvent( ev );
1210 }
1211 // Keysym should be converted to Unicode, if possible and necessary,
1212 // and Java KeyEvent keycode should be calculated.
1213 // For release we should post released event.
1214 //
1215 // Preserve modifiers to get Java key code for dead keys
1216 long keysym = xkeycodeToKeysym(ev);
1217 boolean isDeadKey = isDeadKey(keysym);
1218 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym)
1219 : XKeysym.getJavaKeycode(ev);
1220 if( jkc == null ) {
1221 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1222 }
1223 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1224 keyEventLog.fine(">>>Fire Event:"+
1225 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1226 "jkeycode:decimal="+jkc.getJavaKeycode()+
1227 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1228 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1229 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1230 );
1231 }
1232 // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1233 // We used to cache that value and retrieve it on KeyRelease,
1234 // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1235 // might never be cached before.
1236 // Also, switching between keyboard layouts, we might cache a wrong letter.
1237 // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1238 unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
1239
1240 // Take a first keysym from a keysym array associated with the XKeyevent
1241 // and convert it to Unicode. Then, even if Java keycode for the keystroke
1242 // is undefined, we still will have a guess of what was engraved on a keytop.
1243 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1340
1341 boolean isShowing() {
1342 return visible;
1343 }
1344
1345 boolean isResizable() {
1346 return true;
1347 }
1348
1349 boolean isLocationByPlatform() {
1350 return false;
1351 }
1352
1353 void updateSizeHints() {
1354 updateSizeHints(x, y, width, height);
1355 }
1356
1357 void updateSizeHints(int x, int y, int width, int height) {
1358 long flags = XUtilConstants.PSize | (isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition));
1359 if (!isResizable()) {
1360 if (log.isLoggable(PlatformLogger.FINER)) {
1361 log.finer("Window {0} is not resizable", this);
1362 }
1363 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize;
1364 } else {
1365 if (log.isLoggable(PlatformLogger.FINER)) {
1366 log.finer("Window {0} is resizable", this);
1367 }
1368 }
1369 setSizeHints(flags, x, y, width, height);
1370 }
1371
1372 void updateSizeHints(int x, int y) {
1373 long flags = isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition);
1374 if (!isResizable()) {
1375 if (log.isLoggable(PlatformLogger.FINER)) {
1376 log.finer("Window {0} is not resizable", this);
1377 }
1378 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize | XUtilConstants.PSize;
1379 } else {
1380 if (log.isLoggable(PlatformLogger.FINER)) {
1381 log.finer("Window {0} is resizable", this);
1382 }
1383 }
1384 setSizeHints(flags, x, y, width, height);
1385 }
1386
1387 void validateSurface() {
1388 if ((width != oldWidth) || (height != oldHeight)) {
1389 doValidateSurface();
1390
1391 oldWidth = width;
1392 oldHeight = height;
1393 }
1394 }
1395
1396 final void doValidateSurface() {
1397 SurfaceData oldData = surfaceData;
1398 if (oldData != null) {
1399 surfaceData = graphicsConfig.createSurfaceData(this);
1400 oldData.invalidate();
|
385 }
386
387 /**
388 * Returns true if the event has been handled and should not be
389 * posted to Java.
390 */
391 boolean prePostEvent(AWTEvent e) {
392 return false;
393 }
394
395 static Method m_sendMessage;
396 static void sendEvent(final AWTEvent e) {
397 // The uses of this method imply that the incoming event is system-generated
398 SunToolkit.setSystemGenerated(e);
399 PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
400 public void run() {
401 AWTAccessor.getAWTEventAccessor().setPosted(e);
402 ((Component)e.getSource()).dispatchEvent(e);
403 }
404 }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
405 if (focusLog.isLoggable(PlatformLogger.Level.FINER) && (e instanceof FocusEvent)) {
406 focusLog.finer("Sending " + e);
407 }
408 XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), pe);
409 }
410
411
412 /*
413 * Post an event to the event queue.
414 */
415 // NOTE: This method may be called by privileged threads.
416 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
417 void postEvent(AWTEvent event) {
418 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
419 }
420
421 static void postEventStatic(AWTEvent event) {
422 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
423 }
424
425 public void postEventToEventQueue(final AWTEvent event) {
645 rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
646 }
647 finally {
648 XToolkit.awtUnlock();
649 }
650 }
651 return rbutton;
652 }
653
654 static int getMouseMovementSmudge() {
655 //TODO: It's possible to read corresponding settings
656 return AWT_MULTICLICK_SMUDGE;
657 }
658
659 public void handleButtonPressRelease(XEvent xev) {
660 super.handleButtonPressRelease(xev);
661 XButtonEvent xbe = xev.get_xbutton();
662 if (isEventDisabled(xev)) {
663 return;
664 }
665 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
666 eventLog.fine(xbe.toString());
667 }
668 long when;
669 int modifiers;
670 boolean popupTrigger = false;
671 int button=0;
672 boolean wheel_mouse = false;
673 int lbutton = xbe.get_button();
674 /*
675 * Ignore the buttons above 20 due to the bit limit for
676 * InputEvent.BUTTON_DOWN_MASK.
677 * One more bit is reserved for FIRST_HIGH_BIT.
678 */
679 if (lbutton > SunToolkit.MAX_BUTTONS_SUPPORTED) {
680 return;
681 }
682 int type = xev.get_type();
683 when = xbe.get_time();
684 long jWhen = XToolkit.nowMillisUTC_offset(when);
685
686 int x = xbe.get_x();
687 int y = xbe.get_y();
688 if (xev.get_xany().get_window() != window) {
689 Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
690 x = localXY.x;
691 y = localXY.y;
692 }
693
694 if (type == XConstants.ButtonPress) {
695 //Allow this mouse button to generate CLICK event on next ButtonRelease
696 mouseButtonClickAllowed |= XlibUtil.getButtonMask(lbutton);
697 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
698 /*
699 multiclick checking
700 */
701 if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
702 eventLog.finest("lastWindow = " + lastWindow + ", lastButton "
703 + lastButton + ", lastTime " + lastTime + ", multiClickTime "
704 + XToolkit.getMultiClickTime());
705 }
706 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) {
707 clickCount++;
708 } else {
709 clickCount = 1;
710 lastWindowRef = new WeakReference(this);
711 lastButton = lbutton;
712 lastX = x;
713 lastY = y;
714 }
715 lastTime = when;
716
717
718 /*
719 Check for popup trigger !!
720 */
721 if (lbutton == getRightButtonNumber() || lbutton > 2) {
874 synchronized (getStateLock()) {
875 mouseAboveMe = above;
876 }
877 }
878
879 protected void enterNotify(long window) {
880 if (window == getWindow()) {
881 setMouseAbove(true);
882 }
883 }
884 protected void leaveNotify(long window) {
885 if (window == getWindow()) {
886 setMouseAbove(false);
887 }
888 }
889
890 public void handleXCrossingEvent(XEvent xev) {
891 super.handleXCrossingEvent(xev);
892 XCrossingEvent xce = xev.get_xcrossing();
893
894 if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
895 eventLog.finest(xce.toString());
896 }
897
898 if (xce.get_type() == XConstants.EnterNotify) {
899 enterNotify(xce.get_window());
900 } else { // LeaveNotify:
901 leaveNotify(xce.get_window());
902 }
903
904 // Skip event If it was caused by a grab
905 // This is needed because on displays with focus-follows-mouse on MousePress X system generates
906 // two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
907 // current component. Second one notifies that it has entered into the same component.
908 // This looks like the window under the mouse has actually changed and Java handle these events
909 // accordingly. This leads to impossibility to make a double click on Component (6404708)
910 XWindowPeer toplevel = getToplevelXWindow();
911 if (toplevel != null && !toplevel.isModalBlocked()){
912 if (xce.get_mode() != XConstants.NotifyNormal) {
913 // 6404708 : need update cursor in accordance with skipping Leave/EnterNotify event
914 // whereas it doesn't need to handled further.
978 xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount, popupTrigger,
979 MouseEvent.NOBUTTON);
980 postEventToEventQueue(me);
981 eventLog.finest("Clearing last window ref");
982 lastWindowRef = null;
983 }
984 if (xce.get_type() == XConstants.EnterNotify) {
985 MouseEvent me = new MouseEvent(getEventSource(), MouseEvent.MOUSE_ENTERED,
986 jWhen, modifiers, xce.get_x(), xce.get_y(), xce.get_x_root(), xce.get_y_root(), clickCount,
987 popupTrigger, MouseEvent.NOBUTTON);
988 postEventToEventQueue(me);
989 }
990 }
991
992 public void doLayout(int x, int y, int width, int height) {}
993
994 public void handleConfigureNotifyEvent(XEvent xev) {
995 Rectangle oldBounds = getBounds();
996
997 super.handleConfigureNotifyEvent(xev);
998 if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
999 insLog.finer("Configure, {0}, event disabled: {1}",
1000 xev.get_xconfigure(), isEventDisabled(xev));
1001 }
1002 if (isEventDisabled(xev)) {
1003 return;
1004 }
1005
1006 // if ( Check if it's a resize, a move, or a stacking order change )
1007 // {
1008 Rectangle bounds = getBounds();
1009 if (!bounds.getSize().equals(oldBounds.getSize())) {
1010 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
1011 }
1012 if (!bounds.getLocation().equals(oldBounds.getLocation())) {
1013 postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
1014 }
1015 // }
1016 }
1017
1018 public void handleMapNotifyEvent(XEvent xev) {
1019 super.handleMapNotifyEvent(xev);
1020 if (log.isLoggable(PlatformLogger.Level.FINE)) {
1021 log.fine("Mapped {0}", this);
1022 }
1023 if (isEventDisabled(xev)) {
1024 return;
1025 }
1026 ComponentEvent ce;
1027
1028 ce = new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_SHOWN);
1029 postEventToEventQueue(ce);
1030 }
1031
1032 public void handleUnmapNotifyEvent(XEvent xev) {
1033 super.handleUnmapNotifyEvent(xev);
1034 if (isEventDisabled(xev)) {
1035 return;
1036 }
1037 ComponentEvent ce;
1038
1039 ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
1040 postEventToEventQueue(ce);
1041 }
1042
1043 private void dumpKeysymArray(XKeyEvent ev) {
1044 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1045 keyEventLog.fine(" "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 0))+
1046 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 1))+
1047 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 2))+
1048 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 3)));
1049 }
1050 }
1051 /**
1052 Return unicode character or 0 if no correspondent character found.
1053 Parameter is a keysym basically from keysymdef.h
1054 XXX: how about vendor keys? Is there some with Unicode value and not in the list?
1055 */
1056 int keysymToUnicode( long keysym, int state ) {
1057 return XKeysym.convertKeysym( keysym, state );
1058 }
1059 int keyEventType2Id( int xEventType ) {
1060 return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED :
1061 xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED : 0;
1062 }
1063 static private long xkeycodeToKeysym(XKeyEvent ev) {
1064 return XKeysym.getKeysym( ev );
1065 }
1066 private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
1067 return XKeysym.xkeycode2primary_keysym( ev );
1068 }
1069 static private int primaryUnicode2JavaKeycode(int uni) {
1070 return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
1071 //return (uni > 0? uni + 0x01000000 : 0);
1072 }
1073 void logIncomingKeyEvent(XKeyEvent ev) {
1074 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1075 keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
1076 }
1077 dumpKeysymArray(ev);
1078 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1079 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev)));
1080 }
1081 }
1082 public void handleKeyPress(XEvent xev) {
1083 super.handleKeyPress(xev);
1084 XKeyEvent ev = xev.get_xkey();
1085 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
1086 eventLog.fine(ev.toString());
1087 }
1088 if (isEventDisabled(xev)) {
1089 return;
1090 }
1091 handleKeyPress(ev);
1092 }
1093 // called directly from this package, unlike handleKeyRelease.
1094 // un-final it if you need to override it in a subclass.
1095 final void handleKeyPress(XKeyEvent ev) {
1096 long keysym[] = new long[2];
1097 int unicodeKey = 0;
1098 keysym[0] = XConstants.NoSymbol;
1099
1100 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1101 logIncomingKeyEvent( ev );
1102 }
1103 if ( //TODO check if there's an active input method instance
1104 // without calling a native method. Is it necessary though?
1105 haveCurrentX11InputMethodInstance()) {
1106 if (x11inputMethodLookupString(ev.pData, keysym)) {
1107 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1108 keyEventLog.fine("--XWindow.java XIM did process event; return; dec keysym processed:"+(keysym[0])+
1109 "; hex keysym processed:"+Long.toHexString(keysym[0])
1110 );
1111 }
1112 return;
1113 }else {
1114 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1115 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1116 keyEventLog.fine("--XWindow.java XIM did NOT process event, hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1117 " unicode key:"+Integer.toHexString((int)unicodeKey));
1118 }
1119 }
1120 }else {
1121 // No input method instance found. For example, there's a Java Input Method.
1122 // Produce do-it-yourself keysym and perhaps unicode character.
1123 keysym[0] = xkeycodeToKeysym(ev);
1124 unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1125 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1126 keyEventLog.fine("--XWindow.java XIM is absent; hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1127 " unicode key:"+Integer.toHexString((int)unicodeKey));
1128 }
1129 }
1130 // Keysym should be converted to Unicode, if possible and necessary,
1131 // and Java KeyEvent keycode should be calculated.
1132 // For press we should post pressed & typed Java events.
1133 //
1134 // Press event might be not processed to this time because
1135 // (1) either XIM could not handle it or
1136 // (2) it was Latin 1:1 mapping.
1137 //
1138 // Preserve modifiers to get Java key code for dead keys
1139 boolean isDeadKey = isDeadKey(keysym[0]);
1140 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym[0])
1141 : XKeysym.getJavaKeycode(ev);
1142 if( jkc == null ) {
1143 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1144 }
1145
1146 // Take the first keysym from a keysym array associated with the XKeyevent
1147 // and convert it to Unicode. Then, even if a Java keycode for the keystroke
1148 // is undefined, we still have a guess of what has been engraved on a keytop.
1149 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1150
1151 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1152 keyEventLog.fine(">>>Fire Event:"+
1153 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1154 "jkeycode:decimal="+jkc.getJavaKeycode()+
1155 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1156 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1157 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1158 );
1159 }
1160
1161 int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1162 int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1163 primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1164 jkc.getJavaKeycode();
1165 postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1166 ev.get_time(),
1167 isDeadKey ? jkeyExtended : jkeyToReturn,
1168 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1169 jkc.getKeyLocation(),
1170 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1171 unicodeFromPrimaryKeysym,
1172 jkeyExtended);
1173
1174
1175 if (unicodeKey > 0 && !isDeadKey) {
1176 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1177 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1178 }
1179 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1180 ev.get_time(),
1181 java.awt.event.KeyEvent.VK_UNDEFINED,
1182 unicodeKey,
1183 java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1184 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
1185 unicodeFromPrimaryKeysym,
1186 java.awt.event.KeyEvent.VK_UNDEFINED);
1187
1188 }
1189
1190
1191 }
1192
1193 public void handleKeyRelease(XEvent xev) {
1194 super.handleKeyRelease(xev);
1195 XKeyEvent ev = xev.get_xkey();
1196 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
1197 eventLog.fine(ev.toString());
1198 }
1199 if (isEventDisabled(xev)) {
1200 return;
1201 }
1202 handleKeyRelease(ev);
1203 }
1204 // un-private it if you need to call it from elsewhere
1205 private void handleKeyRelease(XKeyEvent ev) {
1206 int unicodeKey = 0;
1207
1208 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1209 logIncomingKeyEvent( ev );
1210 }
1211 // Keysym should be converted to Unicode, if possible and necessary,
1212 // and Java KeyEvent keycode should be calculated.
1213 // For release we should post released event.
1214 //
1215 // Preserve modifiers to get Java key code for dead keys
1216 long keysym = xkeycodeToKeysym(ev);
1217 boolean isDeadKey = isDeadKey(keysym);
1218 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym)
1219 : XKeysym.getJavaKeycode(ev);
1220 if( jkc == null ) {
1221 jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1222 }
1223 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
1224 keyEventLog.fine(">>>Fire Event:"+
1225 (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1226 "jkeycode:decimal="+jkc.getJavaKeycode()+
1227 ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1228 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1229 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1230 );
1231 }
1232 // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1233 // We used to cache that value and retrieve it on KeyRelease,
1234 // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1235 // might never be cached before.
1236 // Also, switching between keyboard layouts, we might cache a wrong letter.
1237 // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1238 unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
1239
1240 // Take a first keysym from a keysym array associated with the XKeyevent
1241 // and convert it to Unicode. Then, even if Java keycode for the keystroke
1242 // is undefined, we still will have a guess of what was engraved on a keytop.
1243 int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1340
1341 boolean isShowing() {
1342 return visible;
1343 }
1344
1345 boolean isResizable() {
1346 return true;
1347 }
1348
1349 boolean isLocationByPlatform() {
1350 return false;
1351 }
1352
1353 void updateSizeHints() {
1354 updateSizeHints(x, y, width, height);
1355 }
1356
1357 void updateSizeHints(int x, int y, int width, int height) {
1358 long flags = XUtilConstants.PSize | (isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition));
1359 if (!isResizable()) {
1360 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1361 log.finer("Window {0} is not resizable", this);
1362 }
1363 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize;
1364 } else {
1365 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1366 log.finer("Window {0} is resizable", this);
1367 }
1368 }
1369 setSizeHints(flags, x, y, width, height);
1370 }
1371
1372 void updateSizeHints(int x, int y) {
1373 long flags = isLocationByPlatform() ? 0 : (XUtilConstants.PPosition | XUtilConstants.USPosition);
1374 if (!isResizable()) {
1375 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1376 log.finer("Window {0} is not resizable", this);
1377 }
1378 flags |= XUtilConstants.PMinSize | XUtilConstants.PMaxSize | XUtilConstants.PSize;
1379 } else {
1380 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1381 log.finer("Window {0} is resizable", this);
1382 }
1383 }
1384 setSizeHints(flags, x, y, width, height);
1385 }
1386
1387 void validateSurface() {
1388 if ((width != oldWidth) || (height != oldHeight)) {
1389 doValidateSurface();
1390
1391 oldWidth = width;
1392 oldHeight = height;
1393 }
1394 }
1395
1396 final void doValidateSurface() {
1397 SurfaceData oldData = surfaceData;
1398 if (oldData != null) {
1399 surfaceData = graphicsConfig.createSurfaceData(this);
1400 oldData.invalidate();
|