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)) focusLog.finer("Sending " + e);
406 XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), pe);
407 }
408
409
410 /*
411 * Post an event to the event queue.
412 */
413 // NOTE: This method may be called by privileged threads.
414 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
415 void postEvent(AWTEvent event) {
416 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
417 }
418
419 static void postEventStatic(AWTEvent event) {
420 XToolkit.postEvent(XToolkit.targetToAppContext(event.getSource()), event);
421 }
422
423 public void postEventToEventQueue(final AWTEvent event) {
424 //fix for 6239938 : Choice drop-down does not disappear when it loses focus, on XToolkit
425 if (!prePostEvent(event)) {
643 rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
644 }
645 finally {
646 XToolkit.awtUnlock();
647 }
648 }
649 return rbutton;
650 }
651
652 static int getMouseMovementSmudge() {
653 //TODO: It's possible to read corresponding settings
654 return AWT_MULTICLICK_SMUDGE;
655 }
656
657 public void handleButtonPressRelease(XEvent xev) {
658 super.handleButtonPressRelease(xev);
659 XButtonEvent xbe = xev.get_xbutton();
660 if (isEventDisabled(xev)) {
661 return;
662 }
663 if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(xbe.toString());
664 long when;
665 int modifiers;
666 boolean popupTrigger = false;
667 int button=0;
668 boolean wheel_mouse = false;
669 int lbutton = xbe.get_button();
670 /*
671 * Ignore the buttons above 20 due to the bit limit for
672 * InputEvent.BUTTON_DOWN_MASK.
673 * One more bit is reserved for FIRST_HIGH_BIT.
674 */
675 if (lbutton > SunToolkit.MAX_BUTTONS_SUPPORTED) {
676 return;
677 }
678 int type = xev.get_type();
679 when = xbe.get_time();
680 long jWhen = XToolkit.nowMillisUTC_offset(when);
681
682 int x = xbe.get_x();
683 int y = xbe.get_y();
684 if (xev.get_xany().get_window() != window) {
685 Point localXY = toLocal(xbe.get_x_root(), xbe.get_y_root());
686 x = localXY.x;
687 y = localXY.y;
688 }
689
690 if (type == XConstants.ButtonPress) {
691 //Allow this mouse button to generate CLICK event on next ButtonRelease
692 mouseButtonClickAllowed |= XlibUtil.getButtonMask(lbutton);
693 XWindow lastWindow = (lastWindowRef != null) ? ((XWindow)lastWindowRef.get()):(null);
694 /*
695 multiclick checking
696 */
697 if (eventLog.isLoggable(PlatformLogger.FINEST)) eventLog.finest("lastWindow = " + lastWindow + ", lastButton "
698 + lastButton + ", lastTime " + lastTime + ", multiClickTime "
699 + XToolkit.getMultiClickTime());
700 if (lastWindow == this && lastButton == lbutton && (when - lastTime) < XToolkit.getMultiClickTime()) {
701 clickCount++;
702 } else {
703 clickCount = 1;
704 lastWindowRef = new WeakReference(this);
705 lastButton = lbutton;
706 lastX = x;
707 lastY = y;
708 }
709 lastTime = when;
710
711
712 /*
713 Check for popup trigger !!
714 */
715 if (lbutton == getRightButtonNumber() || lbutton > 2) {
716 popupTrigger = true;
717 } else {
718 popupTrigger = false;
719 }
868 synchronized (getStateLock()) {
869 mouseAboveMe = above;
870 }
871 }
872
873 protected void enterNotify(long window) {
874 if (window == getWindow()) {
875 setMouseAbove(true);
876 }
877 }
878 protected void leaveNotify(long window) {
879 if (window == getWindow()) {
880 setMouseAbove(false);
881 }
882 }
883
884 public void handleXCrossingEvent(XEvent xev) {
885 super.handleXCrossingEvent(xev);
886 XCrossingEvent xce = xev.get_xcrossing();
887
888 if (eventLog.isLoggable(PlatformLogger.FINEST)) eventLog.finest(xce.toString());
889
890 if (xce.get_type() == XConstants.EnterNotify) {
891 enterNotify(xce.get_window());
892 } else { // LeaveNotify:
893 leaveNotify(xce.get_window());
894 }
895
896 // Skip event If it was caused by a grab
897 // This is needed because on displays with focus-follows-mouse on MousePress X system generates
898 // two XCrossing events with mode != NormalNotify. First of them notifies that the mouse has left
899 // current component. Second one notifies that it has entered into the same component.
900 // This looks like the window under the mouse has actually changed and Java handle these events
901 // accordingly. This leads to impossibility to make a double click on Component (6404708)
902 XWindowPeer toplevel = getToplevelXWindow();
903 if (toplevel != null && !toplevel.isModalBlocked()){
904 if (xce.get_mode() != XConstants.NotifyNormal) {
905 // 6404708 : need update cursor in accordance with skipping Leave/EnterNotify event
906 // whereas it doesn't need to handled further.
907 if (xce.get_type() == XConstants.EnterNotify) {
908 XAwtState.setComponentMouseEntered(getEventSource());
1012 return;
1013 }
1014 ComponentEvent ce;
1015
1016 ce = new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_SHOWN);
1017 postEventToEventQueue(ce);
1018 }
1019
1020 public void handleUnmapNotifyEvent(XEvent xev) {
1021 super.handleUnmapNotifyEvent(xev);
1022 if (isEventDisabled(xev)) {
1023 return;
1024 }
1025 ComponentEvent ce;
1026
1027 ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
1028 postEventToEventQueue(ce);
1029 }
1030
1031 private void dumpKeysymArray(XKeyEvent ev) {
1032 keyEventLog.fine(" "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 0))+
1033 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 1))+
1034 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 2))+
1035 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 3)));
1036 }
1037 /**
1038 Return unicode character or 0 if no correspondent character found.
1039 Parameter is a keysym basically from keysymdef.h
1040 XXX: how about vendor keys? Is there some with Unicode value and not in the list?
1041 */
1042 int keysymToUnicode( long keysym, int state ) {
1043 return XKeysym.convertKeysym( keysym, state );
1044 }
1045 int keyEventType2Id( int xEventType ) {
1046 return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED :
1047 xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED : 0;
1048 }
1049 static private long xkeycodeToKeysym(XKeyEvent ev) {
1050 return XKeysym.getKeysym( ev );
1051 }
1052 private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
1053 return XKeysym.xkeycode2primary_keysym( ev );
1054 }
1055 static private int primaryUnicode2JavaKeycode(int uni) {
1056 return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
1057 //return (uni > 0? uni + 0x01000000 : 0);
1058 }
1059 void logIncomingKeyEvent(XKeyEvent ev) {
1060 keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
1061 dumpKeysymArray(ev);
1062 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev)));
1063 }
1064 public void handleKeyPress(XEvent xev) {
1065 super.handleKeyPress(xev);
1066 XKeyEvent ev = xev.get_xkey();
1067 if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(ev.toString());
1068 if (isEventDisabled(xev)) {
1069 return;
1070 }
1071 handleKeyPress(ev);
1072 }
1073 // called directly from this package, unlike handleKeyRelease.
1074 // un-final it if you need to override it in a subclass.
1075 final void handleKeyPress(XKeyEvent ev) {
1076 long keysym[] = new long[2];
1077 int unicodeKey = 0;
1078 keysym[0] = XConstants.NoSymbol;
1079
1080 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1081 logIncomingKeyEvent( ev );
1082 }
1083 if ( //TODO check if there's an active input method instance
1084 // without calling a native method. Is it necessary though?
1085 haveCurrentX11InputMethodInstance()) {
1086 if (x11inputMethodLookupString(ev.pData, keysym)) {
1087 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1136 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1137 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1138 );
1139 }
1140
1141 int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1142 int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1143 primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1144 jkc.getJavaKeycode();
1145 postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1146 ev.get_time(),
1147 isDeadKey ? jkeyExtended : jkeyToReturn,
1148 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1149 jkc.getKeyLocation(),
1150 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1151 unicodeFromPrimaryKeysym,
1152 jkeyExtended);
1153
1154
1155 if (unicodeKey > 0 && !isDeadKey) {
1156 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1157 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1158 ev.get_time(),
1159 java.awt.event.KeyEvent.VK_UNDEFINED,
1160 unicodeKey,
1161 java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1162 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
1163 unicodeFromPrimaryKeysym,
1164 java.awt.event.KeyEvent.VK_UNDEFINED);
1165
1166 }
1167
1168
1169 }
1170
1171 public void handleKeyRelease(XEvent xev) {
1172 super.handleKeyRelease(xev);
1173 XKeyEvent ev = xev.get_xkey();
1174 if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(ev.toString());
1175 if (isEventDisabled(xev)) {
1176 return;
1177 }
1178 handleKeyRelease(ev);
1179 }
1180 // un-private it if you need to call it from elsewhere
1181 private void handleKeyRelease(XKeyEvent ev) {
1182 int unicodeKey = 0;
1183
1184 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1185 logIncomingKeyEvent( ev );
1186 }
1187 // Keysym should be converted to Unicode, if possible and necessary,
1188 // and Java KeyEvent keycode should be calculated.
1189 // For release we should post released event.
1190 //
1191 // Preserve modifiers to get Java key code for dead keys
1192 long keysym = xkeycodeToKeysym(ev);
1193 boolean isDeadKey = isDeadKey(keysym);
1194 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym)
|
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) {
426 //fix for 6239938 : Choice drop-down does not disappear when it loses focus, on XToolkit
427 if (!prePostEvent(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) {
722 popupTrigger = true;
723 } else {
724 popupTrigger = false;
725 }
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.
915 if (xce.get_type() == XConstants.EnterNotify) {
916 XAwtState.setComponentMouseEntered(getEventSource());
1020 return;
1021 }
1022 ComponentEvent ce;
1023
1024 ce = new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_SHOWN);
1025 postEventToEventQueue(ce);
1026 }
1027
1028 public void handleUnmapNotifyEvent(XEvent xev) {
1029 super.handleUnmapNotifyEvent(xev);
1030 if (isEventDisabled(xev)) {
1031 return;
1032 }
1033 ComponentEvent ce;
1034
1035 ce = new ComponentEvent(target, ComponentEvent.COMPONENT_HIDDEN);
1036 postEventToEventQueue(ce);
1037 }
1038
1039 private void dumpKeysymArray(XKeyEvent ev) {
1040 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1041 keyEventLog.fine(" "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 0))+
1042 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 1))+
1043 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 2))+
1044 "\n "+Long.toHexString(XlibWrapper.XKeycodeToKeysym(XToolkit.getDisplay(), ev.get_keycode(), 3)));
1045 }
1046 }
1047 /**
1048 Return unicode character or 0 if no correspondent character found.
1049 Parameter is a keysym basically from keysymdef.h
1050 XXX: how about vendor keys? Is there some with Unicode value and not in the list?
1051 */
1052 int keysymToUnicode( long keysym, int state ) {
1053 return XKeysym.convertKeysym( keysym, state );
1054 }
1055 int keyEventType2Id( int xEventType ) {
1056 return xEventType == XConstants.KeyPress ? java.awt.event.KeyEvent.KEY_PRESSED :
1057 xEventType == XConstants.KeyRelease ? java.awt.event.KeyEvent.KEY_RELEASED : 0;
1058 }
1059 static private long xkeycodeToKeysym(XKeyEvent ev) {
1060 return XKeysym.getKeysym( ev );
1061 }
1062 private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
1063 return XKeysym.xkeycode2primary_keysym( ev );
1064 }
1065 static private int primaryUnicode2JavaKeycode(int uni) {
1066 return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
1067 //return (uni > 0? uni + 0x01000000 : 0);
1068 }
1069 void logIncomingKeyEvent(XKeyEvent ev) {
1070 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1071 keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
1072 }
1073 dumpKeysymArray(ev);
1074 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1075 keyEventLog.fine("XXXXXXXXXXXXXX javakeycode will be most probably:0x"+ Integer.toHexString(XKeysym.getJavaKeycodeOnly(ev)));
1076 }
1077 }
1078 public void handleKeyPress(XEvent xev) {
1079 super.handleKeyPress(xev);
1080 XKeyEvent ev = xev.get_xkey();
1081 if (eventLog.isLoggable(PlatformLogger.FINE)) {
1082 eventLog.fine(ev.toString());
1083 }
1084 if (isEventDisabled(xev)) {
1085 return;
1086 }
1087 handleKeyPress(ev);
1088 }
1089 // called directly from this package, unlike handleKeyRelease.
1090 // un-final it if you need to override it in a subclass.
1091 final void handleKeyPress(XKeyEvent ev) {
1092 long keysym[] = new long[2];
1093 int unicodeKey = 0;
1094 keysym[0] = XConstants.NoSymbol;
1095
1096 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1097 logIncomingKeyEvent( ev );
1098 }
1099 if ( //TODO check if there's an active input method instance
1100 // without calling a native method. Is it necessary though?
1101 haveCurrentX11InputMethodInstance()) {
1102 if (x11inputMethodLookupString(ev.pData, keysym)) {
1103 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1152 " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1153 ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1154 );
1155 }
1156
1157 int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1158 int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1159 primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1160 jkc.getJavaKeycode();
1161 postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1162 ev.get_time(),
1163 isDeadKey ? jkeyExtended : jkeyToReturn,
1164 (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1165 jkc.getKeyLocation(),
1166 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1167 unicodeFromPrimaryKeysym,
1168 jkeyExtended);
1169
1170
1171 if (unicodeKey > 0 && !isDeadKey) {
1172 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1173 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1174 }
1175 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1176 ev.get_time(),
1177 java.awt.event.KeyEvent.VK_UNDEFINED,
1178 unicodeKey,
1179 java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1180 ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
1181 unicodeFromPrimaryKeysym,
1182 java.awt.event.KeyEvent.VK_UNDEFINED);
1183
1184 }
1185
1186
1187 }
1188
1189 public void handleKeyRelease(XEvent xev) {
1190 super.handleKeyRelease(xev);
1191 XKeyEvent ev = xev.get_xkey();
1192 if (eventLog.isLoggable(PlatformLogger.FINE)) {
1193 eventLog.fine(ev.toString());
1194 }
1195 if (isEventDisabled(xev)) {
1196 return;
1197 }
1198 handleKeyRelease(ev);
1199 }
1200 // un-private it if you need to call it from elsewhere
1201 private void handleKeyRelease(XKeyEvent ev) {
1202 int unicodeKey = 0;
1203
1204 if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1205 logIncomingKeyEvent( ev );
1206 }
1207 // Keysym should be converted to Unicode, if possible and necessary,
1208 // and Java KeyEvent keycode should be calculated.
1209 // For release we should post released event.
1210 //
1211 // Preserve modifiers to get Java key code for dead keys
1212 long keysym = xkeycodeToKeysym(ev);
1213 boolean isDeadKey = isDeadKey(keysym);
1214 XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym)
|