Index: modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxLockingState.java =================================================================== --- modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxLockingState.java (revision 0) +++ modules/awt/src/main/java/unix/org/apache/harmony/awt/wtk/linux/LinuxLockingState.java (revision 0) @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Ilya Berezhniuk + * @version $Revision$ + */ +package org.apache.harmony.awt.wtk.linux; + +import java.awt.event.KeyEvent; + +import org.apache.harmony.awt.wtk.LockingState; + +/** + * The class providing implementation for locking keys operations. + */ +public class LinuxLockingState extends LockingState { + + @Override + public boolean isKanaImplemented() { + return false; + } + + @Override + public boolean getLockingState(int keyCode) { + return false; + } + + @Override + public void setLockingState(int keyCode, boolean on) { + } + +} Index: modules/awt/src/main/java/common/java/awt/Toolkit.java =================================================================== --- modules/awt/src/main/java/common/java/awt/Toolkit.java (revision 561952) +++ modules/awt/src/main/java/common/java/awt/Toolkit.java (working copy) @@ -28,6 +28,7 @@ import java.awt.event.AWTEventListener; import java.awt.event.AWTEventListenerProxy; import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.awt.im.InputMethodHighlight; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; @@ -95,6 +96,7 @@ import org.apache.harmony.awt.wtk.Synchronizer; import org.apache.harmony.awt.wtk.WTK; import org.apache.harmony.awt.wtk.WindowFactory; +import org.apache.harmony.awt.wtk.LockingState; public abstract class Toolkit { private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$ @@ -795,16 +797,30 @@ } } - public boolean getLockingKeyState(int a0) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException { - lockAWT(); - try { - } finally { - unlockAWT(); + public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException { + + if (GraphicsEnvironment.isHeadless()) { + throw new HeadlessException(); } - if (true) { - throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ + + if (keyCode != KeyEvent.VK_CAPS_LOCK && + keyCode != KeyEvent.VK_NUM_LOCK && + keyCode != KeyEvent.VK_SCROLL_LOCK && + keyCode != KeyEvent.VK_KANA_LOCK) { + throw new IllegalArgumentException(Messages.getString("awt.29A")); //$NON-NLS-1$ } - return true; + + LockingState ls = LockingState.getInstance(); + + if (ls == null) { + throw new UnsupportedOperationException(); + } + + if (keyCode == KeyEvent.VK_KANA_LOCK && !ls.isKanaImplemented()) { + throw new UnsupportedOperationException(); + } + + return ls.getLockingState(keyCode); } public int getMaximumCursorColors() throws HeadlessException { @@ -952,16 +968,30 @@ } } - public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException { - lockAWT(); - try { - } finally { - unlockAWT(); + public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException { + + if (GraphicsEnvironment.isHeadless()) { + throw new HeadlessException(); } - if (true) { - throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ + + if (keyCode != KeyEvent.VK_CAPS_LOCK && + keyCode != KeyEvent.VK_NUM_LOCK && + keyCode != KeyEvent.VK_SCROLL_LOCK && + keyCode != KeyEvent.VK_KANA_LOCK) { + throw new IllegalArgumentException(Messages.getString("awt.29A")); //$NON-NLS-1$ } - return; + + LockingState ls = LockingState.getInstance(); + + if (ls == null) { + throw new UnsupportedOperationException(); + } + + if (keyCode == KeyEvent.VK_KANA_LOCK && !ls.isKanaImplemented()) { + throw new UnsupportedOperationException(); + } + + ls.setLockingState(keyCode, on); } void onQueueEmpty() { @@ -1184,7 +1214,7 @@ } Object getEventMonitor(){ - return wtk.getNativeEventQueue().getEventMonitor(); + return wtk.getNativeEventQueue().getEventMonitor(); } /** Index: modules/awt/src/main/java/common/org/apache/harmony/awt/wtk/LockingState.java =================================================================== --- modules/awt/src/main/java/common/org/apache/harmony/awt/wtk/LockingState.java (revision 0) +++ modules/awt/src/main/java/common/org/apache/harmony/awt/wtk/LockingState.java (revision 0) @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Ilya Berezhniuk + * @version $Revision$ + */ +package org.apache.harmony.awt.wtk; + +import java.awt.event.KeyEvent; + +/** + * The base class for locking keys operations. + */ +public abstract class LockingState { + + private static LockingState instance = null; + + + /** + * Checks if KANA locking key is present in keyboard layout. + * @return true if KANA implemented, false otherwise + */ + public abstract boolean isKanaImplemented(); + + /** + * Obtains locking state for specified key + * @return locking state for locking keys, false otherwise + */ + public abstract boolean getLockingState(int keyKode); + + /** + * Sets locking state for specified key + */ + public abstract void setLockingState(int keyKode, boolean on); + + /** + * Returns instance for platform-dependent implementation + */ + public static synchronized LockingState getInstance() { + + if (instance != null) { + return instance; + } + + String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + String packageBase = "org.apache.harmony.awt.wtk"; //$NON-NLS-1$ + String win = "windows"; //$NON-NLS-1$ + String lin = "linux"; //$NON-NLS-1$ + String className; + + if (osName.startsWith(lin)) { + className = packageBase + "." + lin + ".LinuxLockingState"; //$NON-NLS-1$ //$NON-NLS-2$ + } else if (osName.startsWith(win)) { + className = packageBase + "." + win + ".WinLockingState"; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + return null; + } + + LockingState newLS = null; + + try { + newLS = (LockingState) Class.forName(className).newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + instance = newLS; + return instance; + } +} Index: modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties =================================================================== --- modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties (revision 561952) +++ modules/awt/src/main/java/common/org/apache/harmony/awt/internal/nls/messages.properties (working copy) @@ -488,6 +488,7 @@ awt.297=Invalid keyLocation awt.298=dataBuffer is too small awt.299=Font file can not be read +awt.29A=Keyboard doesn't have KANA key awt.err.00=file dialog {0} error! awt.err.01=error: {0} Index: modules/awt/src/main/java/windows/org/apache/harmony/awt/wtk/windows/WinLockingState.java =================================================================== --- modules/awt/src/main/java/windows/org/apache/harmony/awt/wtk/windows/WinLockingState.java (revision 0) +++ modules/awt/src/main/java/windows/org/apache/harmony/awt/wtk/windows/WinLockingState.java (revision 0) @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Ilya Berezhniuk + * @version $Revision$ + */ +package org.apache.harmony.awt.wtk.windows; + +import java.awt.event.KeyEvent; + +import org.apache.harmony.awt.wtk.LockingState; +import org.apache.harmony.awt.nativebridge.windows.Win32; + +/** + * The class providing implementation for locking keys operations. + */ +public class WinLockingState extends LockingState { + + /** + * To ensure that required libraries are loaded + */ + static final Win32 win32 = Win32.getInstance(); + + private static native void init(); + private static native void set_locking_state(int keyCode, boolean on); + private static native boolean obtain_locking_state(int keyCode); + private static native boolean is_kana_present(); + + /** + * constructor is invoked only once in LockingState.getInstance() + */ + public WinLockingState() { + init(); + } + + @Override + public boolean isKanaImplemented() { + return is_kana_present(); + } + + @Override + public boolean getLockingState(int keyCode) { + return obtain_locking_state(keyCode); + } + + @Override + public void setLockingState(int keyCode, boolean on) { + + set_locking_state(keyCode, on); + } + +} Index: modules/awt/src/main/native/win32wrapper/windows/org_apache_harmony_awt_wtk_windows_WinLockingState.cpp =================================================================== --- modules/awt/src/main/native/win32wrapper/windows/org_apache_harmony_awt_wtk_windows_WinLockingState.cpp (revision 0) +++ modules/awt/src/main/native/win32wrapper/windows/org_apache_harmony_awt_wtk_windows_WinLockingState.cpp (revision 0) @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Ilya Berezhniuk + * @version $Revision$ + */ + +#include +#include "nativelib_common.h" + + +static libHandler libUser32; + +// Java prototypes: +// private static native void init(); +// private static native void set_locking_state(int keyCode, boolean on); +// private static native boolean obtain_locking_state(int keyCode); +// private static native boolean is_kana_present(); + +// C prototypes declaration +extern "C" { +JNIEXPORT void JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_init(JNIEnv * env, jclass cls); +JNIEXPORT void JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_set_1locking_1state(JNIEnv *env, jobject self, jint keyCode, jboolean on); +JNIEXPORT jboolean JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_obtain_1locking_1state(JNIEnv *env, jobject self, jint keyCode); +JNIEXPORT jboolean JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_is_1kana_1present(JNIEnv *env, jobject self); +} + + +JNIEXPORT void JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_init(JNIEnv * env, jclass cls) +{ + LOAD_LIB(libUser32, "User32"); +} + +// Function types declaration +typedef void (__stdcall * pfun_keybd_event) (BYTE, BYTE, DWORD, ULONG_PTR); +typedef SHORT (__stdcall * pfun_GetKeyState)(int); +typedef UINT (__stdcall * pfun_MapVirtualKey) (UINT, UINT); + +// Pointers to API functions +pfun_keybd_event p_keybd_event = NULL; +pfun_GetKeyState p_GetKeyState = NULL; +pfun_MapVirtualKey p_MapVirtualKey = NULL; + +// Translate Java VK to Win32 VK +static inline int get_virt_locking_key(jint code) +{ + switch (code) + { + case 20:/*VK_CAPS_LOCK*/ + return VK_CAPITAL; + case 144:/*VK_NUM_LOCK*/ + return VK_NUMLOCK; + case 145:/*VK_SCROLL_LOCK*/ + return VK_SCROLL; + case 262:/*VK_KANA_LOCK*/ + return VK_KANA; + } + + return 0; +} + + +JNIEXPORT void JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_set_1locking_1state(JNIEnv *env, jobject self, jint keyCode, jboolean on) +{ + if (p_GetKeyState == NULL) + p_GetKeyState = (pfun_GetKeyState)FindFunction(libUser32, "GetKeyState"); + + if (p_keybd_event == NULL) + p_keybd_event = (pfun_keybd_event)FindFunction(libUser32, "keybd_event"); + + int vk = get_virt_locking_key(keyCode); + + if (vk == 0) + return; + + bool enabled = ((p_GetKeyState(vk) & 1) != 0); + + if ((enabled && on) || (!enabled && !on)) + return; + + // keybd_event function was superseded with SendInput + // But using SendInput makes library unusable on Windows versions < 0x0500 + // So using deprecated Win32 functions + p_keybd_event(vk, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); + p_keybd_event(vk, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); +} + +JNIEXPORT jboolean JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_obtain_1locking_1state(JNIEnv *env, jobject self, jint keyCode) +{ + if (p_GetKeyState == NULL) + p_GetKeyState = (pfun_GetKeyState)FindFunction(libUser32, "GetKeyState"); + + int vk = get_virt_locking_key(keyCode); + + if (vk == 0) + return JNI_FALSE; + + return (p_GetKeyState(vk) & 1) ? JNI_TRUE : JNI_FALSE; +} + +JNIEXPORT jboolean JNICALL Java_org_apache_harmony_awt_wtk_windows_WinLockingState_is_1kana_1present(JNIEnv *env, jobject self) +{ + if (p_MapVirtualKey == NULL) + p_MapVirtualKey = (pfun_MapVirtualKey)FindFunction(libUser32, "MapVirtualKey"); + + return (p_MapVirtualKey(VK_KANA, 0) != 0) ? JNI_TRUE : JNI_FALSE; +} Index: modules/awt/src/main/native/win32wrapper/windows/makefile =================================================================== --- modules/awt/src/main/native/win32wrapper/windows/makefile (revision 561952) +++ modules/awt/src/main/native/win32wrapper/windows/makefile (working copy) @@ -24,6 +24,7 @@ Callback.obj \ org_apache_harmony_awt_nativebridge_windows_Win32.obj \ org_apache_harmony_awt_nativebridge_windows_WGL.obj \ + org_apache_harmony_awt_wtk_windows_WinLockingState.obj \ WinDataTransfer.obj \ WinManagement.obj \ nativelib_common.obj