src/solaris/classes/sun/awt/X11/XWindow.java

Print this page




1098                 }
1099             }
1100         }else  {
1101             // No input method instance found. For example, there's a Java Input Method.
1102             // Produce do-it-yourself keysym and perhaps unicode character.
1103             keysym[0] = xkeycodeToKeysym(ev);
1104             unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1105             if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1106                 keyEventLog.fine("--XWindow.java XIM is absent;             hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1107                                  "                                         unicode key:"+Integer.toHexString((int)unicodeKey));
1108             }
1109         }
1110         // Keysym should be converted to Unicode, if possible and necessary,
1111         // and Java KeyEvent keycode should be calculated.
1112         // For press we should post pressed & typed Java events.
1113         //
1114         // Press event might be not processed to this time because
1115         //  (1) either XIM could not handle it or
1116         //  (2) it was Latin 1:1 mapping.
1117         //
1118         XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);



1119         if( jkc == null ) {
1120             jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1121         }
1122 
1123         // Take the first keysym from a keysym array associated with the XKeyevent
1124         // and convert it to Unicode. Then, even if a Java keycode for the keystroke
1125         // is undefined, we still have a guess of what has been engraved on a keytop.
1126         int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1127 
1128         if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1129             keyEventLog.fine(">>>Fire Event:"+
1130                (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1131                "jkeycode:decimal="+jkc.getJavaKeycode()+
1132                ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1133                " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1134                ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1135             );
1136         }
1137 
1138         int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1139         int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1140                            primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1141                              jkc.getJavaKeycode();
1142         postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
1143                           ev.get_time(),
1144                           jkeyToReturn,
1145                           (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1146                           jkc.getKeyLocation(),
1147                           ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1148                           unicodeFromPrimaryKeysym,
1149                           jkeyExtended);
1150 
1151 
1152         if( unicodeKey > 0 ) {
1153                 keyEventLog.fine("fire _TYPED on "+unicodeKey);
1154                 postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
1155                               ev.get_time(),
1156                               java.awt.event.KeyEvent.VK_UNDEFINED,
1157                               unicodeKey,
1158                               java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
1159                               ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
1160                               unicodeFromPrimaryKeysym,
1161                               java.awt.event.KeyEvent.VK_UNDEFINED);
1162 
1163         }
1164 
1165 
1166     }
1167 
1168     public void handleKeyRelease(XEvent xev) {
1169         super.handleKeyRelease(xev);
1170         XKeyEvent ev = xev.get_xkey();
1171         if (eventLog.isLoggable(PlatformLogger.FINE)) eventLog.fine(ev.toString());
1172         if (isEventDisabled(xev)) {
1173             return;
1174         }
1175         handleKeyRelease(ev);
1176     }
1177     // un-private it if you need to call it from elsewhere
1178     private void handleKeyRelease(XKeyEvent ev) {
1179         long keysym[] = new long[2];
1180         int unicodeKey = 0;
1181         keysym[0] = XConstants.NoSymbol;
1182 
1183         if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1184             logIncomingKeyEvent( ev );
1185         }
1186         // Keysym should be converted to Unicode, if possible and necessary,
1187         // and Java KeyEvent keycode should be calculated.
1188         // For release we should post released event.
1189         //
1190         XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev);




1191         if( jkc == null ) {
1192             jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1193         }
1194         if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1195             keyEventLog.fine(">>>Fire Event:"+
1196                (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1197                "jkeycode:decimal="+jkc.getJavaKeycode()+
1198                ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1199                " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1200                ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1201             );
1202         }
1203         // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1204         // We used to cache that value and retrieve it on KeyRelease,
1205         // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1206         // might never be cached before.
1207         // Also, switching between keyboard layouts, we might cache a wrong letter.
1208         // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1209         unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
1210 
1211         // Take a first keysym from a keysym array associated with the XKeyevent
1212         // and convert it to Unicode. Then, even if Java keycode for the keystroke
1213         // is undefined, we still will have a guess of what was engraved on a keytop.
1214         int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1215 
1216         int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1217         int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1218                            primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1219                              jkc.getJavaKeycode();
1220         postKeyEvent(  java.awt.event.KeyEvent.KEY_RELEASED,
1221                           ev.get_time(),
1222                           jkeyToReturn,
1223                           (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1224                           jkc.getKeyLocation(),
1225                           ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1226                           unicodeFromPrimaryKeysym,
1227                           jkeyExtended);
1228 
1229 
1230     }





1231 
1232     /*
1233      * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
1234      * unreliable, since mapping changes can happen for a virtual desktop
1235      * switch or MacOS style shading that became quite popular under X as
1236      * well.  Yes, it probably should not be this way, as it violates
1237      * ICCCM, but reality is that quite a lot of window managers abuse
1238      * mapping state.
1239      */
1240     int getWMState() {
1241         if (stateChanged) {
1242             stateChanged = false;
1243             WindowPropertyGetter getter =
1244                 new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
1245                                          XWM.XA_WM_STATE);
1246             try {
1247                 int status = getter.execute();
1248                 if (status != XConstants.Success || getter.getData() == 0) {
1249                     return savedState = XUtilConstants.WithdrawnState;
1250                 }




1098                 }
1099             }
1100         }else  {
1101             // No input method instance found. For example, there's a Java Input Method.
1102             // Produce do-it-yourself keysym and perhaps unicode character.
1103             keysym[0] = xkeycodeToKeysym(ev);
1104             unicodeKey = keysymToUnicode( keysym[0], ev.get_state() );
1105             if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1106                 keyEventLog.fine("--XWindow.java XIM is absent;             hex keysym:"+Long.toHexString(keysym[0])+"\n"+
1107                                  "                                         unicode key:"+Integer.toHexString((int)unicodeKey));
1108             }
1109         }
1110         // Keysym should be converted to Unicode, if possible and necessary,
1111         // and Java KeyEvent keycode should be calculated.
1112         // For press we should post pressed & typed Java events.
1113         //
1114         // Press event might be not processed to this time because
1115         //  (1) either XIM could not handle it or
1116         //  (2) it was Latin 1:1 mapping.
1117         //
1118         // Preserve modifiers to get Java key code for dead keys  
1119         boolean isDeadKey = isDeadKey(keysym[0]);        
1120         XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym[0])
1121                 : XKeysym.getJavaKeycode(ev);
1122         if( jkc == null ) {
1123             jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1124         }
1125 
1126         // Take the first keysym from a keysym array associated with the XKeyevent
1127         // and convert it to Unicode. Then, even if a Java keycode for the keystroke
1128         // is undefined, we still have a guess of what has been engraved on a keytop.
1129         int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1130 
1131         if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1132             keyEventLog.fine(">>>Fire Event:"+
1133                (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1134                "jkeycode:decimal="+jkc.getJavaKeycode()+
1135                ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
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)
1195                 : XKeysym.getJavaKeycode(ev);        
1196         if( jkc == null ) {
1197             jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
1198         }
1199         if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
1200             keyEventLog.fine(">>>Fire Event:"+
1201                (ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
1202                "jkeycode:decimal="+jkc.getJavaKeycode()+
1203                ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
1204                " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
1205                ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
1206             );
1207         }
1208         // We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
1209         // We used to cache that value and retrieve it on KeyRelease,
1210         // but in case for example of a dead key+vowel pair, a vowel after a deadkey
1211         // might never be cached before.
1212         // Also, switching between keyboard layouts, we might cache a wrong letter.
1213         // That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
1214         unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
1215 
1216         // Take a first keysym from a keysym array associated with the XKeyevent
1217         // and convert it to Unicode. Then, even if Java keycode for the keystroke
1218         // is undefined, we still will have a guess of what was engraved on a keytop.
1219         int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
1220 
1221         int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
1222         int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
1223                            primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
1224                              jkc.getJavaKeycode();
1225         postKeyEvent(  java.awt.event.KeyEvent.KEY_RELEASED,
1226                           ev.get_time(),
1227                           isDeadKey ? jkeyExtended : jkeyToReturn,
1228                           (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
1229                           jkc.getKeyLocation(),
1230                           ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
1231                           unicodeFromPrimaryKeysym,
1232                           jkeyExtended);
1233 
1234 
1235     }
1236     
1237     
1238     private boolean isDeadKey(long keysym){
1239         return XKeySymConstants.XK_dead_grave <= keysym && keysym <= XKeySymConstants.XK_dead_semivoiced_sound;
1240     }    
1241 
1242     /*
1243      * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
1244      * unreliable, since mapping changes can happen for a virtual desktop
1245      * switch or MacOS style shading that became quite popular under X as
1246      * well.  Yes, it probably should not be this way, as it violates
1247      * ICCCM, but reality is that quite a lot of window managers abuse
1248      * mapping state.
1249      */
1250     int getWMState() {
1251         if (stateChanged) {
1252             stateChanged = false;
1253             WindowPropertyGetter getter =
1254                 new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
1255                                          XWM.XA_WM_STATE);
1256             try {
1257                 int status = getter.execute();
1258                 if (status != XConstants.Success || getter.getData() == 0) {
1259                     return savedState = XUtilConstants.WithdrawnState;
1260                 }