sikuli-driver team mailing list archive
-
sikuli-driver team
-
Mailing list archive
-
Message #04746
[Merge] lp:~vgod/sikuli/sandbox into lp:sikuli
Tsung-Hsiang Chang has proposed merging lp:~vgod/sikuli/sandbox into lp:sikuli.
Requested reviews:
Sikuli Drivers (sikuli-driver)
For more details, see:
https://code.launchpad.net/~vgod/sikuli/sandbox/+merge/72322
This branch implements a global hotkey manager for all platforms(Win/Mac/Linux), which was requested in Bug #635806.
--
https://code.launchpad.net/~vgod/sikuli/sandbox/+merge/72322
Your team Sikuli Drivers is requested to review the proposed merge of lp:~vgod/sikuli/sandbox into lp:sikuli.
=== modified file 'sikuli-ide/CMakeLists.txt' (properties changed: -x to +x)
--- sikuli-ide/CMakeLists.txt 2011-08-01 19:38:29 +0000
+++ sikuli-ide/CMakeLists.txt 2011-08-21 03:38:17 +0000
@@ -43,8 +43,6 @@
SET(SWING_LAYOUT_JAR "${COMMON_LIB_DIR}/swing-layout-1.0.1.jar")
SET(COMMONS_CLI_JAR "${COMMON_LIB_DIR}/commons-cli-1.2.jar")
SET(JSON_SIMPLE_JAR "${COMMON_LIB_DIR}/json_simple-1.1.jar")
-SET(JXGRABKEY_JAR "${COMMON_LIB_DIR}/jxgrabkey/lib/JXGrabKey.jar")
-SET(JINTELLITYPE_JAR "${COMMON_LIB_DIR}/jintellitype-1.3.6/jintellitype-1.3.6.jar")
SET(SWINGX_JAR "${COMMON_LIB_DIR}/swingx-core-1.6.2.jar")
SET(MAC_WIDGETS_JAR "${COMMON_LIB_DIR}/mac_widgets.jar")
SET(FORMS_JAR "${COMMON_LIB_DIR}/forms-1.2.1.jar")
@@ -89,7 +87,7 @@
SET(CLASSPATH ${CLASSPATH}${SEP}${JXGRABKEY_JAR})
ELSEIF(WIN32)
SET(MANIFEST ${RESOURCE_DIR}/META-INF/MANIFEST-win32.MF)
- SET(CLASSPATH ${CLASSPATH}${SEP}${JINTELLITYPE_JAR})
+ #SET(CLASSPATH ${CLASSPATH}${SEP}${JINTELLITYPE_JAR})
ELSE()
SET(MANIFEST ${RESOURCE_DIR}/META-INF/MANIFEST.MF)
ENDIF()
@@ -152,7 +150,7 @@
SET(FRAMEWORKS_IN_APP_DIR ${JAR_IN_APP_DIR}/libs)
SET(JAR_LIB_DIR ${JAR_DIR}/META-INF/lib)
- LIST(APPEND INCLUDE_JARS ${JINTELLITYPE_JAR})
+ #LIST(APPEND INCLUDE_JARS ${JINTELLITYPE_JAR})
FILE(GLOB sikuli_script_jnilibs "${BASE_DIR}/../sikuli-script/target/lib/*.dll")
SET(jnilibs ${sikuli_script_jnilibs})
ENDIF()
@@ -222,12 +220,6 @@
else()
SET(LIB_GRABKEY "${COMMON_LIB_DIR}/jxgrabkey/lib/libJXGrabKey-32.so")
endif()
- add_custom_target( ${JAR_FILE}.framework
- COMMAND ${CMAKE_COMMAND} -E make_directory ${JAR_LIB_DIR}
- COMMAND cp ${LIB_GRABKEY} ${JAR_LIB_DIR}/libJXGrabKey.so
- COMMENT "Packaging Frameworks in Jar"
- )
- add_dependencies( ${JAR_FILE} ${JAR_FILE}.framework )
add_custom_target( ${APP_FILE}.framework
COMMAND ${CMAKE_COMMAND} -E make_directory ${FRAMEWORKS_IN_APP_DIR}
@@ -393,7 +385,7 @@
add_dependencies( ${JAR_FILE}.prepare
${JAR_FILE}.resources
${JAR_FILE}.classes-in-jar
- ${JAR_FILE}.libs-in-jar
+ # ${JAR_FILE}.libs-in-jar
)
add_dependencies( ${JAR_FILE} ${JAR_FILE}.prepare )
@@ -403,7 +395,7 @@
ADD_SUBDIRECTORY( ${JAVA_SRC_DIR} )
-ADD_SUBDIRECTORY( ${NATIVE_SRC_DIR} )
+#ADD_SUBDIRECTORY( ${NATIVE_SRC_DIR} )
ADD_SUBDIRECTORY( ${JAVA_TEST_DIR} )
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/NativeLayer.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/NativeLayer.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/NativeLayer.java 2011-08-21 03:38:17 +0000
@@ -3,13 +3,10 @@
* Released under the MIT License.
*
*/
-package org.sikuli.ide;
-
-public interface NativeLayer {
- public void initApp();
- public void initIDE(SikuliIDE ide);
- public void installHotkey(int keyCode, int modifiers,
- SikuliIDE ide,
- String callbackMethod, String callbackType);
-}
-
+package org.sikuli.ide;
+
+public interface NativeLayer {
+ public void initApp();
+ public void initIDE(SikuliIDE ide);
+}
+
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForLinux.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForLinux.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForLinux.java 2011-08-21 03:38:17 +0000
@@ -3,91 +3,14 @@
* Released under the MIT License.
*
*/
-package org.sikuli.ide;
-
-import java.lang.reflect.*;
-import java.awt.Event;
-import java.awt.event.*;
-import java.util.*;
-import java.io.*;
-import com.wapmx.nativeutils.jniloader.NativeLoader;
-import jxgrabkey.HotkeyConflictException;
-import jxgrabkey.HotkeyListener;
-import jxgrabkey.JXGrabKey;
-
-
-import org.sikuli.script.Debug;
-
-public class NativeLayerForLinux implements NativeLayer {
- private Map<String, Integer> _callbackIdMap = new HashMap<String,Integer>();
- private Map<Integer, String> _idCallbackMap = new HashMap<Integer,String>();
-
- public void initApp(){}
-
- public void initIDE(SikuliIDE ide){
- try{
- NativeLoader.loadLibrary("JXGrabKey");
- }
- catch(IOException e){
- Debug.error("Can't load native lib JXGrabKey");
- e.printStackTrace();
- }
- }
-
- public void installHotkey(int key, int mod,
- final SikuliIDE ide,
- final String callbackMethod, String callbackType){
-
- String txtMod = KeyEvent.getKeyModifiersText(mod).toUpperCase();
- txtMod = txtMod.replace("META","WIN");
- txtMod = txtMod.replace("WINDOWS","WIN");
- String txtCode = KeyEvent.getKeyText(key).toUpperCase();
- Debug.info("install hotkey: " + txtMod + "+" + txtCode +
- " for " + callbackMethod);
-
- JXGrabKey grabKey = JXGrabKey.getInstance();
- int id;
- if( _callbackIdMap.containsKey(callbackMethod) ){
- id = _callbackIdMap.get(callbackMethod);
- grabKey.unregisterHotKey(id);
- }
- else{
- id = _callbackIdMap.size()+1;
- _callbackIdMap.put(callbackMethod, id);
- _idCallbackMap.put(id, callbackMethod);
- }
- try{
- //JXGrabKey.setDebugOutput(true);
- grabKey.registerAwtHotkey(id, mod, key);
- }catch(HotkeyConflictException e){
- Debug.error("Hot key conflicts");
- grabKey.cleanUp();
- return;
- }
-
- //Implement HotkeyListener
-
- if(_callbackIdMap.size()==1){
- HotkeyListener hotkeyListener = new jxgrabkey.HotkeyListener(){
- public void onHotkey(int id) {
- Debug.log(2, "onHotkey: " + id);
- String callbackFunc = _idCallbackMap.get(id);
- Class params[] = {};
- Object paramsObj[] = {};
- Class cls = ide.getClass();
- try{
- Method callback = cls.getDeclaredMethod(callbackFunc, params);
- callback.invoke(ide, paramsObj);
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- };
- JXGrabKey.getInstance().addHotkeyListener(hotkeyListener);
- }
-
- }
-}
-
-
+package org.sikuli.ide;
+
+public class NativeLayerForLinux implements NativeLayer {
+ public void initApp(){}
+
+ public void initIDE(SikuliIDE ide){
+ }
+
+}
+
+
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForMac.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForMac.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForMac.java 2011-08-21 03:38:17 +0000
@@ -3,216 +3,75 @@
* Released under the MIT License.
*
*/
-package org.sikuli.ide;
-
-import java.awt.event.KeyEvent;
-import java.awt.event.InputEvent;
-import javax.swing.*;
-import java.io.IOException;
-import java.util.prefs.*;
-import com.apple.eawt.*;
-import com.wapmx.nativeutils.jniloader.NativeLoader;
-
-import org.sikuli.script.Debug;
-
-// http://lists.apple.com/archives/mac-games-dev/2001/Sep/msg00113.html
-// full key table: http://www.mactech.com/articles/mactech/Vol.04/04.12/Macinkeys/
-// modifiers code: http://www.mactech.com/macintosh-c/chap02-1.html
-
-public class NativeLayerForMac implements NativeLayer {
- static final int CARBON_MASK_CMD = 0x0100;
- static final int CARBON_MASK_SHIFT = 0x0200;
- static final int CARBON_MASK_OPT = 0x0800;
- static final int CARBON_MASK_CTRL = 0x1000;
-
- static {
- try{
- NativeLoader.loadLibrary("NativeLayerForMac");
- }
- catch(IOException e){
- e.printStackTrace();
- }
- }
-
- public void initIDE(final SikuliIDE ide){
- }
-
- public void initApp(){
- Application app = Application.getApplication();
- app.addPreferencesMenuItem();
- app.setEnabledPreferencesMenu(true);
- app.addApplicationListener(
- new ApplicationAdapter() {
- public void handleOpenApplication(ApplicationEvent event){
- Debug.info("open application: Sikuli-IDE");
- System.setProperty("apple.laf.useScreenMenuBar", "true");
- System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Sikuli IDE");
- }
-
- public void handleOpenFile(ApplicationEvent evt) {
- final String fname = evt.getFilename();
- Debug.log(1, "opening " + fname);
- if(fname.endsWith(".skl")){
- SikuliIDE._runningSkl = true;
- Thread t = new Thread() {
- public void run() {
- try{
- SikuliIDE.runSkl(fname, null);
- }
- catch(IOException e){
- e.printStackTrace();
- }
- }
- };
- t.setDaemon(false);
- t.start();
- }
- else if(fname.endsWith(".sikuli")){
- SikuliIDE ide = SikuliIDE.getInstance(null);
- ide.loadFile(fname);
- }
- }
-
- public void handlePreferences(ApplicationEvent evt){
- Debug.log(1, "opening preferences setting");
- SikuliIDE ide = SikuliIDE.getInstance();
- ide.showPreferencesWindow();
- }
-
- public void handleQuit(ApplicationEvent event){
- SikuliIDE.getInstance().quit();
- }
- }
- );
- }
-
- public void installHotkey(int key, int mod,
- SikuliIDE ide,
- String callbackMethod, String callbackType){
- int ckey = convertToCarbonKey(key);
- int cmod = convertToCarbonModifiers(mod);
- Debug.log(2, "register hotkey Java:" + key + "(" +mod+
- ") Carbon: " + ckey + "(" + cmod + ")");
- installGlobalHotkey(ckey, cmod, ide,
- callbackMethod, callbackType);
- }
-
- private native void installGlobalHotkey(int keyCode, int modifiers,
- SikuliIDE ide,
- String callbackMethod, String callbackType);
-
- private int convertToCarbonModifiers(int mod){
- int cmod = 0;
- if((mod&InputEvent.SHIFT_MASK) != 0) cmod |= CARBON_MASK_SHIFT;
- if((mod&InputEvent.META_MASK) != 0) cmod |= CARBON_MASK_CMD;
- if((mod&InputEvent.ALT_MASK) != 0) cmod |= CARBON_MASK_OPT;
- if((mod&InputEvent.CTRL_MASK) != 0) cmod |= CARBON_MASK_CTRL;
- return cmod;
- }
-
- private int convertToCarbonKey(int keycode){
- switch(keycode){
- case KeyEvent.VK_BACK_SPACE: return 0x33;
- case KeyEvent.VK_TAB: return 0x30;
- case KeyEvent.VK_CLEAR: return 0x47;
- case KeyEvent.VK_ENTER: return 0x24;
- case KeyEvent.VK_SHIFT: return 0xF0;
- case KeyEvent.VK_CONTROL: return 0xF1;
- case KeyEvent.VK_META: return 0xF2;
- case KeyEvent.VK_PAUSE: return 0x71; // = F15
- case KeyEvent.VK_ESCAPE: return 0x35;
- case KeyEvent.VK_SPACE: return 0x31;
- case KeyEvent.VK_OPEN_BRACKET: return 0x21;
- case KeyEvent.VK_BACK_SLASH: return 0x2A;
- case KeyEvent.VK_CLOSE_BRACKET: return 0x1E;
- case KeyEvent.VK_SLASH: return 0x2C;
- case KeyEvent.VK_PERIOD: return 0x2F;
- case KeyEvent.VK_COMMA: return 0x2B;
- case KeyEvent.VK_SEMICOLON: return 0x29;
- case KeyEvent.VK_END: return 0x77;
- case KeyEvent.VK_HOME: return 0x73;
- case KeyEvent.VK_LEFT: return 0x7B;
- case KeyEvent.VK_UP: return 0x7E;
- case KeyEvent.VK_RIGHT: return 0x7C;
- case KeyEvent.VK_DOWN: return 0x7D;
- case KeyEvent.VK_PRINTSCREEN: return 0x69; // F13
- case KeyEvent.VK_INSERT: return 0x72; // help
- case KeyEvent.VK_DELETE: return 0x75;
- case KeyEvent.VK_HELP: return 0x72;
- case KeyEvent.VK_0: return 0x1D;
- case KeyEvent.VK_1: return 0x12;
- case KeyEvent.VK_2: return 0x13;
- case KeyEvent.VK_3: return 0x14;
- case KeyEvent.VK_4: return 0x15;
- case KeyEvent.VK_5: return 0x17;
- case KeyEvent.VK_6: return 0x16;
- case KeyEvent.VK_7: return 0x1A;
- case KeyEvent.VK_8: return 0x1C;
- case KeyEvent.VK_9: return 0x19;
- case KeyEvent.VK_MINUS: return 0x1B;
- case KeyEvent.VK_EQUALS: return 0x18;
- case KeyEvent.VK_A: return 0x00;
- case KeyEvent.VK_B: return 0x0B;
- case KeyEvent.VK_C: return 0x08;
- case KeyEvent.VK_D: return 0x02;
- case KeyEvent.VK_E: return 0x0E;
- case KeyEvent.VK_F: return 0x03;
- case KeyEvent.VK_G: return 0x05;
- case KeyEvent.VK_H: return 0x04;
- case KeyEvent.VK_I: return 0x22;
- case KeyEvent.VK_J: return 0x26;
- case KeyEvent.VK_K: return 0x28;
- case KeyEvent.VK_L: return 0x25;
- case KeyEvent.VK_M: return 0x2E;
- case KeyEvent.VK_N: return 0x2D;
- case KeyEvent.VK_O: return 0x1F;
- case KeyEvent.VK_P: return 0x23;
- case KeyEvent.VK_Q: return 0x0C;
- case KeyEvent.VK_R: return 0x0F;
- case KeyEvent.VK_S: return 0x01;
- case KeyEvent.VK_T: return 0x11;
- case KeyEvent.VK_U: return 0x20;
- case KeyEvent.VK_V: return 0x09;
- case KeyEvent.VK_W: return 0x0D;
- case KeyEvent.VK_X: return 0x07;
- case KeyEvent.VK_Y: return 0x10;
- case KeyEvent.VK_Z: return 0x06;
- case KeyEvent.VK_NUMPAD0: return 0x52;
- case KeyEvent.VK_NUMPAD1: return 0x53;
- case KeyEvent.VK_NUMPAD2: return 0x54;
- case KeyEvent.VK_NUMPAD3: return 0x55;
- case KeyEvent.VK_NUMPAD4: return 0x56;
- case KeyEvent.VK_NUMPAD5: return 0x57;
- case KeyEvent.VK_NUMPAD6: return 0x58;
- case KeyEvent.VK_NUMPAD7: return 0x59;
- case KeyEvent.VK_NUMPAD8: return 0x5B;
- case KeyEvent.VK_NUMPAD9: return 0x5C;
- case KeyEvent.VK_MULTIPLY: return 0x43;
- case KeyEvent.VK_ADD: return 0x45;
- case KeyEvent.VK_SEPARATOR: return 0xFF; // not supported with Button or GetKeys
- case KeyEvent.VK_SUBTRACT: return 0x4E;
- case KeyEvent.VK_DECIMAL: return 0x41;
- case KeyEvent.VK_DIVIDE: return 0x4B;
- case KeyEvent.VK_F1: return 0x7A;
- case KeyEvent.VK_F2: return 0x7B;
- case KeyEvent.VK_F3: return 0x63;
- case KeyEvent.VK_F4: return 0x76;
- case KeyEvent.VK_F5: return 0x60;
- case KeyEvent.VK_F6: return 0x61;
- case KeyEvent.VK_F7: return 0x62;
- case KeyEvent.VK_F8: return 0x64;
- case KeyEvent.VK_F9: return 0x65;
- case KeyEvent.VK_F10: return 0x6D;
- case KeyEvent.VK_F11: return 0x67;
- case KeyEvent.VK_F12: return 0x6F;
- case KeyEvent.VK_F13: return 0x69;
- case KeyEvent.VK_F14: return 0x6B;
- case KeyEvent.VK_F15: return 0x71;
- case KeyEvent.VK_NUM_LOCK: return 0x47;
- default: return 0xFF;
- }
-
- }
-}
-
-
+package org.sikuli.ide;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.InputEvent;
+import javax.swing.*;
+import java.io.IOException;
+import java.util.prefs.*;
+import com.apple.eawt.*;
+
+import org.sikuli.script.Debug;
+
+// http://lists.apple.com/archives/mac-games-dev/2001/Sep/msg00113.html
+// full key table: http://www.mactech.com/articles/mactech/Vol.04/04.12/Macinkeys/
+// modifiers code: http://www.mactech.com/macintosh-c/chap02-1.html
+
+public class NativeLayerForMac implements NativeLayer {
+
+ public void initIDE(final SikuliIDE ide){
+ }
+
+ public void initApp(){
+ Application app = Application.getApplication();
+ app.addPreferencesMenuItem();
+ app.setEnabledPreferencesMenu(true);
+ app.addApplicationListener(
+ new ApplicationAdapter() {
+ public void handleOpenApplication(ApplicationEvent event){
+ Debug.info("open application: Sikuli-IDE");
+ System.setProperty("apple.laf.useScreenMenuBar", "true");
+ System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Sikuli IDE");
+ }
+
+ public void handleOpenFile(ApplicationEvent evt) {
+ final String fname = evt.getFilename();
+ Debug.log(1, "opening " + fname);
+ if(fname.endsWith(".skl")){
+ SikuliIDE._runningSkl = true;
+ Thread t = new Thread() {
+ public void run() {
+ try{
+ SikuliIDE.runSkl(fname, null);
+ }
+ catch(IOException e){
+ e.printStackTrace();
+ }
+ }
+ };
+ t.setDaemon(false);
+ t.start();
+ }
+ else if(fname.endsWith(".sikuli")){
+ SikuliIDE ide = SikuliIDE.getInstance(null);
+ ide.loadFile(fname);
+ }
+ }
+
+ public void handlePreferences(ApplicationEvent evt){
+ Debug.log(1, "opening preferences setting");
+ SikuliIDE ide = SikuliIDE.getInstance();
+ ide.showPreferencesWindow();
+ }
+
+ public void handleQuit(ApplicationEvent event){
+ SikuliIDE.getInstance().quit();
+ }
+ }
+ );
+ }
+
+}
+
+
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForWindows.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForWindows.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/NativeLayerForWindows.java 2011-08-21 03:38:17 +0000
@@ -3,71 +3,15 @@
* Released under the MIT License.
*
*/
-package org.sikuli.ide;
-
-import java.lang.reflect.*;
-import java.awt.Event;
-import java.awt.event.*;
-import java.util.*;
-import com.melloware.jintellitype.HotkeyListener;
-import com.melloware.jintellitype.IntellitypeListener;
-import com.melloware.jintellitype.JIntellitype;
-
-import org.sikuli.script.Debug;
-
-public class NativeLayerForWindows implements NativeLayer {
- private Map<String, Integer> _callbackIdMap = new HashMap<String,Integer>();
- private Map<Integer, String> _idCallbackMap = new HashMap<Integer,String>();
-
- public void initApp(){
- }
- public void initIDE(SikuliIDE ide){
- }
-
- public void installHotkey(int key, int mod,
- final SikuliIDE ide,
- final String callbackMethod, String callbackType){
- JIntellitype itype = JIntellitype.getInstance();
- String txtMod = KeyEvent.getKeyModifiersText(mod).toUpperCase();
- txtMod = txtMod.replace("META","WIN");
- txtMod = txtMod.replace("WINDOWS","WIN");
- String txtCode = KeyEvent.getKeyText(key).toUpperCase();
- Debug.info("install hotkey: " + txtMod + "+" + txtCode +
- " for " + callbackMethod);
-
- int id;
- if( _callbackIdMap.containsKey(callbackMethod) ){
- id = _callbackIdMap.get(callbackMethod);
- itype.unregisterHotKey(id);
- }
- else{
- id = _callbackIdMap.size()+1;
- _callbackIdMap.put(callbackMethod, id);
- _idCallbackMap.put(id, callbackMethod);
- }
-
- //itype.registerHotKey(id, txtMod + "+" + txtCode);
- itype.registerSwingHotKey(id, mod, key);
- //Debug.log(1, "[WIN] " + callbackMethod + " " + id);
- if(_callbackIdMap.size()==1){
- itype.addHotKeyListener(new HotkeyListener(){
- public void onHotKey(int id){
- Debug.log(2, "Hotkey pressed");
- String callbackFunc = _idCallbackMap.get(id);
- Class params[] = {};
- Object paramsObj[] = {};
- Class cls = ide.getClass();
- try{
- Method callback = cls.getDeclaredMethod(callbackFunc, params);
- callback.invoke(ide, paramsObj);
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- });
- }
- }
-}
-
-
+package org.sikuli.ide;
+
+
+public class NativeLayerForWindows implements NativeLayer {
+ public void initApp(){
+ }
+ public void initIDE(SikuliIDE ide){
+ }
+
+}
+
+
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/PreferencesWin.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/PreferencesWin.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/PreferencesWin.java 2011-08-21 03:38:17 +0000
@@ -93,7 +93,7 @@
_radOCR.isSelected()?UserPreferences.AUTO_NAMING_OCR:
UserPreferences.AUTO_NAMING_OFF);
if(_old_cap_hkey != _cap_hkey || _old_cap_mod != _cap_mod){
- //FIXME: remove the old hotkey
+ ide.removeCaptureHotkey(_old_cap_hkey, _old_cap_mod);
ide.installCaptureHotkey(_cap_hkey, _cap_mod);
}
pref.setCheckUpdate(_chkAutoUpdate.isSelected());
=== modified file 'sikuli-ide/src/main/java/org/sikuli/ide/SikuliIDE.java'
--- sikuli-ide/src/main/java/org/sikuli/ide/SikuliIDE.java 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/java/org/sikuli/ide/SikuliIDE.java 2011-08-21 03:38:17 +0000
@@ -39,6 +39,9 @@
import org.sikuli.script.ScreenImage;
import org.sikuli.script.Observer;
import org.sikuli.script.Subject;
+import org.sikuli.script.Env;
+import org.sikuli.script.HotkeyListener;
+import org.sikuli.script.HotkeyEvent;
import org.apache.commons.cli.CommandLine;
@@ -744,9 +747,16 @@
public boolean isInited(){ return _inited; }
+ public void removeCaptureHotkey(int key, int mod){
+ Env.removeHotkey(key, mod);
+ }
+
public void installCaptureHotkey(int key, int mod){
- _native.installHotkey(key, mod, this,
- "onQuickCapture", "(Ljava/lang/String;)V");
+ Env.addHotkey(key, mod, new HotkeyListener(){
+ public void hotkeyPressed(HotkeyEvent e){
+ onQuickCapture();
+ }
+ });
}
private void initHotkeys(){
@@ -756,8 +766,11 @@
installCaptureHotkey(key, mod);
key = pref.getStopHotkey();
mod = pref.getStopHotkeyModifiers();
- _native.installHotkey(key, mod, this,
- "onStopRunning", "()V");
+ Env.addHotkey(key, mod, new HotkeyListener(){
+ public void hotkeyPressed(HotkeyEvent e){
+ onStopRunning();
+ }
+ });
}
static private void initNativeLayer(){
=== removed file 'sikuli-ide/src/main/native/CMakeLists.txt'
--- sikuli-ide/src/main/native/CMakeLists.txt 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/native/CMakeLists.txt 1970-01-01 00:00:00 +0000
@@ -1,65 +0,0 @@
-# Copyright 2010-2011, Sikuli.org
-# Released under the MIT License.
-ENABLE_LANGUAGE(CXX)
-
-SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../../cmake_modules/")
-INCLUDE("${CMAKE_MODULE_PATH}/common.cmake")
-
-FIND_PROGRAM ( JAVA_JAVA_H javah PATHS ${JAVA_BIN_PATH} )
-SET(JNI_HEADERS
- org_sikuli_ide_NativeLayerForMac.h
-)
-
-SET(LIBRARY_OUTPUT_PATH ${BINARY_LIB_DIR})
-
-FIND_PACKAGE(JNI REQUIRED)
-IF(APPLE)
- FIND_LIBRARY(CARBON_LIBRARY Carbon)
- FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
- SET(EXTRA_LIBS ${CARBON_LIBRARY} ${COREFOUNDATION_LIBRARY})
-ENDIF(APPLE)
-
-INCLUDE_DIRECTORIES(${JNI_INCLUDE_DIRS})
-
-
-IF(APPLE)
- SET(BUILD_TARGETS
- NativeLayerForMac
- )
-
- ADD_LIBRARY(NativeLayerForMac SHARED
- NativeLayerForMac.cc
- org_sikuli_ide_NativeLayerForMac.h
- )
-
-ENDIF(APPLE)
-
-foreach(JNI_HEADER ${JNI_HEADERS})
- STRING(REGEX REPLACE "_" "." JNI_CLASS ${JNI_HEADER})
- STRING(REGEX REPLACE "\\.h$" "" JNI_CLASS ${JNI_CLASS})
- STRING(REGEX REPLACE "\\." "/" JNI_JAVA_SOURCE ${JNI_CLASS})
- SET(JNI_JAVA_SOURCE "${JNI_JAVA_SOURCE}.java")
- ADD_CUSTOM_COMMAND(
- OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${JNI_HEADER}
- COMMAND ${JAVA_JAVA_H} -d ${CMAKE_CURRENT_SOURCE_DIR}
- -classpath ${BINARY_CLASS_DIR} ${JNI_CLASS}
- DEPENDS ${JAVA_SRC_DIR}/${JNI_JAVA_SOURCE}
- )
-endforeach(JNI_HEADER ${JNI_HEADERS})
-
-
-foreach(BUILD_TARGET ${BUILD_TARGETS})
- TARGET_LINK_LIBRARIES(${BUILD_TARGET} ${EXTRA_LIBS})
- if(APPLE)
- set_target_properties(${BUILD_TARGET} PROPERTIES SUFFIX ".jnilib")
- endif(APPLE)
-endforeach(BUILD_TARGET ${BUILD_TARGETS})
-
-add_custom_target(${JAR_FILE}.libs-in-jar
- COMMAND ${CMAKE_COMMAND} -E make_directory ${JAR_DIR}/META-INF
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${BINARY_LIB_DIR} ${JAR_DIR}/META-INF/lib
-)
-
-IF(EXISTS ${BUILD_TARGETS})
- add_dependencies(${JAR_FILE}.libs-in-jar ${BUILD_TARGETS})
-ENDIF()
=== removed file 'sikuli-ide/src/main/native/NativeLayerForMac.cc'
--- sikuli-ide/src/main/native/NativeLayerForMac.cc 2011-05-05 15:07:14 +0000
+++ sikuli-ide/src/main/native/NativeLayerForMac.cc 1970-01-01 00:00:00 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright 2010-2011, Sikuli.org
- * Released under the MIT License.
- *
- */
-#include "org_sikuli_ide_NativeLayerForMac.h"
-
-#include <Carbon/Carbon.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-#include<iostream>
-#include<map>
-
-using namespace std;
-
-struct CallbackData {
- JavaVM *vm;
- int hotkey, mods;
- const char *func, *func_t;
- jobject cls;
-
- CallbackData(JavaVM *vm_, int hotkey_, int mods_, const char* func_,
- const char* func_t_, jobject cls_){
- vm = vm_;
- hotkey = hotkey_;
- mods = mods_;
- func = func_;
- func_t = func_t_;
- cls = cls_;
- }
-};
-
-
-void callJavaMethod(JavaVM *jvm, jobject obj,
- const char* func, const char* func_t){
- JNIEnv *env;
- jvm->GetEnv((void**)&env, JNI_VERSION_1_4);
- jvm->AttachCurrentThread((void **)&env, NULL);
- jclass cls = env->GetObjectClass(obj);
- jmethodID mid = env->GetMethodID(cls, func, func_t);
- if( mid == NULL ){
- cerr << "Callback method " << func << " not found." << endl;
- return;
- }
- env->CallVoidMethod(obj, mid);
-}
-
-OSStatus shortcutHandler( EventHandlerCallRef inCaller, EventRef inEvent,
- void* inIdDataMap )
-{
- EventHotKeyID hkId;
- GetEventParameter(inEvent, kEventParamDirectObject, typeEventHotKeyID, NULL,
- sizeof(hkId), NULL, &hkId);
- map<int,CallbackData*>
- *idDataMap = reinterpret_cast<map<int,CallbackData*>*>(inIdDataMap);
- CallbackData *data = (*idDataMap)[hkId.id];
- int hotkey = data->hotkey;
- cout << "[JNI] shortcut pressed. " << hotkey << endl;
- callJavaMethod(data->vm, data->cls, data->func, data->func_t);
- return noErr;
-}
-
-void installShortcutHandler( CallbackData *data ){
- static map<string, int> callbackIdMap;
- static map<int, CallbackData*> idDataMap;
- static map<string, EventHotKeyRef> callbackRefMap;
- EventTypeSpec shortcutEvents[] = {
- { kEventClassKeyboard, kEventHotKeyPressed },
- };
- EventHotKeyRef myHotKeyRef;
- EventHotKeyID myHotKeyID;
- myHotKeyID.signature='htk1';
- map<string, int>::iterator it;
- if( (it=callbackIdMap.find(data->func)) == callbackIdMap.end() ){
- myHotKeyID.id = callbackIdMap.size()+1;
- callbackIdMap[data->func] = myHotKeyID.id;
- cout << "[JNI] " << data->func << " id: " << myHotKeyID.id << endl;
- }
- else{
- myHotKeyID.id = it->second;
- myHotKeyRef = callbackRefMap[data->func];
- UnregisterEventHotKey(myHotKeyRef);
- }
- idDataMap[myHotKeyID.id] = data;
-
- if(callbackIdMap.size() == 1){
- InstallApplicationEventHandler(&shortcutHandler, 1, shortcutEvents,
- &idDataMap, NULL);
- }
-
- OSStatus err = RegisterEventHotKey(data->hotkey, data->mods,
- myHotKeyID, GetApplicationEventTarget(), 0,
- &myHotKeyRef);
-
- if(err)
- cerr << "Error registering shortcut handler.. " << err << endl;
- else
- callbackRefMap[data->func] = myHotKeyRef;
-}
-
-JNIEXPORT void JNICALL Java_org_sikuli_ide_NativeLayerForMac_installGlobalHotkey (JNIEnv *env, jobject jobj, jint hotkey, jint modifiers, jobject jIde,
- jstring jCallbackName, jstring jCallbackType){
-
- cout << "[JNI] install global hotkey: " << hotkey << endl;
- const char *cName = env->GetStringUTFChars(jCallbackName, NULL);
- const char *cType = env->GetStringUTFChars(jCallbackType, NULL);
- JavaVM* vm = NULL;
- env->GetJavaVM(&vm);
- jobject ide = env->NewGlobalRef(jIde);
- env->DeleteLocalRef(jIde);
- CallbackData *data = new CallbackData(vm, hotkey, modifiers,
- cName, cType, ide);
- installShortcutHandler(data);
-}
=== removed file 'sikuli-ide/src/main/native/org_sikuli_ide_NativeLayerForMac.h'
--- sikuli-ide/src/main/native/org_sikuli_ide_NativeLayerForMac.h 2011-05-30 19:54:10 +0000
+++ sikuli-ide/src/main/native/org_sikuli_ide_NativeLayerForMac.h 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_sikuli_ide_NativeLayerForMac */
-
-#ifndef _Included_org_sikuli_ide_NativeLayerForMac
-#define _Included_org_sikuli_ide_NativeLayerForMac
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef org_sikuli_ide_NativeLayerForMac_CARBON_MASK_CMD
-#define org_sikuli_ide_NativeLayerForMac_CARBON_MASK_CMD 256L
-#undef org_sikuli_ide_NativeLayerForMac_CARBON_MASK_SHIFT
-#define org_sikuli_ide_NativeLayerForMac_CARBON_MASK_SHIFT 512L
-#undef org_sikuli_ide_NativeLayerForMac_CARBON_MASK_OPT
-#define org_sikuli_ide_NativeLayerForMac_CARBON_MASK_OPT 2048L
-#undef org_sikuli_ide_NativeLayerForMac_CARBON_MASK_CTRL
-#define org_sikuli_ide_NativeLayerForMac_CARBON_MASK_CTRL 4096L
-/*
- * Class: org_sikuli_ide_NativeLayerForMac
- * Method: installGlobalHotkey
- * Signature: (IILorg/sikuli/ide/SikuliIDE;Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_sikuli_ide_NativeLayerForMac_installGlobalHotkey
- (JNIEnv *, jobject, jint, jint, jobject, jstring, jstring);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
=== modified file 'sikuli-script/CMakeLists.txt'
--- sikuli-script/CMakeLists.txt 2011-08-03 19:47:33 +0000
+++ sikuli-script/CMakeLists.txt 2011-08-21 03:38:17 +0000
@@ -36,13 +36,20 @@
SET(CMAKE_SWIG_OUTDIR ${CMAKE_BINARY_DIR}/${NATIVE_PACKAGE_DIR})
SET(COMMON_LIB_DIR "${BASE_DIR}/../lib")
+
+# dependent libs
+SET(JXGRABKEY_JAR "${COMMON_LIB_DIR}/jxgrabkey/lib/JXGrabKey.jar")
+SET(JINTELLITYPE_JAR "${COMMON_LIB_DIR}/jintellitype-1.3.6/jintellitype-1.3.6.jar")
+
#SET(INCLUDE_LIB_DIR "${BASE_DIR}/lib")
SET(INCLUDE_LIB_DIR "${COMMON_LIB_DIR}/mx-native-loader-1.2/target/classes")
+
SET(BINARY_DIR "${BASE_DIR}/target")
SET(BINARY_CLASS_DIR "${BINARY_DIR}/classes")
SET(TEST_CLASS_DIR "${CMAKE_BINARY_DIR}/test")
SET(BINARY_LIB_DIR "${BINARY_DIR}/lib")
SET(JAR_DIR "${BINARY_DIR}/jar")
+SET(JAR_LIB_DIR ${JAR_DIR}/META-INF/lib)
SET(JUNIT_JAR "${COMMON_LIB_DIR}/junit-4.8.2.jar")
SET(MOCKITO_JAR "${COMMON_LIB_DIR}/mockito-all-1.8.5.jar")
@@ -53,6 +60,13 @@
${INCLUDE_LIB_DIR}${SEP}${JYTHON_JAR}${SEP}.
)
+IF(LINUX)
+ SET(CLASSPATH ${CLASSPATH}${SEP}${JXGRABKEY_JAR})
+ELSEIF(WIN32)
+ SET(CLASSPATH ${CLASSPATH}${SEP}${JINTELLITYPE_JAR})
+ENDIF()
+
+
SET(TEST_CLASSPATH
${CLASSPATH}${SEP}${JUNIT_JAR}${SEP}${BINARY_CLASS_DIR}${SEP}${MOCKITO_JAR}
)
@@ -83,6 +97,7 @@
)
ENDIF()
+
SET(LIB_IN_JAR_DIR "${JAR_DIR}/Lib")
add_custom_target( ${JAR_FILE}.python-src-in-jar
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_IN_JAR_DIR}
@@ -132,6 +147,12 @@
COMMENT "Update version number to ${VERSION}"
)
+add_custom_target(${JAR_FILE}.libs-in-jar
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${JAR_DIR}/META-INF
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${BINARY_LIB_DIR} ${JAR_LIB_DIR}
+)
+
+
# Dependencies
add_dependencies(${JAR_FILE}
@@ -144,6 +165,54 @@
${JAR_FILE}.jython-libs-in-jar
)
+IF(WIN32)
+ IF(NOT EXISTS ${JAR_DIR}/com/melloware/jintellitype)
+ add_custom_target( ${JAR_FILE}.jintellitype-in-jar
+ COMMAND ${CMAKE_COMMAND} -E chdir ${JAR_DIR} ${JAVA_ARCHIVE} xf ${JINTELLITYPE_JAR}
+ COMMENT "Merging Jintellitype's JAR"
+ )
+ ENDIF()
+ add_dependencies(${JAR_FILE}
+ ${JAR_FILE}.jintellitype-in-jar
+ )
+
+ SET(LIB_GRABKEY "${COMMON_LIB_DIR}/jintellitype-1.3.6/JIntellitype.dll")
+ add_custom_target( ${JAR_FILE}.hotkey-lib
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIB_GRABKEY} ${BINARY_LIB_DIR}/
+ COMMENT "Packaging JIntellitype in Jar"
+ )
+
+ENDIF(WIN32)
+
+IF(LINUX)
+ IF(NOT EXISTS ${JAR_DIR}/jxgrabkey)
+ add_custom_target( ${JAR_FILE}.jxgrabkey-in-jar
+ COMMAND ${CMAKE_COMMAND} -E chdir ${JAR_DIR} ${JAVA_ARCHIVE} xf ${JXGRABKEY_JAR}
+ COMMENT "Merging JXGrabKey's JAR"
+ )
+ ENDIF()
+
+ add_dependencies(${JAR_FILE}
+ ${JAR_FILE}.jxgrabkey-in-jar
+ )
+ENDIF(LINUX)
+
+IF(LINUX)
+ EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE SYSTEM_ARCH)
+ if(SYSTEM_ARCH MATCHES "x86_64")
+ SET(LIB_GRABKEY "${COMMON_LIB_DIR}/jxgrabkey/lib/libJXGrabKey-64.so")
+ else()
+ SET(LIB_GRABKEY "${COMMON_LIB_DIR}/jxgrabkey/lib/libJXGrabKey-32.so")
+ endif()
+ add_custom_target( ${JAR_FILE}.hotkey-lib
+ COMMAND cp ${LIB_GRABKEY} ${BINARY_LIB_DIR}/libJXGrabKey.so
+ COMMENT "Packaging JXGrabKey in Jar"
+ )
+ENDIF(LINUX)
+add_dependencies( ${JAR_FILE} ${JAR_FILE}.hotkey-lib )
+add_dependencies( ${JAR_FILE}.libs-in-jar ${JAR_FILE}.hotkey-lib )
+
+
ADD_SUBDIRECTORY(${NATIVE_SRC_DIR})
ADD_SUBDIRECTORY(${JAVA_SRC_DIR})
ADD_SUBDIRECTORY(${JAVA_TEST_DIR})
=== modified file 'sikuli-script/hudson-test.xml'
--- sikuli-script/hudson-test.xml 2011-05-30 18:13:11 +0000
+++ sikuli-script/hudson-test.xml 2011-08-21 03:38:17 +0000
@@ -15,6 +15,7 @@
<pathelement location="target/sikuli-script.jar" />
</path>
<path id="classpath.test">
+ <pathelement location="../lib/jintellitype-1.3.6/jintellitype-1.3.6.jar" />
<pathelement location="../lib/junit-4.8.2.jar" />
<pathelement location="../lib/mockito-all-1.8.5.jar" />
<pathelement location="${tst-dir}" />
=== modified file 'sikuli-script/src/main/java/CMakeLists.txt'
--- sikuli-script/src/main/java/CMakeLists.txt 2011-06-28 22:11:24 +0000
+++ sikuli-script/src/main/java/CMakeLists.txt 2011-08-21 03:38:17 +0000
@@ -1,11 +1,20 @@
# Copyright 2010-2011, Sikuli.org
# Released under the MIT License.
IF(APPLE)
- SET(OS_EXTRA_SOURCE_FILES org/sikuli/script/MacUtil.java)
+ SET(OS_EXTRA_SOURCE_FILES
+ org/sikuli/script/MacUtil.java
+ org/sikuli/script/internal/hotkey/MacHotkeyManager.java
+ )
ELSEIF(LINUX)
- SET(OS_EXTRA_SOURCE_FILES org/sikuli/script/LinuxUtil.java)
+ SET(OS_EXTRA_SOURCE_FILES
+ org/sikuli/script/LinuxUtil.java
+ org/sikuli/script/internal/hotkey/LinuxHotkeyManager.java
+ )
ELSEIF(WIN32)
- SET(OS_EXTRA_SOURCE_FILES org/sikuli/script/Win32Util.java)
+ SET(OS_EXTRA_SOURCE_FILES
+ org/sikuli/script/Win32Util.java
+ org/sikuli/script/internal/hotkey/WindowsHotkeyManager.java
+ )
ENDIF()
@@ -56,6 +65,7 @@
org/sikuli/script/KeyModifier.java
org/sikuli/script/Button.java
org/sikuli/script/Constants.java
+ org/sikuli/script/internal/hotkey/HotkeyManager.java
)
add_custom_target( ${PROJECT_NAME}.classes
=== modified file 'sikuli-script/src/main/java/org/sikuli/script/DesktopRobot.java'
--- sikuli-script/src/main/java/org/sikuli/script/DesktopRobot.java 2011-07-28 05:18:05 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/DesktopRobot.java 2011-08-21 03:38:17 +0000
@@ -115,159 +115,7 @@
}
public void typeChar(char character, KeyMode mode) {
- switch (character) {
- case 'a': doType(mode,KeyEvent.VK_A); break;
- case 'b': doType(mode,KeyEvent.VK_B); break;
- case 'c': doType(mode,KeyEvent.VK_C); break;
- case 'd': doType(mode,KeyEvent.VK_D); break;
- case 'e': doType(mode,KeyEvent.VK_E); break;
- case 'f': doType(mode,KeyEvent.VK_F); break;
- case 'g': doType(mode,KeyEvent.VK_G); break;
- case 'h': doType(mode,KeyEvent.VK_H); break;
- case 'i': doType(mode,KeyEvent.VK_I); break;
- case 'j': doType(mode,KeyEvent.VK_J); break;
- case 'k': doType(mode,KeyEvent.VK_K); break;
- case 'l': doType(mode,KeyEvent.VK_L); break;
- case 'm': doType(mode,KeyEvent.VK_M); break;
- case 'n': doType(mode,KeyEvent.VK_N); break;
- case 'o': doType(mode,KeyEvent.VK_O); break;
- case 'p': doType(mode,KeyEvent.VK_P); break;
- case 'q': doType(mode,KeyEvent.VK_Q); break;
- case 'r': doType(mode,KeyEvent.VK_R); break;
- case 's': doType(mode,KeyEvent.VK_S); break;
- case 't': doType(mode,KeyEvent.VK_T); break;
- case 'u': doType(mode,KeyEvent.VK_U); break;
- case 'v': doType(mode,KeyEvent.VK_V); break;
- case 'w': doType(mode,KeyEvent.VK_W); break;
- case 'x': doType(mode,KeyEvent.VK_X); break;
- case 'y': doType(mode,KeyEvent.VK_Y); break;
- case 'z': doType(mode,KeyEvent.VK_Z); break;
- case 'A': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_A); break;
- case 'B': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_B); break;
- case 'C': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_C); break;
- case 'D': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_D); break;
- case 'E': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_E); break;
- case 'F': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_F); break;
- case 'G': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_G); break;
- case 'H': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_H); break;
- case 'I': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_I); break;
- case 'J': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_J); break;
- case 'K': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_K); break;
- case 'L': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_L); break;
- case 'M': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_M); break;
- case 'N': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_N); break;
- case 'O': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_O); break;
- case 'P': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_P); break;
- case 'Q': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_Q); break;
- case 'R': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_R); break;
- case 'S': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_S); break;
- case 'T': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_T); break;
- case 'U': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_U); break;
- case 'V': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_V); break;
- case 'W': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_W); break;
- case 'X': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_X); break;
- case 'Y': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_Y); break;
- case 'Z': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_Z); break;
- case '`': doType(mode,KeyEvent.VK_BACK_QUOTE); break;
- case '0': doType(mode,KeyEvent.VK_0); break;
- case '1': doType(mode,KeyEvent.VK_1); break;
- case '2': doType(mode,KeyEvent.VK_2); break;
- case '3': doType(mode,KeyEvent.VK_3); break;
- case '4': doType(mode,KeyEvent.VK_4); break;
- case '5': doType(mode,KeyEvent.VK_5); break;
- case '6': doType(mode,KeyEvent.VK_6); break;
- case '7': doType(mode,KeyEvent.VK_7); break;
- case '8': doType(mode,KeyEvent.VK_8); break;
- case '9': doType(mode,KeyEvent.VK_9); break;
- case '-': doType(mode,KeyEvent.VK_MINUS); break;
- case '=': doType(mode,KeyEvent.VK_EQUALS); break;
- case '~': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE); break;
- case '!': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_1); break;
- case '@': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_2); break;
- case '#': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_3); break;
- case '$': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_4); break;
- case '%': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_5); break;
- case '^': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_6); break;
- case '&': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_7); break;
- case '*': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_8); break;
- case '(': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_9); break;
- case ')': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_0); break;
- case '_': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS); break;
- case '+': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS); break;
- case '\b': doType(mode,KeyEvent.VK_BACK_SPACE); break;
- case '\t': doType(mode,KeyEvent.VK_TAB); break;
- case '\r': doType(mode,KeyEvent.VK_ENTER); break;
- case '\n': doType(mode,KeyEvent.VK_ENTER); break;
- case '[': doType(mode,KeyEvent.VK_OPEN_BRACKET); break;
- case ']': doType(mode,KeyEvent.VK_CLOSE_BRACKET); break;
- case '\\': doType(mode,KeyEvent.VK_BACK_SLASH); break;
- case '{': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET); break;
- case '}': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET); break;
- case '|': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH); break;
- case ';': doType(mode,KeyEvent.VK_SEMICOLON); break;
- case ':': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_SEMICOLON); break;
- case '\'': doType(mode,KeyEvent.VK_QUOTE); break;
- case '"': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE); break;
- case ',': doType(mode,KeyEvent.VK_COMMA); break;
- case '<': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_COMMA); break;
- case '.': doType(mode,KeyEvent.VK_PERIOD); break;
- case '>': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_PERIOD); break;
- case '/': doType(mode,KeyEvent.VK_SLASH); break;
- case '?': doType(mode,KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH); break;
- case ' ': doType(mode,KeyEvent.VK_SPACE); break;
- case Key.ESC : doType(mode,KeyEvent.VK_ESCAPE); break;
- case Key.UP : doType(mode,KeyEvent.VK_UP); break;
- case Key.RIGHT : doType(mode,KeyEvent.VK_RIGHT); break;
- case Key.DOWN : doType(mode,KeyEvent.VK_DOWN); break;
- case Key.LEFT : doType(mode,KeyEvent.VK_LEFT); break;
- case Key.PAGE_UP : doType(mode,KeyEvent.VK_PAGE_UP); break;
- case Key.PAGE_DOWN : doType(mode,KeyEvent.VK_PAGE_DOWN); break;
- case Key.DELETE : doType(mode,KeyEvent.VK_DELETE); break;
- case Key.END : doType(mode,KeyEvent.VK_END); break;
- case Key.HOME : doType(mode,KeyEvent.VK_HOME); break;
- case Key.INSERT : doType(mode,KeyEvent.VK_INSERT); break;
- case Key.F1 : doType(mode,KeyEvent.VK_F1); break;
- case Key.F2 : doType(mode,KeyEvent.VK_F2); break;
- case Key.F3 : doType(mode,KeyEvent.VK_F3); break;
- case Key.F4 : doType(mode,KeyEvent.VK_F4); break;
- case Key.F5 : doType(mode,KeyEvent.VK_F5); break;
- case Key.F6 : doType(mode,KeyEvent.VK_F6); break;
- case Key.F7 : doType(mode,KeyEvent.VK_F7); break;
- case Key.F8 : doType(mode,KeyEvent.VK_F8); break;
- case Key.F9 : doType(mode,KeyEvent.VK_F9); break;
- case Key.F10 : doType(mode,KeyEvent.VK_F10); break;
- case Key.F11 : doType(mode,KeyEvent.VK_F11); break;
- case Key.F12 : doType(mode,KeyEvent.VK_F12); break;
- case Key.F13 : doType(mode,KeyEvent.VK_F13); break;
- case Key.F14 : doType(mode,KeyEvent.VK_F14); break;
- case Key.F15 : doType(mode,KeyEvent.VK_F15); break;
- case Key.SHIFT : doType(mode,KeyEvent.VK_SHIFT); break;
- case Key.CTRL : doType(mode,KeyEvent.VK_CONTROL); break;
- case Key.ALT : doType(mode,KeyEvent.VK_ALT); break;
- case Key.META : doType(mode,KeyEvent.VK_META); break;
- case Key.PRINTSCREEN: doType(mode,KeyEvent.VK_PRINTSCREEN); break;
- case Key.SCROLL_LOCK: doType(mode,KeyEvent.VK_SCROLL_LOCK); break;
- case Key.PAUSE : doType(mode,KeyEvent.VK_PAUSE); break;
- case Key.CAPS_LOCK : doType(mode,KeyEvent.VK_CAPS_LOCK); break;
- case Key.NUM0 : doType(mode,KeyEvent.VK_NUMPAD0); break;
- case Key.NUM1 : doType(mode,KeyEvent.VK_NUMPAD1); break;
- case Key.NUM2 : doType(mode,KeyEvent.VK_NUMPAD2); break;
- case Key.NUM3 : doType(mode,KeyEvent.VK_NUMPAD3); break;
- case Key.NUM4 : doType(mode,KeyEvent.VK_NUMPAD4); break;
- case Key.NUM5 : doType(mode,KeyEvent.VK_NUMPAD5); break;
- case Key.NUM6 : doType(mode,KeyEvent.VK_NUMPAD6); break;
- case Key.NUM7 : doType(mode,KeyEvent.VK_NUMPAD7); break;
- case Key.NUM8 : doType(mode,KeyEvent.VK_NUMPAD8); break;
- case Key.NUM9 : doType(mode,KeyEvent.VK_NUMPAD9); break;
- case Key.SEPARATOR : doType(mode,KeyEvent.VK_SEPARATOR); break;
- case Key.NUM_LOCK : doType(mode,KeyEvent.VK_NUM_LOCK); break;
- case Key.ADD : doType(mode,KeyEvent.VK_ADD); break;
- case Key.MINUS : doType(mode,KeyEvent.VK_MINUS); break;
- case Key.MULTIPLY : doType(mode,KeyEvent.VK_MULTIPLY); break;
- case Key.DIVIDE : doType(mode,KeyEvent.VK_DIVIDE); break;
- default:
- throw new IllegalArgumentException("Cannot type character " + character);
- }
+ doType(mode, Key.toJavaKeyCode(character));
}
}
=== modified file 'sikuli-script/src/main/java/org/sikuli/script/Env.java'
--- sikuli-script/src/main/java/org/sikuli/script/Env.java 2011-05-05 15:04:08 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/Env.java 2011-08-21 03:38:17 +0000
@@ -13,6 +13,8 @@
import java.lang.reflect.Constructor;
+import org.sikuli.script.internal.hotkey.HotkeyManager;
+
public class Env {
final static String SikuliVersion = "X-1.0rc3";
@@ -138,4 +140,15 @@
return SikuliVersion;
}
+ public static boolean addHotkey(char key, int modifiers, HotkeyListener listener){
+ return HotkeyManager.getInstance().addHotkey(key, modifiers, listener);
+ }
+
+ public static boolean removeHotkey(char key, int modifiers){
+ return HotkeyManager.getInstance().removeHotkey(key, modifiers);
+ }
+
+ public static void cleanUp(){
+ HotkeyManager.getInstance().cleanUp();
+ }
}
=== added file 'sikuli-script/src/main/java/org/sikuli/script/HotkeyEvent.java'
--- sikuli-script/src/main/java/org/sikuli/script/HotkeyEvent.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/HotkeyEvent.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script;
+
+
+public class HotkeyEvent {
+ public int keyCode;
+ public int modifiers;
+
+ public HotkeyEvent(int code_, int mod_){
+ init(code_, mod_);
+ }
+
+ void init(int code_, int mod_){
+ keyCode = code_;
+ modifiers = mod_;
+ }
+}
+
=== added file 'sikuli-script/src/main/java/org/sikuli/script/HotkeyListener.java'
--- sikuli-script/src/main/java/org/sikuli/script/HotkeyListener.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/HotkeyListener.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script;
+
+
+public interface HotkeyListener {
+ public void hotkeyPressed(HotkeyEvent e);
+}
=== modified file 'sikuli-script/src/main/java/org/sikuli/script/Key.java'
--- sikuli-script/src/main/java/org/sikuli/script/Key.java 2011-07-02 01:55:39 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/Key.java 2011-08-21 03:38:17 +0000
@@ -5,7 +5,10 @@
*/
package org.sikuli.script;
+import java.awt.event.KeyEvent;
+
public class Key {
+ public static final char SPACE = ' ';
public static final char ENTER = '\n';
public static final char BACKSPACE = '\b';
public static final char TAB = '\t';
@@ -61,4 +64,163 @@
public static final char MINUS = '\ue03D';
public static final char MULTIPLY = '\ue03E';
public static final char DIVIDE = '\ue03F';
+
+ /**
+ * Convert Sikuli Key to Java virtual key code
+ */
+ public static int[] toJavaKeyCode(char key){
+ switch (key) {
+ case 'a': return new int[] {KeyEvent.VK_A};
+ case 'b': return new int[] {KeyEvent.VK_B};
+ case 'c': return new int[] {KeyEvent.VK_C};
+ case 'd': return new int[] {KeyEvent.VK_D};
+ case 'e': return new int[] {KeyEvent.VK_E};
+ case 'f': return new int[] {KeyEvent.VK_F};
+ case 'g': return new int[] {KeyEvent.VK_G};
+ case 'h': return new int[] {KeyEvent.VK_H};
+ case 'i': return new int[] {KeyEvent.VK_I};
+ case 'j': return new int[] {KeyEvent.VK_J};
+ case 'k': return new int[] {KeyEvent.VK_K};
+ case 'l': return new int[] {KeyEvent.VK_L};
+ case 'm': return new int[] {KeyEvent.VK_M};
+ case 'n': return new int[] {KeyEvent.VK_N};
+ case 'o': return new int[] {KeyEvent.VK_O};
+ case 'p': return new int[] {KeyEvent.VK_P};
+ case 'q': return new int[] {KeyEvent.VK_Q};
+ case 'r': return new int[] {KeyEvent.VK_R};
+ case 's': return new int[] {KeyEvent.VK_S};
+ case 't': return new int[] {KeyEvent.VK_T};
+ case 'u': return new int[] {KeyEvent.VK_U};
+ case 'v': return new int[] {KeyEvent.VK_V};
+ case 'w': return new int[] {KeyEvent.VK_W};
+ case 'x': return new int[] {KeyEvent.VK_X};
+ case 'y': return new int[] {KeyEvent.VK_Y};
+ case 'z': return new int[] {KeyEvent.VK_Z};
+ case 'A': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_A};
+ case 'B': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_B};
+ case 'C': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_C};
+ case 'D': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_D};
+ case 'E': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_E};
+ case 'F': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_F};
+ case 'G': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_G};
+ case 'H': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_H};
+ case 'I': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_I};
+ case 'J': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_J};
+ case 'K': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_K};
+ case 'L': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_L};
+ case 'M': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_M};
+ case 'N': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_N};
+ case 'O': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_O};
+ case 'P': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_P};
+ case 'Q': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_Q};
+ case 'R': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_R};
+ case 'S': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_S};
+ case 'T': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_T};
+ case 'U': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_U};
+ case 'V': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_V};
+ case 'W': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_W};
+ case 'X': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_X};
+ case 'Y': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_Y};
+ case 'Z': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_Z};
+ case '`': return new int[] {KeyEvent.VK_BACK_QUOTE};
+ case '0': return new int[] {KeyEvent.VK_0};
+ case '1': return new int[] {KeyEvent.VK_1};
+ case '2': return new int[] {KeyEvent.VK_2};
+ case '3': return new int[] {KeyEvent.VK_3};
+ case '4': return new int[] {KeyEvent.VK_4};
+ case '5': return new int[] {KeyEvent.VK_5};
+ case '6': return new int[] {KeyEvent.VK_6};
+ case '7': return new int[] {KeyEvent.VK_7};
+ case '8': return new int[] {KeyEvent.VK_8};
+ case '9': return new int[] {KeyEvent.VK_9};
+ case '-': return new int[] {KeyEvent.VK_MINUS};
+ case '=': return new int[] {KeyEvent.VK_EQUALS};
+ case '~': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE};
+ case '!': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_1};
+ case '@': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_2};
+ case '#': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_3};
+ case '$': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_4};
+ case '%': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_5};
+ case '^': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_6};
+ case '&': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_7};
+ case '*': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_8};
+ case '(': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_9};
+ case ')': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_0};
+ case '_': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS};
+ case '+': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS};
+ case '\b':return new int[] {KeyEvent.VK_BACK_SPACE};
+ case '\t':return new int[] {KeyEvent.VK_TAB};
+ case '\r':return new int[] {KeyEvent.VK_ENTER};
+ case '\n':return new int[] {KeyEvent.VK_ENTER};
+ case '[': return new int[] {KeyEvent.VK_OPEN_BRACKET};
+ case ']': return new int[] {KeyEvent.VK_CLOSE_BRACKET};
+ case '\\':return new int[] {KeyEvent.VK_BACK_SLASH};
+ case '{': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET};
+ case '}': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET};
+ case '|': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH};
+ case ';': return new int[] {KeyEvent.VK_SEMICOLON};
+ case ':': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_SEMICOLON};
+ case '\'':return new int[] {KeyEvent.VK_QUOTE};
+ case '"': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE};
+ case ',': return new int[] {KeyEvent.VK_COMMA};
+ case '<': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_COMMA};
+ case '.': return new int[] {KeyEvent.VK_PERIOD};
+ case '>': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_PERIOD};
+ case '/': return new int[] {KeyEvent.VK_SLASH};
+ case '?': return new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH};
+ case ' ': return new int[] {KeyEvent.VK_SPACE};
+ case Key.ESC : return new int[] {KeyEvent.VK_ESCAPE};
+ case Key.UP : return new int[] {KeyEvent.VK_UP};
+ case Key.RIGHT : return new int[] {KeyEvent.VK_RIGHT};
+ case Key.DOWN : return new int[] {KeyEvent.VK_DOWN};
+ case Key.LEFT : return new int[] {KeyEvent.VK_LEFT};
+ case Key.PAGE_UP : return new int[] {KeyEvent.VK_PAGE_UP};
+ case Key.PAGE_DOWN : return new int[] {KeyEvent.VK_PAGE_DOWN};
+ case Key.DELETE : return new int[] {KeyEvent.VK_DELETE};
+ case Key.END : return new int[] {KeyEvent.VK_END};
+ case Key.HOME : return new int[] {KeyEvent.VK_HOME};
+ case Key.INSERT : return new int[] {KeyEvent.VK_INSERT};
+ case Key.F1 : return new int[] {KeyEvent.VK_F1};
+ case Key.F2 : return new int[] {KeyEvent.VK_F2};
+ case Key.F3 : return new int[] {KeyEvent.VK_F3};
+ case Key.F4 : return new int[] {KeyEvent.VK_F4};
+ case Key.F5 : return new int[] {KeyEvent.VK_F5};
+ case Key.F6 : return new int[] {KeyEvent.VK_F6};
+ case Key.F7 : return new int[] {KeyEvent.VK_F7};
+ case Key.F8 : return new int[] {KeyEvent.VK_F8};
+ case Key.F9 : return new int[] {KeyEvent.VK_F9};
+ case Key.F10 : return new int[] {KeyEvent.VK_F10};
+ case Key.F11 : return new int[] {KeyEvent.VK_F11};
+ case Key.F12 : return new int[] {KeyEvent.VK_F12};
+ case Key.F13 : return new int[] {KeyEvent.VK_F13};
+ case Key.F14 : return new int[] {KeyEvent.VK_F14};
+ case Key.F15 : return new int[] {KeyEvent.VK_F15};
+ case Key.SHIFT : return new int[] {KeyEvent.VK_SHIFT};
+ case Key.CTRL : return new int[] {KeyEvent.VK_CONTROL};
+ case Key.ALT : return new int[] {KeyEvent.VK_ALT};
+ case Key.META : return new int[] {KeyEvent.VK_META};
+ case Key.PRINTSCREEN: return new int[] {KeyEvent.VK_PRINTSCREEN};
+ case Key.SCROLL_LOCK: return new int[] {KeyEvent.VK_SCROLL_LOCK};
+ case Key.PAUSE : return new int[] {KeyEvent.VK_PAUSE};
+ case Key.CAPS_LOCK : return new int[] {KeyEvent.VK_CAPS_LOCK};
+ case Key.NUM0 : return new int[] {KeyEvent.VK_NUMPAD0};
+ case Key.NUM1 : return new int[] {KeyEvent.VK_NUMPAD1};
+ case Key.NUM2 : return new int[] {KeyEvent.VK_NUMPAD2};
+ case Key.NUM3 : return new int[] {KeyEvent.VK_NUMPAD3};
+ case Key.NUM4 : return new int[] {KeyEvent.VK_NUMPAD4};
+ case Key.NUM5 : return new int[] {KeyEvent.VK_NUMPAD5};
+ case Key.NUM6 : return new int[] {KeyEvent.VK_NUMPAD6};
+ case Key.NUM7 : return new int[] {KeyEvent.VK_NUMPAD7};
+ case Key.NUM8 : return new int[] {KeyEvent.VK_NUMPAD8};
+ case Key.NUM9 : return new int[] {KeyEvent.VK_NUMPAD9};
+ case Key.SEPARATOR : return new int[] {KeyEvent.VK_SEPARATOR};
+ case Key.NUM_LOCK : return new int[] {KeyEvent.VK_NUM_LOCK};
+ case Key.ADD : return new int[] {KeyEvent.VK_ADD};
+ case Key.MINUS : return new int[] {KeyEvent.VK_MINUS};
+ case Key.MULTIPLY : return new int[] {KeyEvent.VK_MULTIPLY};
+ case Key.DIVIDE : return new int[] {KeyEvent.VK_DIVIDE};
+ default:
+ throw new IllegalArgumentException("Cannot convert character " + key);
+ }
+ }
}
=== added directory 'sikuli-script/src/main/java/org/sikuli/script/internal'
=== added directory 'sikuli-script/src/main/java/org/sikuli/script/internal/hotkey'
=== added file 'sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/HotkeyManager.java'
--- sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/HotkeyManager.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/HotkeyManager.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script.internal.hotkey;
+
+import java.lang.reflect.Constructor;
+
+import java.awt.event.KeyEvent;
+
+import org.sikuli.script.HotkeyListener;
+import org.sikuli.script.Env;
+import org.sikuli.script.Debug;
+import org.sikuli.script.Key;
+
+public abstract class HotkeyManager {
+ protected static HotkeyManager _instance = null;
+
+ private static String getOSHotkeyManagerClass(){
+ String pkg = "org.sikuli.script.internal.hotkey.";
+ switch(Env.getOS()){
+ case MAC: return pkg+"MacHotkeyManager";
+ case WINDOWS: return pkg+"WindowsHotkeyManager";
+ case LINUX: return pkg+"LinuxHotkeyManager";
+ default:
+ Debug.error("Error: Hotkey registration is not supported on your OS.");
+ }
+ return null;
+ }
+
+ protected String getKeyCodeText(int key){
+ return KeyEvent.getKeyText(key).toUpperCase();
+ }
+
+ protected String getKeyModifierText(int modifiers){
+ String txtMod = KeyEvent.getKeyModifiersText(modifiers).toUpperCase();
+ if(Env.isMac()){
+ txtMod = txtMod.replace("META","CMD");
+ txtMod = txtMod.replace("WINDOWS","CMD");
+ }
+ else{
+ txtMod = txtMod.replace("META","WIN");
+ txtMod = txtMod.replace("WINDOWS","WIN");
+ }
+ return txtMod;
+ }
+
+ public static HotkeyManager getInstance(){
+ if(_instance==null){
+ String cls = getOSHotkeyManagerClass();
+ if(cls != null){
+ try{
+ Class c = Class.forName(cls);
+ Constructor constr = c.getConstructor();
+ _instance = (HotkeyManager)constr.newInstance();
+ }
+ catch(Exception e){
+ Debug.error("Can't create " + cls + ": " + e.getMessage());
+ }
+ }
+ }
+ return _instance;
+ }
+
+ /**
+ * install a hotkey listener.
+ *
+ * @return true if success. false otherwise.
+ */
+ public boolean addHotkey(char key, int modifiers, HotkeyListener listener){
+ int[] keyCodes = Key.toJavaKeyCode(key);
+ int keyCode = keyCodes[keyCodes.length-1];
+ String txtMod = getKeyModifierText(modifiers);
+ String txtCode = getKeyCodeText(keyCode);
+ Debug.info("add hotkey: " + txtMod + " " + txtCode);
+ return _instance._addHotkey(keyCode, modifiers, listener);
+ }
+
+
+ /**
+ * uninstall a hotkey listener.
+ *
+ * @return true if success. false otherwise.
+ */
+ public boolean removeHotkey(char key, int modifiers){
+ int[] keyCodes = Key.toJavaKeyCode(key);
+ int keyCode = keyCodes[keyCodes.length-1];
+ String txtMod = getKeyModifierText(modifiers);
+ String txtCode = getKeyCodeText(keyCode);
+ Debug.info("remove hotkey: " + txtMod + " " + txtCode);
+ return _instance._removeHotkey(keyCode, modifiers);
+ }
+
+
+ abstract protected boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener);
+ abstract protected boolean _removeHotkey(int keyCode, int modifiers);
+ abstract public void cleanUp();
+}
=== added file 'sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/LinuxHotkeyManager.java'
--- sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/LinuxHotkeyManager.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/LinuxHotkeyManager.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script.internal.hotkey;
+
+import java.lang.reflect.*;
+import java.awt.Event;
+import java.awt.event.*;
+import java.util.*;
+import java.io.IOException;
+
+import org.sikuli.script.Debug;
+import org.sikuli.script.HotkeyListener;
+import org.sikuli.script.HotkeyEvent;
+
+import com.wapmx.nativeutils.jniloader.NativeLoader;
+import jxgrabkey.HotkeyConflictException;
+import jxgrabkey.JXGrabKey;
+
+public class LinuxHotkeyManager extends HotkeyManager {
+ static{
+ try{
+ NativeLoader.loadLibrary("JXGrabKey");
+ }
+ catch(IOException e){
+ Debug.error("Can't load native lib JXGrabKey");
+ e.printStackTrace();
+ }
+ }
+
+ class HotkeyData {
+ int key, modifiers;
+ HotkeyListener listener;
+
+ public HotkeyData(int key_, int mod_, HotkeyListener l_){
+ key = key_;
+ modifiers = mod_;
+ listener = l_;
+ }
+ };
+
+ class MyHotkeyHandler implements jxgrabkey.HotkeyListener{
+ public void onHotkey(int id){
+ Debug.log(4, "Hotkey pressed");
+ HotkeyData data = _idCallbackMap.get(id);
+ HotkeyEvent e = new HotkeyEvent(data.key, data.modifiers);
+ data.listener.hotkeyPressed(e);
+ }
+ };
+
+ private Map<Integer, HotkeyData> _idCallbackMap = new HashMap<Integer,HotkeyData >();
+ private int _gHotkeyId = 1;
+
+ protected boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener){
+ JXGrabKey grabKey = JXGrabKey.getInstance();
+
+ if(_gHotkeyId == 1){
+ grabKey.addHotkeyListener(new MyHotkeyHandler());
+ }
+
+ _removeHotkey(keyCode, modifiers);
+ int id = _gHotkeyId++;
+ HotkeyData data = new HotkeyData(keyCode, modifiers, listener);
+ _idCallbackMap.put(id, data);
+
+ try{
+ //JXGrabKey.setDebugOutput(true);
+ grabKey.registerAwtHotkey(id, modifiers, keyCode);
+ }catch(HotkeyConflictException e){
+ Debug.error("Hot key conflicts: " + txtMod + "+" + txtCode);
+ return false;
+ }
+ return true;
+ }
+
+ protected boolean _removeHotkey(int keyCode, int modifiers){
+ for( Map.Entry<Integer, HotkeyData> entry : _idCallbackMap.entrySet() ){
+ HotkeyData data = entry.getValue();
+ if(data.key == keyCode && data.modifiers == modifiers){
+ JXGrabKey grabKey = JXGrabKey.getInstance();
+ int id = entry.getKey();
+ grabKey.unregisterHotKey(id);
+ _idCallbackMap.remove(id);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public void cleanUp(){
+ JXGrabKey grabKey = JXGrabKey.getInstance();
+ for( Map.Entry<Integer, HotkeyData> entry : _idCallbackMap.entrySet() ){
+ int id = entry.getKey();
+ grabKey.unregisterHotKey(id);
+ }
+ _gHotkeyId = 1;
+ _idCallbackMap.clear();
+ grabKey.getInstance().cleanUp();
+ }
+
+}
+
+
=== added file 'sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/MacHotkeyManager.java'
--- sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/MacHotkeyManager.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/MacHotkeyManager.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script.internal.hotkey;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.InputEvent;
+import javax.swing.*;
+import java.io.IOException;
+import java.util.prefs.*;
+import com.apple.eawt.*;
+import com.wapmx.nativeutils.jniloader.NativeLoader;
+
+import org.sikuli.script.Debug;
+import org.sikuli.script.Env;
+import org.sikuli.script.HotkeyListener;
+
+// http://lists.apple.com/archives/mac-games-dev/2001/Sep/msg00113.html
+// full key table: http://www.mactech.com/articles/mactech/Vol.04/04.12/Macinkeys/
+// modifiers code: http://www.mactech.com/macintosh-c/chap02-1.html
+
+public class MacHotkeyManager extends HotkeyManager {
+ static final int CARBON_MASK_CMD = 0x0100;
+ static final int CARBON_MASK_SHIFT = 0x0200;
+ static final int CARBON_MASK_OPT = 0x0800;
+ static final int CARBON_MASK_CTRL = 0x1000;
+
+ static {
+ try{
+ NativeLoader.loadLibrary("MacHotkeyManager");
+ }
+ catch(IOException e){
+ e.printStackTrace();
+ }
+ }
+
+ protected boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener){
+ int ckey = convertToCarbonKey(keyCode);
+ int cmod = convertToCarbonModifiers(modifiers);
+ return installGlobalHotkey(keyCode, modifiers, ckey, cmod, listener);
+ }
+
+
+ protected boolean _removeHotkey(int keyCode, int modifiers){
+ int ckey = convertToCarbonKey(keyCode);
+ int cmod = convertToCarbonModifiers(modifiers);
+ return uninstallGlobalHotkey(ckey, cmod);
+ }
+
+
+ private native boolean installGlobalHotkey(int jKey, int jMod, int keyCode, int modifiers, HotkeyListener listener);
+ private native boolean uninstallGlobalHotkey(int keyCode, int modifiers);
+ public native void cleanUp();
+
+ private int convertToCarbonModifiers(int mod){
+ int cmod = 0;
+ if((mod&InputEvent.SHIFT_MASK) != 0) cmod |= CARBON_MASK_SHIFT;
+ if((mod&InputEvent.META_MASK) != 0) cmod |= CARBON_MASK_CMD;
+ if((mod&InputEvent.ALT_MASK) != 0) cmod |= CARBON_MASK_OPT;
+ if((mod&InputEvent.CTRL_MASK) != 0) cmod |= CARBON_MASK_CTRL;
+ return cmod;
+ }
+
+ private int convertToCarbonKey(int keycode){
+ switch(keycode){
+ case KeyEvent.VK_BACK_SPACE: return 0x33;
+ case KeyEvent.VK_TAB: return 0x30;
+ case KeyEvent.VK_CLEAR: return 0x47;
+ case KeyEvent.VK_ENTER: return 0x24;
+ case KeyEvent.VK_SHIFT: return 0xF0;
+ case KeyEvent.VK_CONTROL: return 0xF1;
+ case KeyEvent.VK_META: return 0xF2;
+ case KeyEvent.VK_PAUSE: return 0x71; // = F15
+ case KeyEvent.VK_ESCAPE: return 0x35;
+ case KeyEvent.VK_SPACE: return 0x31;
+ case KeyEvent.VK_OPEN_BRACKET: return 0x21;
+ case KeyEvent.VK_BACK_SLASH: return 0x2A;
+ case KeyEvent.VK_CLOSE_BRACKET: return 0x1E;
+ case KeyEvent.VK_SLASH: return 0x2C;
+ case KeyEvent.VK_PERIOD: return 0x2F;
+ case KeyEvent.VK_COMMA: return 0x2B;
+ case KeyEvent.VK_SEMICOLON: return 0x29;
+ case KeyEvent.VK_END: return 0x77;
+ case KeyEvent.VK_HOME: return 0x73;
+ case KeyEvent.VK_LEFT: return 0x7B;
+ case KeyEvent.VK_UP: return 0x7E;
+ case KeyEvent.VK_RIGHT: return 0x7C;
+ case KeyEvent.VK_DOWN: return 0x7D;
+ case KeyEvent.VK_PRINTSCREEN: return 0x69; // F13
+ case KeyEvent.VK_INSERT: return 0x72; // help
+ case KeyEvent.VK_DELETE: return 0x75;
+ case KeyEvent.VK_HELP: return 0x72;
+ case KeyEvent.VK_0: return 0x1D;
+ case KeyEvent.VK_1: return 0x12;
+ case KeyEvent.VK_2: return 0x13;
+ case KeyEvent.VK_3: return 0x14;
+ case KeyEvent.VK_4: return 0x15;
+ case KeyEvent.VK_5: return 0x17;
+ case KeyEvent.VK_6: return 0x16;
+ case KeyEvent.VK_7: return 0x1A;
+ case KeyEvent.VK_8: return 0x1C;
+ case KeyEvent.VK_9: return 0x19;
+ case KeyEvent.VK_MINUS: return 0x1B;
+ case KeyEvent.VK_EQUALS: return 0x18;
+ case KeyEvent.VK_A: return 0x00;
+ case KeyEvent.VK_B: return 0x0B;
+ case KeyEvent.VK_C: return 0x08;
+ case KeyEvent.VK_D: return 0x02;
+ case KeyEvent.VK_E: return 0x0E;
+ case KeyEvent.VK_F: return 0x03;
+ case KeyEvent.VK_G: return 0x05;
+ case KeyEvent.VK_H: return 0x04;
+ case KeyEvent.VK_I: return 0x22;
+ case KeyEvent.VK_J: return 0x26;
+ case KeyEvent.VK_K: return 0x28;
+ case KeyEvent.VK_L: return 0x25;
+ case KeyEvent.VK_M: return 0x2E;
+ case KeyEvent.VK_N: return 0x2D;
+ case KeyEvent.VK_O: return 0x1F;
+ case KeyEvent.VK_P: return 0x23;
+ case KeyEvent.VK_Q: return 0x0C;
+ case KeyEvent.VK_R: return 0x0F;
+ case KeyEvent.VK_S: return 0x01;
+ case KeyEvent.VK_T: return 0x11;
+ case KeyEvent.VK_U: return 0x20;
+ case KeyEvent.VK_V: return 0x09;
+ case KeyEvent.VK_W: return 0x0D;
+ case KeyEvent.VK_X: return 0x07;
+ case KeyEvent.VK_Y: return 0x10;
+ case KeyEvent.VK_Z: return 0x06;
+ case KeyEvent.VK_NUMPAD0: return 0x52;
+ case KeyEvent.VK_NUMPAD1: return 0x53;
+ case KeyEvent.VK_NUMPAD2: return 0x54;
+ case KeyEvent.VK_NUMPAD3: return 0x55;
+ case KeyEvent.VK_NUMPAD4: return 0x56;
+ case KeyEvent.VK_NUMPAD5: return 0x57;
+ case KeyEvent.VK_NUMPAD6: return 0x58;
+ case KeyEvent.VK_NUMPAD7: return 0x59;
+ case KeyEvent.VK_NUMPAD8: return 0x5B;
+ case KeyEvent.VK_NUMPAD9: return 0x5C;
+ case KeyEvent.VK_MULTIPLY: return 0x43;
+ case KeyEvent.VK_ADD: return 0x45;
+ case KeyEvent.VK_SEPARATOR: return 0xFF; // not supported with Button or GetKeys
+ case KeyEvent.VK_SUBTRACT: return 0x4E;
+ case KeyEvent.VK_DECIMAL: return 0x41;
+ case KeyEvent.VK_DIVIDE: return 0x4B;
+ case KeyEvent.VK_F1: return 0x7A;
+ case KeyEvent.VK_F2: return 0x7B;
+ case KeyEvent.VK_F3: return 0x63;
+ case KeyEvent.VK_F4: return 0x76;
+ case KeyEvent.VK_F5: return 0x60;
+ case KeyEvent.VK_F6: return 0x61;
+ case KeyEvent.VK_F7: return 0x62;
+ case KeyEvent.VK_F8: return 0x64;
+ case KeyEvent.VK_F9: return 0x65;
+ case KeyEvent.VK_F10: return 0x6D;
+ case KeyEvent.VK_F11: return 0x67;
+ case KeyEvent.VK_F12: return 0x6F;
+ case KeyEvent.VK_F13: return 0x69;
+ case KeyEvent.VK_F14: return 0x6B;
+ case KeyEvent.VK_F15: return 0x71;
+ case KeyEvent.VK_NUM_LOCK: return 0x47;
+ default: return 0xFF;
+ }
+
+ }
+}
+
+
=== added file 'sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/WindowsHotkeyManager.java'
--- sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/WindowsHotkeyManager.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/java/org/sikuli/script/internal/hotkey/WindowsHotkeyManager.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script.internal.hotkey;
+
+import java.lang.reflect.*;
+import java.awt.Event;
+import java.awt.event.*;
+import java.util.*;
+import com.melloware.jintellitype.IntellitypeListener;
+import com.melloware.jintellitype.JIntellitype;
+
+import org.sikuli.script.Debug;
+import org.sikuli.script.HotkeyListener;
+import org.sikuli.script.HotkeyEvent;
+
+public class WindowsHotkeyManager extends HotkeyManager {
+ class HotkeyData {
+ int key, modifiers;
+ HotkeyListener listener;
+
+ public HotkeyData(int key_, int mod_, HotkeyListener l_){
+ key = key_;
+ modifiers = mod_;
+ listener = l_;
+ }
+ };
+
+ class JIntellitypeHandler implements
+ com.melloware.jintellitype.HotkeyListener{
+ public void onHotKey(int id){
+ Debug.log(4, "Hotkey pressed");
+ HotkeyData data = _idCallbackMap.get(id);
+ HotkeyEvent e = new HotkeyEvent(data.key, data.modifiers);
+ data.listener.hotkeyPressed(e);
+ }
+ };
+
+ private Map<Integer, HotkeyData> _idCallbackMap = new HashMap<Integer,HotkeyData >();
+ private int _gHotkeyId = 1;
+
+ protected boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener){
+ JIntellitype itype = JIntellitype.getInstance();
+
+ if(_gHotkeyId == 1){
+ itype.addHotKeyListener(new JIntellitypeHandler());
+ }
+
+ _removeHotkey(keyCode, modifiers);
+ int id = _gHotkeyId++;
+ HotkeyData data = new HotkeyData(keyCode, modifiers, listener);
+ _idCallbackMap.put(id, data);
+
+ itype.registerSwingHotKey(id, modifiers, keyCode);
+ return true;
+ }
+
+ protected boolean _removeHotkey(int keyCode, int modifiers){
+ for( Map.Entry<Integer, HotkeyData> entry : _idCallbackMap.entrySet() ){
+ HotkeyData data = entry.getValue();
+ if(data.key == keyCode && data.modifiers == modifiers){
+ JIntellitype itype = JIntellitype.getInstance();
+ int id = entry.getKey();
+ itype.unregisterHotKey(id);
+ _idCallbackMap.remove(id);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ public void cleanUp(){
+ JIntellitype itype = JIntellitype.getInstance();
+ for( Map.Entry<Integer, HotkeyData> entry : _idCallbackMap.entrySet() ){
+ int id = entry.getKey();
+ itype.unregisterHotKey(id);
+ }
+ _gHotkeyId = 1;
+ _idCallbackMap.clear();
+ itype.cleanUp();
+ }
+
+}
+
+
=== modified file 'sikuli-script/src/main/native/CMakeLists.txt'
--- sikuli-script/src/main/native/CMakeLists.txt 2011-05-05 15:04:08 +0000
+++ sikuli-script/src/main/native/CMakeLists.txt 2011-08-21 03:38:17 +0000
@@ -18,6 +18,7 @@
org_sikuli_script_VDictProxy.h
org_sikuli_script_Win32Util.h
org_sikuli_script_MacUtil.h
+ org_sikuli_script_internal_hotkey_MacHotkeyManager.h
)
SET(LIBRARY_OUTPUT_PATH ${BINARY_LIB_DIR})
@@ -90,6 +91,7 @@
TARGET_LINK_LIBRARIES(Win32Util ${JAVA_AWT_LIBRARY})
ENDIF()
+
IF(APPLE)
LIST(APPEND BUILD_TARGETS MacUtil)
FIND_LIBRARY(JAVA_LIBRARY JavaVM)
@@ -103,6 +105,17 @@
org_sikuli_script_MacUtil.h
)
TARGET_LINK_LIBRARIES(MacUtil ${EXTRA_LIBS})
+
+ SET(BUILD_TARGETS
+ MacHotkeyManager
+ )
+
+ ADD_LIBRARY(MacHotkeyManager SHARED
+ MacHotkeyManager.cc
+ sikuli-debug.cpp
+ org_sikuli_script_internal_hotkey_MacHotkeyManager.h
+ )
+ TARGET_LINK_LIBRARIES(MacHotkeyManager ${EXTRA_LIBS})
ENDIF()
SET(NATIVE_LIBS
@@ -114,6 +127,7 @@
VDictProxy.cc
org_sikuli_script_VDictProxy.h
)
+TARGET_LINK_LIBRARIES(VDictProxy ${OpenCV_LIBS})
## SWIG: generate a JNI wrapper
@@ -155,9 +169,4 @@
endif(APPLE)
endforeach(BUILD_TARGET ${BUILD_TARGETS})
-add_custom_target(${JAR_FILE}.libs-in-jar
- COMMAND ${CMAKE_COMMAND} -E make_directory ${JAR_DIR}/META-INF
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${BINARY_LIB_DIR} ${JAR_DIR}/META-INF/lib
-)
-
add_dependencies(${JAR_FILE}.libs-in-jar ${NATIVE_LIBS})
=== added file 'sikuli-script/src/main/native/MacHotkeyManager.cc'
--- sikuli-script/src/main/native/MacHotkeyManager.cc 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/native/MacHotkeyManager.cc 2011-08-21 03:38:17 +0000
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+#include "org_sikuli_script_internal_hotkey_MacHotkeyManager.h"
+
+#include <Carbon/Carbon.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include<iostream>
+#include<map>
+
+#include "sikuli-debug.h"
+
+using namespace std;
+using namespace sikuli;
+
+#define HOTKEY_LISTENER_METHOD "hotkeyPressed"
+#define HOTKEY_LISTENER_SIGNATURE "(Lorg/sikuli/script/HotkeyEvent;)V"
+#define HOTKEY_EVENT_CLASS "org/sikuli/script/HotkeyEvent"
+
+struct CallbackData {
+ JavaVM *vm;
+ int hotkey, mods;
+ int jHotkey, jModifiers;
+ jobject listener;
+ EventHotKeyRef ref;
+ EventHotKeyID id;
+
+ CallbackData(JavaVM *vm_, int hotkey_, int mods_, jobject listener_){
+ vm = vm_;
+ hotkey = hotkey_;
+ mods = mods_;
+ listener = listener_;
+ }
+};
+
+jobject CallbackDataToHotkeyEvent(JNIEnv* env, CallbackData* data){
+ jclass clsHkEvent = env->FindClass(HOTKEY_EVENT_CLASS);
+ jobject ret = env->AllocObject(clsHkEvent);
+ jmethodID initMethod = env->GetMethodID(clsHkEvent, "init", "(II)V");
+ env->CallVoidMethod(ret, initMethod, data->jHotkey, data->jModifiers);
+ env->DeleteLocalRef(clsHkEvent);
+ return ret;
+}
+
+
+
+void callJavaMethod(JavaVM *jvm, jobject listener, CallbackData* data){
+ JNIEnv *env;
+ jvm->GetEnv((void**)&env, JNI_VERSION_1_4);
+ jvm->AttachCurrentThread((void **)&env, NULL);
+ jclass cls = env->GetObjectClass(listener);
+ jmethodID mid = env->GetMethodID(cls, HOTKEY_LISTENER_METHOD, HOTKEY_LISTENER_SIGNATURE);
+ if( mid == NULL ){
+ cerr << "Callback method not found." << endl;
+ return;
+ }
+ jobject hkEvent = CallbackDataToHotkeyEvent(env, data);
+ env->CallVoidMethod(listener, mid, hkEvent);
+}
+
+static map<int, CallbackData*> regHotkeys;
+static int gHotkeyId = 0;
+
+OSStatus shortcutHandler( EventHandlerCallRef inCaller, EventRef inEvent,
+ void* args )
+{
+ EventHotKeyID hkId;
+ GetEventParameter(inEvent, kEventParamDirectObject, typeEventHotKeyID, NULL,
+ sizeof(hkId), NULL, &hkId);
+ CallbackData *data = regHotkeys[hkId.id];
+ int hotkey = data->hotkey;
+ dout("MacHotkeyManager") << "shortcut pressed. " << hotkey << endl;
+ callJavaMethod(data->vm, data->listener, data);
+ return noErr;
+}
+
+
+bool unregisterHotkey(CallbackData *data){
+ map<int, CallbackData*>::iterator it;
+ for(it = regHotkeys.begin(); it != regHotkeys.end(); ++it){
+ CallbackData *itdata = it->second;
+ if( itdata->hotkey == data->hotkey && itdata->mods == data->mods){
+ UnregisterEventHotKey(itdata->ref);
+ data->id = itdata->id;
+ data->ref = itdata->ref;
+ regHotkeys.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool installShortcutHandler( CallbackData *data ){
+ EventTypeSpec shortcutEvents[] = {
+ { kEventClassKeyboard, kEventHotKeyPressed },
+ };
+
+ if(gHotkeyId == 0){
+ OSErr err = InstallApplicationEventHandler( &shortcutHandler,
+ GetEventTypeCount(shortcutEvents), shortcutEvents, NULL, NULL);
+ if (err != noErr)
+ cerr << "InstallApplicationEventHandler failed" << endl;
+ }
+
+ bool registered = unregisterHotkey(data);
+ if(!registered){
+ data->id.id = gHotkeyId++;
+ data->id.signature='htk1';
+ }
+
+ OSStatus err = RegisterEventHotKey(data->hotkey, data->mods,
+ data->id, GetApplicationEventTarget(), 0,
+ &(data->ref));
+ if(!err){
+ regHotkeys[data->id.id] = data;
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: installGlobalHotkey
+ * Signature: (IIIILorg/sikuli/script/internal/hotkey/HotkeyListener;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_installGlobalHotkey
+(JNIEnv *env, jobject jobj, jint jHotkey, jint jModifiers, jint hotkey, jint modifiers, jobject listener){
+ dout("MacHotkeyManager") << "install global hotkey: " << hotkey << " mod: " << modifiers << endl;
+ JavaVM* vm = NULL;
+ env->GetJavaVM(&vm);
+ jobject gListener = env->NewGlobalRef(listener);
+ env->DeleteLocalRef(listener);
+ CallbackData *data = new CallbackData(vm, hotkey, modifiers, gListener);
+ data->jHotkey = jHotkey;
+ data->jModifiers = jModifiers;
+ return installShortcutHandler(data);
+}
+
+
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: uninstallGlobalHotkey
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_uninstallGlobalHotkey
+(JNIEnv *env, jobject jobj, jint hotkey, jint modifiers){
+ CallbackData *data = new CallbackData(NULL, hotkey, modifiers, NULL);
+ return unregisterHotkey(data);
+}
+
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: cleanUp
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_cleanUp
+(JNIEnv *env, jobject jobj){
+ map<int, CallbackData*>::iterator it;
+ for(it = regHotkeys.begin(); it != regHotkeys.end(); ++it){
+ CallbackData *itdata = it->second;
+ UnregisterEventHotKey(itdata->ref);
+ }
+ regHotkeys.clear();
+ gHotkeyId = 0;
+}
=== added file 'sikuli-script/src/main/native/org_sikuli_script_internal_hotkey_MacHotkeyManager.h'
--- sikuli-script/src/main/native/org_sikuli_script_internal_hotkey_MacHotkeyManager.h 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/native/org_sikuli_script_internal_hotkey_MacHotkeyManager.h 2011-08-21 03:38:17 +0000
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_sikuli_script_internal_hotkey_MacHotkeyManager */
+
+#ifndef _Included_org_sikuli_script_internal_hotkey_MacHotkeyManager
+#define _Included_org_sikuli_script_internal_hotkey_MacHotkeyManager
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_CMD
+#define org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_CMD 256L
+#undef org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_SHIFT
+#define org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_SHIFT 512L
+#undef org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_OPT
+#define org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_OPT 2048L
+#undef org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_CTRL
+#define org_sikuli_script_internal_hotkey_MacHotkeyManager_CARBON_MASK_CTRL 4096L
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: installGlobalHotkey
+ * Signature: (IIIILorg/sikuli/script/HotkeyListener;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_installGlobalHotkey
+ (JNIEnv *, jobject, jint, jint, jint, jint, jobject);
+
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: uninstallGlobalHotkey
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_uninstallGlobalHotkey
+ (JNIEnv *, jobject, jint, jint);
+
+/*
+ * Class: org_sikuli_script_internal_hotkey_MacHotkeyManager
+ * Method: cleanUp
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_sikuli_script_internal_hotkey_MacHotkeyManager_cleanUp
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
=== modified file 'sikuli-script/src/main/native/sikuli-debug.cpp'
--- sikuli-script/src/main/native/sikuli-debug.cpp 2011-05-05 15:04:08 +0000
+++ sikuli-script/src/main/native/sikuli-debug.cpp 2011-08-21 03:38:17 +0000
@@ -23,16 +23,16 @@
}
std::ostream& sikuli::dout(const char* name){
-#ifdef ENABLE_OCR_DEBUG
- return cout;
+#ifdef SHOW_DEBUG_MESSAGE
+ return cerr << "[" << name << "] ";
#else
return null_out;
#endif
}
std::ostream& sikuli::dhead(const char* name){
-#ifdef ENABLE_OCR_DEBUG
- return cout << "[" << name << "] ";
+#ifdef SHOW_DEBUG_MESSAGE
+ return cerr << "[" << name << "]\n----------------------------\n";
#else
return null_out;
#endif
=== added file 'sikuli-script/src/main/python/sikuli/Env.py'
--- sikuli-script/src/main/python/sikuli/Env.py 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/main/python/sikuli/Env.py 2011-08-21 03:38:17 +0000
@@ -0,0 +1,15 @@
+# Copyright 2010-2011, Sikuli.org
+# Released under the MIT License.
+from org.sikuli.script import Env as JEnv
+from org.sikuli.script import HotkeyListener
+
+class Env(JEnv):
+
+ @classmethod
+ def addHotkey(cls, key, modifiers, handler):
+ class AnonyListener(HotkeyListener):
+ def hotkeyPressed(self, event):
+ handler(event)
+ return JEnv.addHotkey(key, modifiers, AnonyListener())
+
+
=== modified file 'sikuli-script/src/main/python/sikuli/Sikuli.py'
--- sikuli-script/src/main/python/sikuli/Sikuli.py 2011-06-28 22:14:07 +0000
+++ sikuli-script/src/main/python/sikuli/Sikuli.py 2011-08-21 03:38:17 +0000
@@ -22,7 +22,6 @@
from org.sikuli.script import Finder
from org.sikuli.script import Location
from org.sikuli.script import Settings
-from org.sikuli.script import Env
from org.sikuli.script import OS
from org.sikuli.script import App
from org.sikuli.script import ScreenHighlighter
@@ -36,6 +35,7 @@
from Screen import *
from VDict import *
from Helper import *
+from Env import *
import SikuliImporter
_si = SikuliScript()
=== added file 'sikuli-script/src/test/java/org/sikuli/script/HotkeyTest.java'
--- sikuli-script/src/test/java/org/sikuli/script/HotkeyTest.java 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/test/java/org/sikuli/script/HotkeyTest.java 2011-08-21 03:38:17 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010-2011, Sikuli.org
+ * Released under the MIT License.
+ *
+ */
+package org.sikuli.script;
+
+import org.junit.* ;
+import static org.junit.Assert.* ;
+
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JFrame;
+
+import org.sikuli.script.internal.hotkey.HotkeyManager;
+import org.sikuli.script.HotkeyListener;
+import org.sikuli.script.HotkeyEvent;
+import org.sikuli.script.Debug;
+
+public class HotkeyTest
+{
+ public boolean pressed = false;
+
+
+ private void sleep(double secs){
+ int count = 0;
+ while(count < secs*10){
+ try{
+ Thread.sleep(100);
+ count++;
+ }
+ catch(InterruptedException e){}
+ }
+ }
+
+ //@Ignore("ignore this in automated test")
+ @Test
+ public void test_hotkey_install()
+ {
+ JFrame f = new JFrame("hello"); // need this to hook in the event loop
+ boolean ret = Env.addHotkey(Key.F6, 0,
+ new HotkeyListener(){
+ public void hotkeyPressed(HotkeyEvent e){
+ HotkeyTest.this.pressed = true;
+ Debug.log("hotkey pressed!" + e.keyCode + ", " + e.modifiers);
+ }
+ });
+ Debug.log("install hotkey F6: " + ret);
+ ret = Env.addHotkey('2', KeyModifier.ALT,
+ new HotkeyListener(){
+ public void hotkeyPressed(HotkeyEvent e){
+ HotkeyTest.this.pressed = true;
+ Debug.log("hotkey 2 pressed!");
+ }
+ });
+ Debug.log("install hotkey ALT-2: " + ret);
+ Debug.log("press the hot key now.");
+ sleep(5);
+ ret = Env.removeHotkey(Key.F6, 0);
+ Debug.log("remove hotkey F6: " + ret);
+ Debug.log("press the hot key again.");
+ sleep(2);
+ ret = Env.addHotkey(Key.F7, 0,
+ new HotkeyListener(){
+ public void hotkeyPressed(HotkeyEvent e){
+ HotkeyTest.this.pressed = true;
+ Debug.log("hotkey 3 pressed!" + e.keyCode + ", " + e.modifiers);
+ }
+ });
+ Debug.log("install hotkey F7: " + ret);
+ Debug.log("press the hot key now.");
+ sleep(3);
+ //hkm.cleanUp();
+ }
+
+ public static void main(String args[]){
+ (new HotkeyTest()).test_hotkey_install();
+ }
+}
+
=== added file 'sikuli-script/src/test/python/test_hotkey.py'
--- sikuli-script/src/test/python/test_hotkey.py 1970-01-01 00:00:00 +0000
+++ sikuli-script/src/test/python/test_hotkey.py 2011-08-21 03:38:17 +0000
@@ -0,0 +1,46 @@
+import unittest
+from sikuli import *
+from java.awt.event import KeyEvent
+from javax.swing import JFrame
+
+not_pressed = True
+WAIT_TIME = 4
+
+def pressed(event):
+ global not_pressed
+ not_pressed = False
+ print "hotkey pressed! %d %d" %(event.modifiers,event.keyCode)
+
+class TestHotkey(unittest.TestCase):
+ def testAddHotkey(self):
+ self.assertTrue(Env.addHotkey(Key.F6, 0, pressed))
+
+ def testAddHotkeyReal(self):
+ #f = JFrame("hello")
+ global not_pressed
+ Env.addHotkey(Key.F6, 0, pressed)
+ self.assertTrue(not_pressed)
+ count = 0
+ while not_pressed and count < WAIT_TIME:
+ count += 1
+ wait(1)
+ keyDown(Key.F6)
+ keyUp(Key.F6)
+ self.assertFalse(not_pressed)
+ #f.dispose()
+
+ def testRemoveHotkey(self):
+ self.assertFalse(Env.removeHotkey(Key.F7, 0))
+ self.assertTrue(Env.addHotkey(Key.F7, 0, pressed))
+ self.assertTrue(Env.removeHotkey(Key.F7, 0))
+
+
+ def setUp(self):
+ global not_pressed
+ not_pressed = True
+
+ @classmethod
+ def tearDownClass(self):
+ print "clean up"
+ Env.cleanUp()
+