diff --git a/JIntellitype.dll b/JIntellitype.dll new file mode 100644 index 0000000..839236b Binary files /dev/null and b/JIntellitype.dll differ diff --git a/JIntellitype64.dll b/JIntellitype64.dll new file mode 100644 index 0000000..6dc2680 Binary files /dev/null and b/JIntellitype64.dll differ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..f91da00 --- /dev/null +++ b/license.txt @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..34efae0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,302 @@ + + 4.0.0 + com.melloware + jintellitype + jar + 1.3.5 + http://www.melloware.com + JIntellitype + JNI Java bridge to Microsoft Intellitype commands. + + Melloware Inc + http://www.melloware.com + + + http://melloware.com/images/header.jpg + + 1999 + + scm:svn:https://jintellitype.googlecode.com/svn/trunk/ + scm:svn:https://jintellitype.googlecode.com/svn/trunk/ + scm:svn:https://jintellitype.googlecode.com/svn/trunk/ + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + mellowaredev@gmail.com + Melloware + mellowaredev@gmail.com + http://www.melloware.com + Melloware Inc + http://www.melloware.com + + Architect + + + + + + Bertrand Florat + bflorat@users.sourceforge.net + http://jajuk.info + Jajuk Team + http://jajuk.info + + Code Contributor + + + + Peter Fichtner + fichtner@c2tn.de + http://www.c2tn.de + C2TN Team + http://www.c2tn.de + + Code Contributor + + + + Thomas Beckers + + http://www.atunes.org/ + aTunes Team + http://www.atunes.org/ + + Code Contributor + + + + Karl von Randow + + http://xk72.com/ + XK72 + http://xk72.com/ + + Code Contributor + + + + Johannes Frank + + http://radis.sf.net/ + RadiS + http://radis.sf.net/ + + Code Contributor + + + + Wordoholic + + http://wordoholic.com/ + Wordoholic + http://wordoholic.com/ + + Code Contributor + + + + Zeroflag + + + ZeroFlag + + + x64 DLL Contributor + + + + Lars + + + Hamburg + + + Strings for Register Hotkeys + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + maven-assembly-plugin + + + + com.melloware.jintellitype.Main + + + + src/assembly/descriptor.xml + + target/assembly + target/assembly/work + + + + make-assembly + package + + assembly + + + + + + + maven-jar-plugin + + + + com.melloware.jintellitype.Main + + + ${pom.url} + ${project.artifactId} + ${project.organization.name} + ${project.organization.name} + ${project.description} + ${project.version} + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + + true + true + true + + + + maven-surefire-plugin + org.apache.maven.plugins + + true + + + + org.apache.maven.plugins + maven-changes-plugin + + + validate-changes + pre-site + + changes-validate + + + true + + + + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + + summary + dependencies + dependency-convergence + project-team + license + + + + + + org.apache.maven.plugins + maven-jxr-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + http://java.sun.com/j2se/1.4.2/docs/api + + false + + + + org.apache.maven.plugins + maven-pmd-plugin + + + /rulesets/basic.xml + /rulesets/imports.xml + /rulesets/unusedcode.xml + /rulesets/finalizers.xml + /rulesets/logging-jakarta-commons.xml + /rulesets/logging-java.xml + /rulesets/migrating_to_15.xml + /rulesets/design.xml + /rulesets/strings.xml + + 150 + true + utf-8 + 1.6 + + + + org.codehaus.mojo + taglist-maven-plugin + + + TODO + @todo + FIXME + XXX + + + + + org.apache.maven.plugins + maven-changes-plugin + + + + changes-report + + + + + + + + + melloware + melloware + ${distribution.url} + + + melloware + JIntellitype Website + scp://www.melloware.com/products/jintellitype + + + \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..d65b444 --- /dev/null +++ b/readme.txt @@ -0,0 +1,129 @@ +JIntellitype Read Me +http://www.melloware.com/ + +Copyright 1999-2010 Emil A. Lefkof III + +Licensed 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. + +Contents +-------- +1. Overview +2. Features +3. Installation +4. Quick Usage +5. Acknowledgements +6. Feedback + +1. Overview + -------- + JIntellitype is an API for interacting with Microsoft Intellitype keyboard + commands as well as registering for Global Hotkeys in your application. + The API is a Java JNI library that uses a DLL to do all the communication + with Windows. This library ONLY works on Windows. + + Have you ever wanted to have CTRL+SHIFT+G maximize your Swing application + on the desktop even if that application did not have focus? Now you can by + registering a Windows Hotkey combination your application will be alerted + when the combination you select is pressed anywhere in Windows. + + Have you ever wanted to react to those special Play, Pause, Stop keys on some + Microsoft and Logitech keyboards? Even some laptops now have those special + keys built in and if you want your application to "listen" for them, now you + can! + + +2. Features + -------- + -> Can register global hotkey combinations in Windows + -> Application is notified even if it does not have focus. + -> Can react to those Play, Pause, Stop, Next, Forward Media keys like Winamp + -> Very little code, easy to use API + -> Examples included in JIntellitypeTester.java + +3. Installation + ------------ + + FOR USERS: + -> Copy the following files into your classpath + -> jintellitype.jar + -> JIntellitype.dll (or put in Windows/System32) + -> JIntellitype64.dll (rename to JIntellitype.dll and put in path) + + FOR DEVELOPERS: + -> To build you need Maven 2.0.7 or higher installed from Apache. Just run "mvn package" from the + directory where the pom.xml is located to build the project. + + -> To build the C++ code you need Bloodshed C++ IDE. When you load the .dev project included do not + forget to edit Project->Options and under Directories Tab change the Includes directory to contain + both: + /java5/include + /java5/include/win32 + + Where "java5" is the location of your Java JDK. + + +4. Quick Usage + ------------ + +// Create JIntellitype + ... + JIntellitype.getInstance().addHotKeyListener(new HotKeyListener() {...); + JIntellitype.getInstance().addIntellitypeListener(new IntellitypeListener() {...); + ... + +// Assign global hotkeys to Windows+A and ALT+SHIFT+B + JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_WIN, (int)'A'); + JIntellitype.getInstance().registerHotKey(2, JIntellitype.MOD_ALT + JIntellitype.MOD_SHIFT, (int)'B'); + +// listen for hotkey + public void onHotKey(int aIdentifier) { + if (aIdentifier == 1) + System.out.println("WINDOWS+A hotkey pressed"); + } + } + +// listen for intellitype play/pause command + public void onIntellitype(int aCommand) { + switch (aCommand) { + case JIntellitype.APPCOMMAND_MEDIA_PLAY_PAUSE: + System.out.println("Play/Pause message received " + Integer.toString(aCommand)); + break; + default: + System.out.println("Undefined INTELLITYPE message caught " + Integer.toString(aCommand)); + break; + } + } + +// Termination + ... + JIntellitype.getInstance().cleanUp(); + System.exit(0); + + + +See demo at test/com/melloware/jintellitype/JIntellitypeTester.java for more info.. + +5. Acknowledgements + ---------------- + JIntellitype is distributed with a small number of libraries on which it depends. + Those libraries are: + + -> None currently + +6. Feedback + -------- + Your feedback on JIntellitype (hopefully constructive) is always welcome. Please + visit http://www.melloware.com/ for links to browse and join mailing + lists, file bugs and submit feature requests. + + Also a forum is set up at http://forum.melloware.com/index.php for discussion. diff --git a/src/assembly/descriptor.xml b/src/assembly/descriptor.xml new file mode 100644 index 0000000..0f6f4a1 --- /dev/null +++ b/src/assembly/descriptor.xml @@ -0,0 +1,35 @@ + + dist + + zip + + + + target + + + *.jar + + + + src\main + + **/.svn/** + + + + src\test + + **/.svn/** + + + + + *.dll + pom.xml + readme.txt + license.txt + + + + \ No newline at end of file diff --git a/src/changes/changes.xml b/src/changes/changes.xml new file mode 100644 index 0000000..0d4cd5d --- /dev/null +++ b/src/changes/changes.xml @@ -0,0 +1,102 @@ + + + + + + Release Notes + Melloware + + + + + + Modified JIntellitype.java a bit so that it would a)copy .dll files from jar to a temp location and b)load 64bit .dll if 32bit fails. Tested on WinXP 32bit and Win7 64bit (with 64bit JVM). + + + + + Now enables the user to use all keys instead of just [A-Z],[0-9] as before + + + + + Added JIntellitype64.dll for 64 bit JRE's. Simply rename the DLL to + JIntellitype.dll or use the Jintellitype.setLibraryLocation(''); function + to set the path to JIntellitype64.dll. + + + + + Fixed "Jintellitype.setLibraryLocation('');" method to to allow developers + to set the path of the JIntellitype.DLL for use in executable jar's etc. + + + Removed Commons-Logging dependency + + + + + Fixed "Jintellitype.swingToIntelliType()" method to handle both the old + style and new style Swing/AWT modifiers. Such as the older InputEvent.SHIFT_MASK + and the newer InputEvent.SHIFT_DOWN_MASK will both return the SHIFT + modifier. + + + + + Found and fixed race condition in C DLL that was causing the problem of being + able to only register one hotkey at a time. + + + Fixed "on" methods to be synchronized and added properly. + + + Added isJintellitypeSupported() method which checks the DLL is in the path + and the operating System is Windows and its a 32 bit JDK since it will + not run on 64 bit JVM. + + + + + Added Javadoc that explains a modifier of 0 means that no modifier is required if you + want to have a single key be a hotkey. + + + Added example of just using the PRINT_SCREEN key with no modifiers as a hotkey. + + + Added more constants to JIntellitypeConstants.java based on MSDN documentation. + + + Made JIntellitype singleton thread safe by using double checked pattern. + + + + + Added registerHotKey(int identifier, String modifierAndKeyCode) to allow Strings like "CTRL+A" to be + used to register hotkeys for applications that want their users to be able to define hotkeys. + + + Added checkInstanceAlreadyRunning(String appTitle) to prevent multiple instances + of your application from being started if you don't want to. Returns true + if an instance with this application title is already running on the system. + Useful for developers who only want ONE instance of their app running. + + + + + Changed Jintellitype to a singleton class like JIntellitype.getInstance() + + + Added ability to use Swing constants for ALT, CTRL, SHIFT. + + + + + Initial release of the JIntellitype API. + + + + + + \ No newline at end of file diff --git a/src/main/cpp/JIntellitype.cpp b/src/main/cpp/JIntellitype.cpp new file mode 100644 index 0000000..060b2d5 --- /dev/null +++ b/src/main/cpp/JIntellitype.cpp @@ -0,0 +1,157 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed 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. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "com_melloware_jintellitype_JIntellitype.h" +#include "JIntellitypeHandler.h" + +HINSTANCE g_instance = NULL; + + +BOOL WINAPI DllMain +( + HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpvReserved // reserved +) +{ + switch( fdwReason ) + { + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + + case DLL_PROCESS_ATTACH: + g_instance = hinstDLL; + + break; + } + return TRUE; +} + + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: initializeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_initializeLibrary + (JNIEnv *env, jobject object) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + // Create our handler + l_handler = new JIntellitypeHandler( env, object ); + + // Enable it + if( l_handler ) + l_handler->initialize(env, g_instance); +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: regHotKey + * Signature: (III)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_regHotKey + (JNIEnv *env, jobject object, jint identifier, jint modifier, jint keycode) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + if( l_handler ) + { + l_handler->regHotKey(identifier, modifier, keycode); + } + else + { + // throw exception + jclass JIntellitypeException = env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + env->ThrowNew(JIntellitypeException,"JIntellitype was not initialized properly."); + } +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: unregHotKey + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_unregHotKey + (JNIEnv *env, jobject object, jint identifier) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + if( l_handler ) + { + l_handler->unregHotKey(identifier); + } + else + { + // throw exception + jclass JIntellitypeException = env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + env->ThrowNew(JIntellitypeException,"JIntellitype was not initialized properly."); + } + +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: terminate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_terminate + (JNIEnv *env, jobject object) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + // Clean up all resources allocated by this API + if( l_handler ) + l_handler->terminate(); + +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: isRunning + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_melloware_jintellitype_JIntellitype_isRunning + (JNIEnv *env, jclass, jstring wndName) +{ + // App name for the hidden window's registered class + CHAR szAppName[] = "SunAwtFrame"; + const char *cWndName = env->GetStringUTFChars(wndName, 0); + // Find out if there's a hidden window with the given title + HWND mHwnd = FindWindow(szAppName, cWndName); + env->ReleaseStringUTFChars(wndName, cWndName); + // If there is, another instance of our app is already running + return mHwnd != NULL; +} + diff --git a/src/main/cpp/JIntellitype.dev b/src/main/cpp/JIntellitype.dev new file mode 100644 index 0000000..62fa7e1 --- /dev/null +++ b/src/main/cpp/JIntellitype.dev @@ -0,0 +1,149 @@ +[Project] +FileName=JIntellitype.dev +Name=JIntellitype +Ver=1 +IsCpp=1 +Type=3 +Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DBUILDING_DLL=1_@@_ +CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL_@@_ +Includes=c:\java\jdk1.2.2\include;c:\java\jdk1.2.2\include\win32 +Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 --no-export-all-symbols --add-stdcall-alias_@@_ +Libs= +UnitCount=8 +Folders="Header Files","Resource Files","Source Files" +ObjFiles= +PrivateResource=JIntellitype_private.rc +ResourceIncludes= +MakeIncludes= +Icon= +ExeOutput=..\..\..\..\jintellitype +ObjectOutput=..\..\..\target +OverrideOutput=0 +OverrideOutputName=JIntellitype.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=1 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000001001000000100 + +[Unit1] +FileName=JIntellitypeThread.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=JIntellitype.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=JIntellitypeHandler.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=JIntellitypeHandler.h +Folder="Header Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=StdAfx.h +Folder="Header Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=com_melloware_jintellitype_JIntellitype.h +Folder=Header Files +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=465 +LanguageID=1033 +CharsetID=1252 +CompanyName=Melloware Inc (www.melloware.com) +FileVersion=1.0 +FileDescription=Java JNI bridge to MS Intellitype commands +InternalName= +LegalCopyright=Copyright 2006 Melloware Inc +LegalTrademarks=Copyright 2006 Melloware Inc +OriginalFilename= +ProductName=JIntellitype +ProductVersion=1.0 +AutoIncBuildNr=1 + +[Unit11] +FileName=com_melloware_jintellitype_JIntellitype.h +CompileCpp=1 +Folder=Header Files +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=com_melloware_jintellitype_JIntellitype.h +CompileCpp=1 +Folder=Header Files +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=StdAfx.cpp +CompileCpp=1 +Folder="Source Files" +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=JIntellitypeThread.h +CompileCpp=1 +Folder="Header Files" +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/main/cpp/JIntellitype.layout b/src/main/cpp/JIntellitype.layout new file mode 100644 index 0000000..6956056 --- /dev/null +++ b/src/main/cpp/JIntellitype.layout @@ -0,0 +1,76 @@ +[Editor_9] +CursorCol=1 +CursorRow=20 +TopLine=1 +LeftChar=1 +Open=0 +Top=0 +[Editors] +Focused=2 +Order=1,2,0,7,4 +[Editor_0] +Open=1 +Top=0 +CursorCol=5 +CursorRow=118 +TopLine=71 +LeftChar=1 +[Editor_1] +Open=1 +Top=0 +CursorCol=36 +CursorRow=149 +TopLine=75 +LeftChar=1 +[Editor_2] +Open=1 +Top=1 +CursorCol=14 +CursorRow=209 +TopLine=162 +LeftChar=1 +[Editor_3] +Open=0 +Top=0 +CursorCol=23 +CursorRow=3 +TopLine=1 +LeftChar=1 +[Editor_4] +Open=1 +Top=0 +CursorCol=1 +CursorRow=27 +TopLine=1 +LeftChar=1 +[Editor_5] +Open=0 +Top=0 +CursorCol=3 +CursorRow=24 +TopLine=11 +LeftChar=1 +[Editor_6] +Open=0 +Top=0 +CursorCol=1 +CursorRow=16 +TopLine=1 +LeftChar=1 +[Editor_7] +Open=1 +Top=0 +CursorCol=54 +CursorRow=35 +TopLine=3 +LeftChar=1 +[Editor_8] +Open=0 +Top=0 +CursorCol=1 +CursorRow=3 +TopLine=1 +LeftChar=1 +[Editor_10] +Open=0 +Top=0 diff --git a/src/main/cpp/JIntellitypeHandler.cpp b/src/main/cpp/JIntellitypeHandler.cpp new file mode 100644 index 0000000..666fc5d --- /dev/null +++ b/src/main/cpp/JIntellitypeHandler.cpp @@ -0,0 +1,279 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed 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. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "JIntellitypeHandler.h" +#include "JIntellitypeThread.h" +#include + + +UINT WM_SHELLHOOK = 0; + +/* + * Extract the unique handlerID from the java object + */ +JIntellitypeHandler *JIntellitypeHandler::extract( JNIEnv *env, jobject object ) +{ + // Get field ID + jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( object ), "handler", "I" ); + + // Get field + JIntellitypeHandler *l_handler = (JIntellitypeHandler *) env->GetIntField( object, l_handlerId ); + + return l_handler; +} + +/* + * Constructor + */ +JIntellitypeHandler::JIntellitypeHandler( JNIEnv *env, jobject object ) +{ + m_window = NULL; + + // Reference object + m_object = env->NewGlobalRef(object ); + + // Get method IDs + m_fireHotKey = env->GetMethodID( env->GetObjectClass( m_object ) , "onHotKey", "(I)V" ); + m_fireIntellitype = env->GetMethodID( env->GetObjectClass( m_object ) , "onIntellitype", "(I)V" ); + + // Get field ID + jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( m_object ) , "handler", "I" ); + + // Set field + env->SetIntField( m_object, l_handlerId, (jint) this ); +} + +/* + * Destructor + */ +JIntellitypeHandler::~JIntellitypeHandler() +{ + // Get field ID + jfieldID l_handlerId = g_JIntellitypeThread.m_env->GetFieldID( g_JIntellitypeThread.m_env->GetObjectClass( m_object ), "handler", "I" ); + + // Set field + g_JIntellitypeThread.m_env->SetIntField( m_object, l_handlerId, 0 ); + + // Release our reference + g_JIntellitypeThread.m_env->DeleteGlobalRef( m_object ); + + // unregister the shell hook + DeregisterShellHookWindow( m_window ); + + // Destroy window + DestroyWindow( m_window ); +} + + +/* + * Perform initialization of the object and thread. + */ +void JIntellitypeHandler::initialize( JNIEnv *env, HINSTANCE instance ) +{ + m_instance = instance; + g_JIntellitypeThread.MakeSureThreadIsUp( env ); + while( !PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, INITIALIZE_CODE, (LPARAM) this ) ) + Sleep( 0 ); +} + +/* + * Callback method that creates the hidden window on initialization to receive + * any WM_HOTKEY messages and process them. + */ +void JIntellitypeHandler::doInitialize() +{ + // Register window class + WNDCLASSEX l_Class; + l_Class.cbSize = sizeof( l_Class ); + l_Class.style = CS_HREDRAW | CS_VREDRAW; + l_Class.lpszClassName = TEXT( "JIntellitypeHandlerClass" ); + l_Class.lpfnWndProc = WndProc; + l_Class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + l_Class.hCursor = NULL; + l_Class.hIcon = NULL; + l_Class.hIconSm = NULL; + l_Class.lpszMenuName = NULL; + l_Class.cbClsExtra = 0; + l_Class.cbWndExtra = 0; + l_Class.hInstance = m_instance; + + if( !RegisterClassEx( &l_Class ) ) + return; + + // Create window + m_window = CreateWindow + ( + TEXT( "JIntellitypeHandlerClass" ), + TEXT( "JIntellitypeHandler" ), + WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, + NULL, + NULL, + m_instance, + NULL + ); + + if( !m_window ) + return; + + //Set pointer to this object inside the Window's USERDATA section + SetWindowLong( m_window, GWL_USERDATA, (LONG) this ); + + // hide the window + ShowWindow(m_window, SW_HIDE); + UpdateWindow(m_window); + + //register this window as a shell hook to intercept WM_APPCOMMAND messages + WM_SHELLHOOK = RegisterWindowMessage(TEXT("SHELLHOOK")); + BOOL (__stdcall *RegisterShellHookWindow)(HWND) = NULL; + RegisterShellHookWindow = (BOOL (__stdcall *)(HWND))GetProcAddress(GetModuleHandle("USER32.DLL"), "RegisterShellHookWindow"); + + //make sure it worked + if (!RegisterShellHookWindow(m_window)) { + // throw exception + jclass JIntellitypeException = g_JIntellitypeThread.m_env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + g_JIntellitypeThread.m_env->ThrowNew(JIntellitypeException,"Could not register window as a shell hook window."); + } +} + +/* + * Registers a hotkey. + * identifier - unique identifier assigned to this key comination + * modifier - ALT, SHIFT, CTRL, WIN or combination of + * keycode- Ascii keycode, 65 for A, 66 for B etc + */ +void JIntellitypeHandler::regHotKey( jint identifier, jint modifier, jint keycode ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->identifier = identifier; + callback->modifier = modifier; + callback->keycode = keycode; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, REGISTER_HOTKEY_CODE, (LPARAM) callback ); +} + +/* + * Actually registers the hotkey using the Win32API RegisterHotKey call. + */ +void JIntellitypeHandler::doRegHotKey(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + RegisterHotKey(m_window, callback->identifier, callback->modifier, callback->keycode); + free(callback); +} + +/* + * Unregisters a previously assigned hotkey. + * identifier - unique identifier assigned to this key comination + */ +void JIntellitypeHandler::unregHotKey( jint identifier ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->identifier = identifier; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, UNREGISTER_HOTKEY_CODE, (LPARAM) callback ); +} + +/* + * Actually unregisters the hotkey using the Win32API UnregisterHotKey call. + */ +void JIntellitypeHandler::doUnregisterHotKey(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + UnregisterHotKey(m_window, callback->identifier); + free(callback); +} + +/* + * When an intellitype command is recieved by the JFrame this method is called + * to perform a callback to the Intellitype java listeners. + * commandId - the unique command Id from the WM_APPCOMMAND listings + */ +void JIntellitypeHandler::intellitype( jint commandId ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->command = commandId; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, INTELLITYPE_CODE, (LPARAM) callback ); +} + +/* + * Call the correct JVM with the intellitype command for the listeners listening. + */ +void JIntellitypeHandler::doIntellitype(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + g_JIntellitypeThread.m_env->CallVoidMethod(m_object, m_fireIntellitype, callback->command); + free(callback); +} + +/* + * Cleans up resources allocated by JIntellitype. + */ +void JIntellitypeHandler::terminate() +{ + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, TERMINATE_CODE, (LPARAM) this ); +} + +/* + * Callback method to send hotkey to the Java HotKeyListeners registered. + */ +void JIntellitypeHandler::fireHotKey(jint hotkeyId) +{ + g_JIntellitypeThread.m_env->CallVoidMethod(m_object, m_fireHotKey, hotkeyId); +} + + +/* + * WndProc method registered to the hidden window to listen for WM_HOTKEY + * messages and send them back to the Java listeners. + */ +LRESULT CALLBACK JIntellitypeHandler::WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ) +{ + + // check for Intellitype messages and if found send them to Intellitype listeners + if (uMessage == WM_SHELLHOOK) { + if (wParam == HSHELL_APPCOMMAND) { + jint cmd = GET_APPCOMMAND_LPARAM(lParam); + JIntellitypeHandler *l_this = (JIntellitypeHandler *) GetWindowLong( hWnd, GWL_USERDATA ); + l_this->intellitype(cmd); + } + return TRUE; + } + + // check for registered hotkey messages and send them to HotKeyListeners + switch( uMessage ) { + case WM_HOTKEY: { + JIntellitypeHandler *l_this = (JIntellitypeHandler *) GetWindowLong( hWnd, GWL_USERDATA ); + l_this->fireHotKey(wParam); + return TRUE; + break; + } + default: + return DefWindowProc( hWnd, uMessage, wParam, lParam ); + } + +} + + + diff --git a/src/main/cpp/JIntellitypeHandler.h b/src/main/cpp/JIntellitypeHandler.h new file mode 100644 index 0000000..d003ff9 --- /dev/null +++ b/src/main/cpp/JIntellitypeHandler.h @@ -0,0 +1,93 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed 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. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#ifndef __JIntellitypeHandler_h__ +#define __JIntellitypeHandler_h__ + +#include "JIntellitypeThread.h" + +class JIntellitypeHandler +{ + friend DWORD WINAPI JIntellitypeThread::ThreadProc( LPVOID lpParameter ); + +public: + + static JIntellitypeHandler *extract( JNIEnv *env, jobject object ); + + JIntellitypeHandler( JNIEnv *env, jobject object ); + + void initialize( JNIEnv *env, HINSTANCE instance ); + void regHotKey( jint identifier, jint modifier, jint keycode ); + void unregHotKey( jint identifier ); + void intellitype( jint commandId ); + void terminate(); + +private: + + enum + { + INITIALIZE_CODE = 1, + REGISTER_HOTKEY_CODE = 2, + UNREGISTER_HOTKEY_CODE = 3, + TERMINATE_CODE = 4, + INTELLITYPE_CODE = 5 + }; + + ~JIntellitypeHandler(); + + void createHiddenWindow(); + void doInitialize(); + void doRegHotKey(LPARAM callback); + void doUnregisterHotKey(LPARAM callback); + void doIntellitype(LPARAM callback); + void fireHotKey(jint hotkeyId); + void fireIntellitype(jint commandId); + + HINSTANCE m_instance; + HWND m_window; + jobject m_object; + jmethodID m_fireHotKey; + jmethodID m_fireIntellitype; + + static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ); + static DWORD WINAPI ThreadProc( LPVOID lpParameter ); +}; + +typedef struct { + JIntellitypeHandler *handler; + jint identifier; + jint modifier; + jint keycode; + jint command; +} JIntellitypeHandlerCallback; + + +#ifndef WM_APPCOMMAND +#define WM_APPCOMMAND 0x319 +#define FAPPCOMMAND_MASK 0x8000 +#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK)) +#define HSHELL_APPCOMMAND 12 + +#endif + + +#endif diff --git a/src/main/cpp/JIntellitypeThread.cpp b/src/main/cpp/JIntellitypeThread.cpp new file mode 100644 index 0000000..dc55048 --- /dev/null +++ b/src/main/cpp/JIntellitypeThread.cpp @@ -0,0 +1,133 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed 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. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "JIntellitypeThread.h" +#include "JIntellitypeHandler.h" + +JIntellitypeThread g_JIntellitypeThread; + + +JIntellitypeThread::JIntellitypeThread() +{ + m_env = NULL; + m_thread = 0; + m_vm = NULL; + m_handlerCount = 0; +} + + +void JIntellitypeThread::MakeSureThreadIsUp( JNIEnv *env ) +{ + if( !m_thread ) + { + // Get VM + env->GetJavaVM( &m_vm ); + + // Start "native" thread + CreateThread + ( + NULL, + 0, + ThreadProc, + this, + 0, + &m_thread + ); + } +} + + +JIntellitypeThread::operator DWORD () +{ + return m_thread; +} + + +DWORD WINAPI JIntellitypeThread::ThreadProc( LPVOID lpParameter ) +{ + JIntellitypeThread *l_this = (JIntellitypeThread *) lpParameter; + + // Attach the thread to the VM + l_this->m_vm->AttachCurrentThread( (void**) &l_this->m_env, NULL ); + + MSG msg; + while( GetMessage( &msg, NULL, 0, 0 ) ) + { + if( msg.message == WM_JINTELLITYPE ) + { + // Extract handler + JIntellitypeHandler *l_handler; + + switch( msg.wParam ) + { + case JIntellitypeHandler::INITIALIZE_CODE: + l_handler = (JIntellitypeHandler*) msg.lParam; + l_this->m_handlerCount++; + l_handler->doInitialize(); + break; + case JIntellitypeHandler::REGISTER_HOTKEY_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doRegHotKey(msg.lParam); + break; + + case JIntellitypeHandler::UNREGISTER_HOTKEY_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doUnregisterHotKey(msg.lParam); + break; + case JIntellitypeHandler::INTELLITYPE_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doIntellitype(msg.lParam); + break; + + case JIntellitypeHandler::TERMINATE_CODE: + l_handler = (JIntellitypeHandler*) msg.lParam; + + // Destroy it! + delete l_handler; + + // No more handlers? + if( !--l_this->m_handlerCount ) + { + l_this->m_thread = 0; + + // Detach thread from VM + l_this->m_vm->DetachCurrentThread(); + + // Time to die + ExitThread( 0 ); + } + break; + } + } + else + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + } + + // Detach thread from VM + l_this->m_vm->DetachCurrentThread(); + + return 0; +} diff --git a/src/main/cpp/JIntellitypeThread.h b/src/main/cpp/JIntellitypeThread.h new file mode 100644 index 0000000..10b09f9 --- /dev/null +++ b/src/main/cpp/JIntellitypeThread.h @@ -0,0 +1,55 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed 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. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#ifndef __JIntellitypeThread_h__ +#define __JIntellitypeThread_h__ + + +class JIntellitypeThread +{ +public: + + JIntellitypeThread(); + + void MakeSureThreadIsUp( JNIEnv *env ); + + JNIEnv *m_env; + static DWORD WINAPI ThreadProc( LPVOID lpParameter ); + + operator DWORD (); + +private: + + DWORD m_thread; + JavaVM *m_vm; + int m_handlerCount; + + +}; + +extern JIntellitypeThread g_JIntellitypeThread; + + +#define WM_JINTELLITYPE (WM_USER+1) + + +#endif diff --git a/src/main/cpp/JIntellitype_private.h b/src/main/cpp/JIntellitype_private.h new file mode 100644 index 0000000..1c7f45e --- /dev/null +++ b/src/main/cpp/JIntellitype_private.h @@ -0,0 +1,23 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT ! */ + +#ifndef JINTELLITYPE_PRIVATE_H +#define JINTELLITYPE_PRIVATE_H + +/* VERSION DEFINITIONS */ +#define VER_STRING "1.0.0.465" +#define VER_MAJOR 1 +#define VER_MINOR 0 +#define VER_RELEASE 0 +#define VER_BUILD 465 +#define COMPANY_NAME "Melloware Inc (www.melloware.com)" +#define FILE_VERSION "1.0" +#define FILE_DESCRIPTION "Java JNI bridge to MS Intellitype commands" +#define INTERNAL_NAME "" +#define LEGAL_COPYRIGHT "Copyright 2006 Melloware Inc" +#define LEGAL_TRADEMARKS "Copyright 2006 Melloware Inc" +#define ORIGINAL_FILENAME "" +#define PRODUCT_NAME "JIntellitype" +#define PRODUCT_VERSION "1.0" + +#endif /*JINTELLITYPE_PRIVATE_H*/ diff --git a/src/main/cpp/JIntellitype_private.rc b/src/main/cpp/JIntellitype_private.rc new file mode 100644 index 0000000..77374f8 --- /dev/null +++ b/src/main/cpp/JIntellitype_private.rc @@ -0,0 +1,35 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT! */ + +#include // include for version info constants + + +// +// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS... +// +1 VERSIONINFO +FILEVERSION 1,0,0,465 +PRODUCTVERSION 1,0,0,465 +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "Melloware Inc (www.melloware.com)" + VALUE "FileVersion", "1.0" + VALUE "FileDescription", "Java JNI bridge to MS Intellitype commands" + VALUE "InternalName", "" + VALUE "LegalCopyright", "Copyright 2006 Melloware Inc" + VALUE "LegalTrademarks", "Copyright 2006 Melloware Inc" + VALUE "OriginalFilename", "" + VALUE "ProductName", "JIntellitype" + VALUE "ProductVersion", "1.0" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 1252 + } +} + diff --git a/src/main/cpp/Makefile.win b/src/main/cpp/Makefile.win new file mode 100644 index 0000000..0ad1b2c --- /dev/null +++ b/src/main/cpp/Makefile.win @@ -0,0 +1,46 @@ +# Project: JIntellitype +# Makefile created by Dev-C++ 4.9.9.2 + +CPP = g++.exe +CC = gcc.exe +WINDRES = windres.exe +RES = ../../../target/JIntellitype_private.res +OBJ = ../../../target/JIntellitypeThread.o ../../../target/JIntellitype.o ../../../target/JIntellitypeHandler.o ../../../target/StdAfx.o $(RES) +LINKOBJ = ../../../target/JIntellitypeThread.o ../../../target/JIntellitype.o ../../../target/JIntellitypeHandler.o ../../../target/StdAfx.o $(RES) +LIBS = -L"C:/Dev-Cpp/lib" -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 --no-export-all-symbols --add-stdcall-alias -s +INCS = -I"C:/Dev-Cpp/include" +CXXINCS = -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" +BIN = ../../../../jintellitype/JIntellitype.dll +CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -fexpensive-optimizations -O3 +CFLAGS = $(INCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DBUILDING_DLL=1 -fexpensive-optimizations -O3 +RM = rm -f + +.PHONY: all all-before all-after clean clean-custom + +all: all-before ../../../../jintellitype/JIntellitype.dll all-after + + +clean: clean-custom + ${RM} $(OBJ) $(BIN) + +DLLWRAP=dllwrap.exe +DEFFILE=../../../../jintellitype/libJIntellitype.def +STATICLIB=../../../../jintellitype/libJIntellitype.a + +$(BIN): $(LINKOBJ) + $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN) + +../../../target/JIntellitypeThread.o: JIntellitypeThread.cpp + $(CPP) -c JIntellitypeThread.cpp -o ../../../target/JIntellitypeThread.o $(CXXFLAGS) + +../../../target/JIntellitype.o: JIntellitype.cpp + $(CPP) -c JIntellitype.cpp -o ../../../target/JIntellitype.o $(CXXFLAGS) + +../../../target/JIntellitypeHandler.o: JIntellitypeHandler.cpp + $(CPP) -c JIntellitypeHandler.cpp -o ../../../target/JIntellitypeHandler.o $(CXXFLAGS) + +../../../target/StdAfx.o: StdAfx.cpp + $(CPP) -c StdAfx.cpp -o ../../../target/StdAfx.o $(CXXFLAGS) + +../../../target/JIntellitype_private.res: JIntellitype_private.rc + $(WINDRES) -i JIntellitype_private.rc --input-format=rc -o ../../../target/JIntellitype_private.res -O coff diff --git a/src/main/cpp/StdAfx.cpp b/src/main/cpp/StdAfx.cpp new file mode 100644 index 0000000..a10ee7b --- /dev/null +++ b/src/main/cpp/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// win32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/src/main/cpp/StdAfx.h b/src/main/cpp/StdAfx.h new file mode 100644 index 0000000..7203ae8 --- /dev/null +++ b/src/main/cpp/StdAfx.h @@ -0,0 +1,24 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_) +#define AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include + +#include + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_) diff --git a/src/main/cpp/com_melloware_jintellitype_JIntellitype.h b/src/main/cpp/com_melloware_jintellitype_JIntellitype.h new file mode 100644 index 0000000..2394ca6 --- /dev/null +++ b/src/main/cpp/com_melloware_jintellitype_JIntellitype.h @@ -0,0 +1,53 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_melloware_jintellitype_JIntellitype */ + +#ifndef _Included_com_melloware_jintellitype_JIntellitype +#define _Included_com_melloware_jintellitype_JIntellitype +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: initializeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_initializeLibrary + (JNIEnv *, jobject); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: regHotKey + * Signature: (III)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_regHotKey + (JNIEnv *, jobject, jint, jint, jint); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: terminate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_terminate + (JNIEnv *, jobject); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: unregHotKey + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_unregHotKey + (JNIEnv *, jobject, jint); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: isRunning + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_melloware_jintellitype_JIntellitype_isRunning + (JNIEnv *, jclass, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/main/java/com/melloware/jintellitype/HotkeyListener.java b/src/main/java/com/melloware/jintellitype/HotkeyListener.java new file mode 100644 index 0000000..c7bef85 --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/HotkeyListener.java @@ -0,0 +1,46 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed 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. + */ +package com.melloware.jintellitype; + + +/** + * Listener interface for Windows Hotkey events registered using the + * Windows API call RegisterHotKey to globally listen for a key combination + * regardless if your application has focus or not. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + * + * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/registerhotkey.asp + */ +public interface HotkeyListener +{ + /** + * Event fired when a WM_HOTKEY message is received that was initiated + * by this application. + *

+ * @param identifier the unique Identifer the Hotkey was assigned + */ + void onHotKey( int identifier ); +} \ No newline at end of file diff --git a/src/main/java/com/melloware/jintellitype/IntellitypeListener.java b/src/main/java/com/melloware/jintellitype/IntellitypeListener.java new file mode 100644 index 0000000..4fa5ede --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/IntellitypeListener.java @@ -0,0 +1,51 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed 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. + */ +package com.melloware.jintellitype; + + +/** + * Listener interface for Windows Intellitype events. Intellitype are Windows + * App Commands that are specialand were introduced with Microsoft Keyboards + * that had special keys for Play, Pause, Stop, Next etc for controlling + * Media applications like Windows Media Player, Itunes, and Winamp. + *

+ * If you have ever wanted your Swing/SWT application to respond to these global + * events you now can with JIntellitype. Just implement this interface and + * you can now take action when those special Media keys are pressed. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + * + * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputmessages/wm_appcommand.asp + */ +public interface IntellitypeListener +{ + /** + * Event fired when a WM_APPCOMMAND message is received that was initiated + * by this application. + *

+ * @param command the WM_APPCOMMAND that was pressed + */ + void onIntellitype( int command ); +} \ No newline at end of file diff --git a/src/main/java/com/melloware/jintellitype/JIntellitype.java b/src/main/java/com/melloware/jintellitype/JIntellitype.java new file mode 100644 index 0000000..9b348a6 --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/JIntellitype.java @@ -0,0 +1,663 @@ +/** + * JIntellitype ----------------- Copyright 2005-2008 Emil A. Lefkof III, + * Melloware Inc. I always give it my best shot to make a program useful and + * solid, but remeber that there is absolutely no warranty for using this + * program as stated in the following terms: Licensed 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. + */ +package com.melloware.jintellitype; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.swing.SwingUtilities; + +/** + * JIntellitype A Java Implementation for using the Windows API Intellitype + * commands and the RegisterHotKey and UnRegisterHotkey API calls for globally + * responding to key events. Intellitype are commands that are using for Play, + * Stop, Next on Media keyboards or some laptops that have those special keys. + *

+ * JIntellitype class that is used to call Windows API calls using the + * JIntellitype.dll. + *

+ * This file comes with native code in JINTELLITYPE.DLL The DLL should go in + * C:/WINDOWS/SYSTEM or in your current directory + *

+ *

+ * Copyright (c) 1999-2008 Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public final class JIntellitype implements JIntellitypeConstants { + + /** + * Static variable to hold singleton. + */ + private static JIntellitype jintellitype = null; + + /** + * Static variable for double checked thread safety. + */ + private static boolean isInitialized = false; + + /** + * Static variable to hold the libary location if set + */ + private static String libraryLocation = null; + + /** + * Listeners collection for Hotkey events + */ + private final List hotkeyListeners = Collections + .synchronizedList(new CopyOnWriteArrayList()); + + /** + * Listeners collection for Hotkey events + */ + private final List intellitypeListeners = Collections + .synchronizedList(new CopyOnWriteArrayList()); + + /** + * Handler is used by JNI code to keep different JVM instances separate + */ + @SuppressWarnings("unused") + private final int handler = 0; + + /** + * Map containing key->keycode mapping + * @see #registerHotKey(int, String) + * @see #getKey2KeycodeMapping() + */ + private final HashMap keycodeMap; + + /** + * Private Constructor to prevent instantiation. Initialize the library for + * calling. + */ + private JIntellitype() { + // Load JNI library + try { + if (getLibraryLocation() != null) { + System.load(getLibraryLocation()); + } else { + String jarPath = "com/melloware/jintellitype/"; + String tmpDir = System.getProperty("java.io.tmpdir"); + try { + String dll = "JIntellitype.dll"; + fromJarToFs(jarPath + dll, tmpDir + dll); + System.load(tmpDir + dll); + } catch (UnsatisfiedLinkError e) { + String dll = "JIntellitype64.dll"; + fromJarToFs(jarPath + dll, tmpDir + dll); + System.load(tmpDir + dll); + } + } + initializeLibrary(); + } catch (IOException ex) { + throw new JIntellitypeException(ex); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + this.keycodeMap = getKey2KeycodeMapping(); + } + + /** + * Pulls a file out of the JAR and puts it on the File Path. + *

+ * @param jarPath the path to the JAR + * @param filePath the file path to extract to + * @throws IOException if any IO error occurs + */ + private void fromJarToFs(String jarPath, String filePath) throws IOException { + File file = new File(filePath); + if (file.exists()) { + boolean success = file.delete(); + if (!success) { + throw new IOException("couldn't delete " + filePath); + } + } + InputStream is = null; + OutputStream os = null; + try { + is = ClassLoader.getSystemClassLoader().getResourceAsStream(jarPath); + os = new FileOutputStream(filePath); + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } finally { + if (is != null) { + is.close(); + } + if (os != null) { + os.close(); + } + } + } + + /** + * Gets the singleton instance of the JIntellitype object. + *

+ * But the possibility of creation of more instance is only before the + * instance is created. Since all code defined inside getInstance method is + * in the synchronized block, even the subsequent requests will also come and + * wait in the synchronized block. This is a performance issue. The same can + * be solved using double-checked lock. Following is the implementation of + * Singleton with lazy initialization and double-checked lock. + *

+ * @return an instance of JIntellitype class + */ + public static JIntellitype getInstance() { + if (!isInitialized) { + synchronized (JIntellitype.class) { + if (!isInitialized) { + jintellitype = new JIntellitype(); + isInitialized = true; + } + } + } + return jintellitype; + } + + /** + * Adds a listener for hotkeys. + *

+ * @param listener the HotKeyListener to be added + */ + public void addHotKeyListener(HotkeyListener listener) { + hotkeyListeners.add(listener); + } + + /** + * Adds a listener for intellitype commands. + *

+ * @param listener the IntellitypeListener to be added + */ + public void addIntellitypeListener(IntellitypeListener listener) { + intellitypeListeners.add(listener); + } + + /** + * Cleans up all resources used by JIntellitype. + */ + public void cleanUp() { + try { + terminate(); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Uses the JIntellitypeConstants for MOD, + * ALT, CTRL, and WINDOWS keys. + *

+ * @param identifier a unique identifier for this key combination + * @param modifier MOD_SHIFT, MOD_ALT, MOD_CONTROL, MOD_WIN from + * JIntellitypeConstants, or 0 if no modifier needed + * @param keycode the key to respond to in Ascii integer, 65 for A + */ + public void registerHotKey(int identifier, int modifier, int keycode) { + try { + int modifiers = swingToIntelliType(modifier); + if (modifiers == 0) { + modifiers = modifier; + } + regHotKey(identifier, modifier, keycode); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Use the Swing InputEvent constants from + * java.awt.InputEvent. + *

+ * @param identifier a unique identifier for this key combination + * @param modifier InputEvent.SHIFT_MASK, InputEvent.ALT_MASK, + * InputEvent.CTRL_MASK, or 0 if no modifier needed + * @param keycode the key to respond to in Ascii integer, 65 for A + */ + public void registerSwingHotKey(int identifier, int modifier, int keycode) { + try { + regHotKey(identifier, swingToIntelliType(modifier), keycode); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Use the identifiers CTRL, SHIFT, ALT + * and/or WIN. + *

+ * @param identifier a unique identifier for this key combination + * @param modifierAndKeyCode String with modifiers separated by + and keycode + * (e.g. CTRL+SHIFT+A) + * @see #registerHotKey(int, int, int) + * @see #registerSwingHotKey(int, int, int) + */ + public void registerHotKey(int identifier, String modifierAndKeyCode) { + String[] split = modifierAndKeyCode.split("\\+"); + int mask = 0; + int keycode = 0; + + for (int i = 0; i < split.length; i++) { + if ("ALT".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_ALT; + } else if ("CTRL".equalsIgnoreCase(split[i]) || "CONTROL".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_CONTROL; + } else if ("SHIFT".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_SHIFT; + } else if ("WIN".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_WIN; + } else if (keycodeMap.containsKey(split[i].toLowerCase())) { + keycode = keycodeMap.get(split[i].toLowerCase()); + } + } + registerHotKey(identifier, mask, keycode); + } + + /** + * Removes a listener for hotkeys. + */ + public void removeHotKeyListener(HotkeyListener listener) { + hotkeyListeners.remove(listener); + } + + /** + * Removes a listener for intellitype commands. + */ + public void removeIntellitypeListener(IntellitypeListener listener) { + intellitypeListeners.remove(listener); + } + + /** + * Unregisters a previously registered Hotkey identified by its unique + * identifier. + *

+ * @param identifier the unique identifer of this Hotkey + */ + public void unregisterHotKey(int identifier) { + try { + unregHotKey(identifier); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Checks to see if this application is already running. + *

+ * @param appTitle the name of the application to check for + * @return true if running, false if not running + */ + public static boolean checkInstanceAlreadyRunning(String appTitle) { + return getInstance().isRunning(appTitle); + } + + /** + * Checks to make sure the OS is a Windows flavor and that the JIntellitype + * DLL is found in the path and the JDK is 32 bit not 64 bit. The DLL + * currently only supports 32 bit JDK. + *

+ * @return true if Jintellitype may be used, false if not + */ + public static boolean isJIntellitypeSupported() { + boolean result = false; + String os = "none"; + + try { + os = System.getProperty("os.name").toLowerCase(); + } catch (SecurityException ex) { + // we are not allowed to look at this property + System.err.println("Caught a SecurityException reading the system property " + + "'os.name'; the SystemUtils property value will default to null."); + } + + // only works on Windows OS currently + if (os.startsWith("windows")) { + // try an get the instance and if it succeeds then return true + try { + getInstance(); + result = true; + } catch (Exception e) { + result = false; + } + } + + return result; + } + + /** + * Gets the libraryLocation. + *

+ * @return Returns the libraryLocation. + */ + public static String getLibraryLocation() { + return libraryLocation; + } + + /** + * Sets the libraryLocation. + *

+ * @param libraryLocation The libraryLocation to set. + */ + public static void setLibraryLocation(String libraryLocation) { + final File dll = new File(libraryLocation); + if (!dll.isAbsolute()) { + JIntellitype.libraryLocation = dll.getAbsolutePath(); + } else { + // absolute path, no further calculation needed + JIntellitype.libraryLocation = libraryLocation; + } + } + + /** + * Notifies all listeners that Hotkey was pressed. + *

+ * @param identifier the unique identifier received + */ + protected void onHotKey(final int identifier) { + for (final HotkeyListener hotkeyListener : hotkeyListeners) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + hotkeyListener.onHotKey(identifier); + } + }); + } + } + + /** + * Notifies all listeners that Intellitype command was received. + *

+ * @param command the unique WM_APPCOMMAND received + */ + protected void onIntellitype(final int command) { + for (final IntellitypeListener intellitypeListener : intellitypeListeners) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + intellitypeListener.onIntellitype(command); + } + }); + } + } + + /** + * Swing modifier value to Jintellipad conversion. If no conversion needed + * just return the original value. This lets users pass either the original + * JIntellitype constants or Swing InputEvent constants. + *

+ * @param swingKeystrokeModifier the Swing KeystrokeModifier to check + * @return Jintellitype the JIntellitype modifier value + */ + protected static int swingToIntelliType(int swingKeystrokeModifier) { + int mask = 0; + if ((swingKeystrokeModifier & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) { + mask += JIntellitype.MOD_SHIFT; + } + if ((swingKeystrokeModifier & InputEvent.ALT_MASK) == InputEvent.ALT_MASK) { + mask += JIntellitype.MOD_ALT; + } + if ((swingKeystrokeModifier & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) { + mask += JIntellitype.MOD_CONTROL; + } + if ((swingKeystrokeModifier & InputEvent.SHIFT_DOWN_MASK) == InputEvent.SHIFT_DOWN_MASK) { + mask += JIntellitype.MOD_SHIFT; + } + if ((swingKeystrokeModifier & InputEvent.ALT_DOWN_MASK) == InputEvent.ALT_DOWN_MASK) { + mask += JIntellitype.MOD_ALT; + } + if ((swingKeystrokeModifier & InputEvent.CTRL_DOWN_MASK) == InputEvent.CTRL_DOWN_MASK) { + mask += JIntellitype.MOD_CONTROL; + } + return mask; + } + + /** + * Puts all constants from {@link java.awt.event.KeyEvent} in a keycodeMap. + * The key is the lower case form of it. + * @return Map containing key->keycode mapping DOCU Now enables the user to + * use all keys specified here instead of just [A-Z],[0-9] as before + */ + private HashMap getKey2KeycodeMapping() { + HashMap map = new HashMap(); + + map.put("first", KeyEvent.KEY_FIRST); + map.put("last", KeyEvent.KEY_LAST); + map.put("typed", KeyEvent.KEY_TYPED); + map.put("pressed", KeyEvent.KEY_PRESSED); + map.put("released", KeyEvent.KEY_RELEASED); + map.put("enter", KeyEvent.VK_ENTER); + map.put("back_space", KeyEvent.VK_BACK_SPACE); + map.put("tab", KeyEvent.VK_TAB); + map.put("cancel", KeyEvent.VK_CANCEL); + map.put("clear", KeyEvent.VK_CLEAR); + map.put("pause", KeyEvent.VK_PAUSE); + map.put("caps_lock", KeyEvent.VK_CAPS_LOCK); + map.put("escape", KeyEvent.VK_ESCAPE); + map.put("space", KeyEvent.VK_SPACE); + map.put("page_up", KeyEvent.VK_PAGE_UP); + map.put("page_down", KeyEvent.VK_PAGE_DOWN); + map.put("end", KeyEvent.VK_END); + map.put("home", KeyEvent.VK_HOME); + map.put("left", KeyEvent.VK_LEFT); + map.put("up", KeyEvent.VK_UP); + map.put("right", KeyEvent.VK_RIGHT); + map.put("down", KeyEvent.VK_DOWN); + map.put("comma", KeyEvent.VK_COMMA); + map.put("minus", KeyEvent.VK_MINUS); + map.put("period", KeyEvent.VK_PERIOD); + map.put("slash", KeyEvent.VK_SLASH); + map.put("0", KeyEvent.VK_0); + map.put("1", KeyEvent.VK_1); + map.put("2", KeyEvent.VK_2); + map.put("3", KeyEvent.VK_3); + map.put("4", KeyEvent.VK_4); + map.put("5", KeyEvent.VK_5); + map.put("6", KeyEvent.VK_6); + map.put("7", KeyEvent.VK_7); + map.put("8", KeyEvent.VK_8); + map.put("9", KeyEvent.VK_9); + map.put("semicolon", KeyEvent.VK_SEMICOLON); + map.put("equals", KeyEvent.VK_EQUALS); + map.put("a", KeyEvent.VK_A); + map.put("b", KeyEvent.VK_B); + map.put("c", KeyEvent.VK_C); + map.put("d", KeyEvent.VK_D); + map.put("e", KeyEvent.VK_E); + map.put("f", KeyEvent.VK_F); + map.put("g", KeyEvent.VK_G); + map.put("h", KeyEvent.VK_H); + map.put("i", KeyEvent.VK_I); + map.put("j", KeyEvent.VK_J); + map.put("k", KeyEvent.VK_K); + map.put("l", KeyEvent.VK_L); + map.put("m", KeyEvent.VK_M); + map.put("n", KeyEvent.VK_N); + map.put("o", KeyEvent.VK_O); + map.put("p", KeyEvent.VK_P); + map.put("q", KeyEvent.VK_Q); + map.put("r", KeyEvent.VK_R); + map.put("s", KeyEvent.VK_S); + map.put("t", KeyEvent.VK_T); + map.put("u", KeyEvent.VK_U); + map.put("v", KeyEvent.VK_V); + map.put("w", KeyEvent.VK_W); + map.put("x", KeyEvent.VK_X); + map.put("y", KeyEvent.VK_Y); + map.put("z", KeyEvent.VK_Z); + map.put("open_bracket", KeyEvent.VK_OPEN_BRACKET); + map.put("back_slash", KeyEvent.VK_BACK_SLASH); + map.put("close_bracket", KeyEvent.VK_CLOSE_BRACKET); + map.put("numpad0", KeyEvent.VK_NUMPAD0); + map.put("numpad1", KeyEvent.VK_NUMPAD1); + map.put("numpad2", KeyEvent.VK_NUMPAD2); + map.put("numpad3", KeyEvent.VK_NUMPAD3); + map.put("numpad4", KeyEvent.VK_NUMPAD4); + map.put("numpad5", KeyEvent.VK_NUMPAD5); + map.put("numpad6", KeyEvent.VK_NUMPAD6); + map.put("numpad7", KeyEvent.VK_NUMPAD7); + map.put("numpad8", KeyEvent.VK_NUMPAD8); + map.put("numpad9", KeyEvent.VK_NUMPAD9); + map.put("multiply", KeyEvent.VK_MULTIPLY); + map.put("add", KeyEvent.VK_ADD); + map.put("separator", KeyEvent.VK_SEPARATOR); + map.put("subtract", KeyEvent.VK_SUBTRACT); + map.put("decimal", KeyEvent.VK_DECIMAL); + map.put("divide", KeyEvent.VK_DIVIDE); + map.put("delete", KeyEvent.VK_DELETE); + map.put("num_lock", KeyEvent.VK_NUM_LOCK); + map.put("scroll_lock", KeyEvent.VK_SCROLL_LOCK); + map.put("f1", KeyEvent.VK_F1); + map.put("f2", KeyEvent.VK_F2); + map.put("f3", KeyEvent.VK_F3); + map.put("f4", KeyEvent.VK_F4); + map.put("f5", KeyEvent.VK_F5); + map.put("f6", KeyEvent.VK_F6); + map.put("f7", KeyEvent.VK_F7); + map.put("f8", KeyEvent.VK_F8); + map.put("f9", KeyEvent.VK_F9); + map.put("f10", KeyEvent.VK_F10); + map.put("f11", KeyEvent.VK_F11); + map.put("f12", KeyEvent.VK_F12); + map.put("f13", KeyEvent.VK_F13); + map.put("f14", KeyEvent.VK_F14); + map.put("f15", KeyEvent.VK_F15); + map.put("f16", KeyEvent.VK_F16); + map.put("f17", KeyEvent.VK_F17); + map.put("f18", KeyEvent.VK_F18); + map.put("f19", KeyEvent.VK_F19); + map.put("f20", KeyEvent.VK_F20); + map.put("f21", KeyEvent.VK_F21); + map.put("f22", KeyEvent.VK_F22); + map.put("f23", KeyEvent.VK_F23); + map.put("f24", KeyEvent.VK_F24); + map.put("printscreen", KeyEvent.VK_PRINTSCREEN); + map.put("insert", KeyEvent.VK_INSERT); + map.put("help", KeyEvent.VK_HELP); + map.put("meta", KeyEvent.VK_META); + map.put("back_quote", KeyEvent.VK_BACK_QUOTE); + map.put("quote", KeyEvent.VK_QUOTE); + map.put("kp_up", KeyEvent.VK_KP_UP); + map.put("kp_down", KeyEvent.VK_KP_DOWN); + map.put("kp_left", KeyEvent.VK_KP_LEFT); + map.put("kp_right", KeyEvent.VK_KP_RIGHT); + map.put("dead_grave", KeyEvent.VK_DEAD_GRAVE); + map.put("dead_acute", KeyEvent.VK_DEAD_ACUTE); + map.put("dead_circumflex", KeyEvent.VK_DEAD_CIRCUMFLEX); + map.put("dead_tilde", KeyEvent.VK_DEAD_TILDE); + map.put("dead_macron", KeyEvent.VK_DEAD_MACRON); + map.put("dead_breve", KeyEvent.VK_DEAD_BREVE); + map.put("dead_abovedot", KeyEvent.VK_DEAD_ABOVEDOT); + map.put("dead_diaeresis", KeyEvent.VK_DEAD_DIAERESIS); + map.put("dead_abovering", KeyEvent.VK_DEAD_ABOVERING); + map.put("dead_doubleacute", KeyEvent.VK_DEAD_DOUBLEACUTE); + map.put("dead_caron", KeyEvent.VK_DEAD_CARON); + map.put("dead_cedilla", KeyEvent.VK_DEAD_CEDILLA); + map.put("dead_ogonek", KeyEvent.VK_DEAD_OGONEK); + map.put("dead_iota", KeyEvent.VK_DEAD_IOTA); + map.put("dead_voiced_sound", KeyEvent.VK_DEAD_VOICED_SOUND); + map.put("dead_semivoiced_sound", KeyEvent.VK_DEAD_SEMIVOICED_SOUND); + map.put("ampersand", KeyEvent.VK_AMPERSAND); + map.put("asterisk", KeyEvent.VK_ASTERISK); + map.put("quotedbl", KeyEvent.VK_QUOTEDBL); + map.put("less", KeyEvent.VK_LESS); + map.put("greater", KeyEvent.VK_GREATER); + map.put("braceleft", KeyEvent.VK_BRACELEFT); + map.put("braceright", KeyEvent.VK_BRACERIGHT); + map.put("at", KeyEvent.VK_AT); + map.put("colon", KeyEvent.VK_COLON); + map.put("circumflex", KeyEvent.VK_CIRCUMFLEX); + map.put("dollar", KeyEvent.VK_DOLLAR); + map.put("euro_sign", KeyEvent.VK_EURO_SIGN); + map.put("exclamation_mark", KeyEvent.VK_EXCLAMATION_MARK); + map.put("inverted_exclamation_mark", KeyEvent.VK_INVERTED_EXCLAMATION_MARK); + map.put("left_parenthesis", KeyEvent.VK_LEFT_PARENTHESIS); + map.put("number_sign", KeyEvent.VK_NUMBER_SIGN); + map.put("plus", KeyEvent.VK_PLUS); + map.put("right_parenthesis", KeyEvent.VK_RIGHT_PARENTHESIS); + map.put("underscore", KeyEvent.VK_UNDERSCORE); + map.put("context_menu", KeyEvent.VK_CONTEXT_MENU); + map.put("final", KeyEvent.VK_FINAL); + map.put("convert", KeyEvent.VK_CONVERT); + map.put("nonconvert", KeyEvent.VK_NONCONVERT); + map.put("accept", KeyEvent.VK_ACCEPT); + map.put("modechange", KeyEvent.VK_MODECHANGE); + map.put("kana", KeyEvent.VK_KANA); + map.put("kanji", KeyEvent.VK_KANJI); + map.put("alphanumeric", KeyEvent.VK_ALPHANUMERIC); + map.put("katakana", KeyEvent.VK_KATAKANA); + map.put("hiragana", KeyEvent.VK_HIRAGANA); + map.put("full_width", KeyEvent.VK_FULL_WIDTH); + map.put("half_width", KeyEvent.VK_HALF_WIDTH); + map.put("roman_characters", KeyEvent.VK_ROMAN_CHARACTERS); + map.put("all_candidates", KeyEvent.VK_ALL_CANDIDATES); + map.put("previous_candidate", KeyEvent.VK_PREVIOUS_CANDIDATE); + map.put("code_input", KeyEvent.VK_CODE_INPUT); + map.put("japanese_katakana", KeyEvent.VK_JAPANESE_KATAKANA); + map.put("japanese_hiragana", KeyEvent.VK_JAPANESE_HIRAGANA); + map.put("japanese_roman", KeyEvent.VK_JAPANESE_ROMAN); + map.put("kana_lock", KeyEvent.VK_KANA_LOCK); + map.put("input_method_on_off", KeyEvent.VK_INPUT_METHOD_ON_OFF); + map.put("cut", KeyEvent.VK_CUT); + map.put("copy", KeyEvent.VK_COPY); + map.put("paste", KeyEvent.VK_PASTE); + map.put("undo", KeyEvent.VK_UNDO); + map.put("again", KeyEvent.VK_AGAIN); + map.put("find", KeyEvent.VK_FIND); + map.put("props", KeyEvent.VK_PROPS); + map.put("stop", KeyEvent.VK_STOP); + map.put("compose", KeyEvent.VK_COMPOSE); + map.put("alt_graph", KeyEvent.VK_ALT_GRAPH); + map.put("begin", KeyEvent.VK_BEGIN); + + return map; + } + + private synchronized native void initializeLibrary() throws UnsatisfiedLinkError; + + private synchronized native void regHotKey(int identifier, int modifier, int keycode) throws UnsatisfiedLinkError; + + private synchronized native void terminate() throws UnsatisfiedLinkError; + + private synchronized native void unregHotKey(int identifier) throws UnsatisfiedLinkError; + + /** + * Checks if there's an instance with hidden window title = appName running + * Can be used to detect that another instance of your app is already running + * (so exit..) + *

+ * @param appName = the title of the hidden window to search for + */ + private synchronized native boolean isRunning(String appName); +} \ No newline at end of file diff --git a/src/main/java/com/melloware/jintellitype/JIntellitypeConstants.java b/src/main/java/com/melloware/jintellitype/JIntellitypeConstants.java new file mode 100644 index 0000000..d2bb3f6 --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/JIntellitypeConstants.java @@ -0,0 +1,182 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed 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. + */ +package com.melloware.jintellitype; + +/** + * Constants from the Windows API used in JIntellitype. + *

+ * Message information can be found on MSDN here: + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputmessages/wm_appcommand.asp + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public interface JIntellitypeConstants { + + public static final String ERROR_MESSAGE = "JIntellitype DLL Error"; + + // Modifier keys, can be added together + + /** + * ALT key for registering Hotkeys. + */ + public static final int MOD_ALT = 1; + + /** + * CONTROL key for registering Hotkeys. + */ + public static final int MOD_CONTROL = 2; + + /** + * SHIFT key for registering Hotkeys. + */ + public static final int MOD_SHIFT = 4; + + /** + * WINDOWS key for registering Hotkeys. + */ + public static final int MOD_WIN = 8; + + + // Intellitype Virtual Key Constants from MSDN + + /** + * Browser Navigate backward + */ + public static final int APPCOMMAND_BROWSER_BACKWARD = 1; + + /** + * Browser Navigate forward + */ + public static final int APPCOMMAND_BROWSER_FORWARD = 2; + + /** + * Browser Refresh page + */ + public static final int APPCOMMAND_BROWSER_REFRESH = 3; + + /** + * Browser Stop download + */ + public static final int APPCOMMAND_BROWSER_STOP = 4; + + /** + * Browser Open search + */ + public static final int APPCOMMAND_BROWSER_SEARCH = 5; + + /** + * Browser Open favorites + */ + public static final int APPCOMMAND_BROWSER_FAVOURITES = 6; + + /** + * Browser Navigate home + */ + public static final int APPCOMMAND_BROWSER_HOME = 7; + + /** + * Mute the volume + */ + public static final int APPCOMMAND_VOLUME_MUTE = 8; + + /** + * Lower the volume + */ + public static final int APPCOMMAND_VOLUME_DOWN = 9; + + /** + * Raise the volume + */ + public static final int APPCOMMAND_VOLUME_UP = 10; + + /** + * Media application go to next track. + */ + public static final int APPCOMMAND_MEDIA_NEXTTRACK = 11; + + /** + * Media application Go to previous track. + */ + public static final int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12; + + /** + * Media application Stop playback. + */ + public static final int APPCOMMAND_MEDIA_STOP = 13; + + /** + * Media application Play or pause playback. + */ + public static final int APPCOMMAND_MEDIA_PLAY_PAUSE = 14; + + /** + * Open mail application + */ + public static final int APPCOMMAND_LAUNCH_MAIL = 15; + + /** + * Go to Media Select mode. + */ + public static final int APPCOMMAND_LAUNCH_MEDIA_SELECT = 16; + + /** + * Start App1. + */ + public static final int APPCOMMAND_LAUNCH_APP1 = 17; + + /** + * Start App2. + */ + public static final int APPCOMMAND_LAUNCH_APP2 = 18; + + public static final int APPCOMMAND_BASS_DOWN = 19; + public static final int APPCOMMAND_BASS_BOOST = 20; + public static final int APPCOMMAND_BASS_UP = 21; + public static final int APPCOMMAND_TREBLE_DOWN = 22; + public static final int APPCOMMAND_TREBLE_UP = 23; + public static final int APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24; + public static final int APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25; + public static final int APPCOMMAND_MICROPHONE_VOLUME_UP = 26; + public static final int APPCOMMAND_HELP = 27; + public static final int APPCOMMAND_FIND = 28; + public static final int APPCOMMAND_NEW = 29; + public static final int APPCOMMAND_OPEN = 30; + public static final int APPCOMMAND_CLOSE = 31; + public static final int APPCOMMAND_SAVE = 32; + public static final int APPCOMMAND_PRINT = 33; + public static final int APPCOMMAND_UNDO = 34; + public static final int APPCOMMAND_REDO = 35; + public static final int APPCOMMAND_COPY = 36; + public static final int APPCOMMAND_CUT = 37; + public static final int APPCOMMAND_PASTE = 38; + public static final int APPCOMMAND_REPLY_TO_MAIL = 39; + public static final int APPCOMMAND_FORWARD_MAIL = 40; + public static final int APPCOMMAND_SEND_MAIL = 41; + public static final int APPCOMMAND_SPELL_CHECK = 42; + public static final int APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43; + public static final int APPCOMMAND_MIC_ON_OFF_TOGGLE = 44; + public static final int APPCOMMAND_CORRECTION_LIST = 45; + +} diff --git a/src/main/java/com/melloware/jintellitype/JIntellitypeException.java b/src/main/java/com/melloware/jintellitype/JIntellitypeException.java new file mode 100644 index 0000000..a4fa36b --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/JIntellitypeException.java @@ -0,0 +1,55 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed 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. + */ +package com.melloware.jintellitype; + + +/** + * Exception class for all JIntellitype Exceptions. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public class JIntellitypeException extends RuntimeException { + + + public JIntellitypeException() { + super(); + } + + + public JIntellitypeException(String aMessage, Throwable aCause) { + super(aMessage, aCause); + } + + + public JIntellitypeException(String aMessage) { + super(aMessage); + } + + + public JIntellitypeException(Throwable aCause) { + super(aCause); + } + +} diff --git a/src/main/java/com/melloware/jintellitype/Main.java b/src/main/java/com/melloware/jintellitype/Main.java new file mode 100644 index 0000000..b579745 --- /dev/null +++ b/src/main/java/com/melloware/jintellitype/Main.java @@ -0,0 +1,80 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed 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. + */ +package com.melloware.jintellitype; + +import java.util.Properties; + +/** + * Simple executable class that is used as the Main-Class in the JIntellitype + * jar. Outputs version information and other information about the environment + * on which the jar is being executed. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +@SuppressWarnings("") +public final class Main { + + /** + * Private constructor to make sure this class is never instantiated. + * + */ + private Main() { + // private constructor to make singleton. + } + + /** Main method that does what the class level javadoc states. */ + public static void main(String[] argv) { + System.out.println("JIntellitype version \"" + getProjectVersion() + "\""); + System.out.println(" "); + + System.out.println("Running on java version \"" + System.getProperty("java.version") + "\"" + + " (build " + System.getProperty("java.runtime.version") + ")" + + " from " + System.getProperty("java.vendor")); + + System.out.println("Operating environment \"" + System.getProperty("os.name") + "\"" + + " version " + System.getProperty("os.version") + " on " + System.getProperty("os.arch")); + + System.out.println("For more information on JIntellitype please visit http://www.melloware.com"); + } + + /** + * Attempts to read the version number out of the pom.properties. If not found + * then RUNNING.IN.IDE.FULL is returned as the version. + *

+ * @return the full version number of this application + */ + private static String getProjectVersion() { + String version; + + try { + final Properties pomProperties = new Properties(); + pomProperties.load(Main.class.getResourceAsStream("/META-INF/maven/com.melloware/jintellitype/pom.properties")); + version = pomProperties.getProperty("version"); + } catch (Exception e) { + version = "RUNNING.IN.IDE.FULL"; + } + return version; + } +} \ No newline at end of file diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml new file mode 100644 index 0000000..f141139 --- /dev/null +++ b/src/site/fml/faq.fml @@ -0,0 +1,131 @@ + + + + + + General + + + + What is JIntellitype? + + + JIntellitype is a Java API for Windows that allows you to + register global hotkeys and listen for Microsft Intellitype commands. + + + + + + On which platform does it run? + + + Since JIntellitype uses Windows specific calls it will + only work on Windows. Windows 2000 or higher recommended. For a Linux + version see JxGrabKey project on Sourceforge. + + + + + + Does it run on x64 JDK or JRE's? + + + Starting with 1.3.3 JINtellitype comes with a 64 bit DLL. To use it Simply rename the DLL to + JIntellitype.dll or use the Jintellitype.setLibraryLocation(''); function to set the path to JIntellitype64.dll. + + + + + + Where do I get help on JIntellitype? + + + This FAQ answers some frequent questions already, please read the + it thoroughly. +

+ If these resources don't help you with your problem, + or if you think that you found a bug that is not yet documented, + you should contact us. + + + + + + I have a question that is not addressed here. + Where can I ask? + + + See our Contacts page. + + + + + + + Problems + + + + I am pressing my special Intellitype keys on my keyboard but nothing is happening? + + + First, make sure you have followed instructions for using JIntellitype properly. Next, + make sure you do not have Microsft Intellitype drivers installed. The Microsoft software + intercepts the messages before they get to JIntellitype and "eats" them. You can tell if + you are running Microsoft Keyboard software by opening Task Manager and looking for the + process name "itype.exe". + + + + + + I am using Jintellitype.checkInstanceAlreadyRunning("MyApp") but it is allowing me to open + my application more than once when I am expecting it not to? + + + Make sure that "MyApp" is the getTitle() of the main JFrame of your application. + JIntellitype checks by Window title name. + + + + + + + Development + + + + Can I contribute? + + + Yes, please! Check out the contact page and contact us! + + + + + + I think I found a bug in JIntellitype. + What should I do? + + + You should post it to the forums to + make sure it is documented. + + + + + + When will feature XYZ be implemented? + + + Depends. If it is something you really sorely need, you could (politely) + try to exert some pressure on us. You can also try to pay us. + Or try to implement your feature yourself and send us some patches. + In any case, you should contact us about your problem. + + + + + + \ No newline at end of file diff --git a/src/site/resources/default.aspx b/src/site/resources/default.aspx new file mode 100644 index 0000000..0317e49 --- /dev/null +++ b/src/site/resources/default.aspx @@ -0,0 +1 @@ +<% Response.Redirect("http://melloware.com/products/jintellitype/index.html");%> \ No newline at end of file diff --git a/src/site/resources/favicon.ico b/src/site/resources/favicon.ico new file mode 100644 index 0000000..adae938 Binary files /dev/null and b/src/site/resources/favicon.ico differ diff --git a/src/site/resources/images/devc-jni.jpg b/src/site/resources/images/devc-jni.jpg new file mode 100644 index 0000000..f2f68b6 Binary files /dev/null and b/src/site/resources/images/devc-jni.jpg differ diff --git a/src/site/resources/images/duke.gif b/src/site/resources/images/duke.gif new file mode 100644 index 0000000..48e5165 Binary files /dev/null and b/src/site/resources/images/duke.gif differ diff --git a/src/site/resources/images/duke.ico b/src/site/resources/images/duke.ico new file mode 100644 index 0000000..d5dd6df Binary files /dev/null and b/src/site/resources/images/duke.ico differ diff --git a/src/site/resources/images/duke_up.ico b/src/site/resources/images/duke_up.ico new file mode 100644 index 0000000..68bb02e Binary files /dev/null and b/src/site/resources/images/duke_up.ico differ diff --git a/src/site/resources/images/jintellitype-banner.png b/src/site/resources/images/jintellitype-banner.png new file mode 100644 index 0000000..56dc176 Binary files /dev/null and b/src/site/resources/images/jintellitype-banner.png differ diff --git a/src/site/resources/images/jintellitype-banner.pspimage b/src/site/resources/images/jintellitype-banner.pspimage new file mode 100644 index 0000000..a8ef4c4 Binary files /dev/null and b/src/site/resources/images/jintellitype-banner.pspimage differ diff --git a/src/site/resources/images/jintellitype-logo.png b/src/site/resources/images/jintellitype-logo.png new file mode 100644 index 0000000..0f626c2 Binary files /dev/null and b/src/site/resources/images/jintellitype-logo.png differ diff --git a/src/site/resources/images/jintellitype-logo.pspimage b/src/site/resources/images/jintellitype-logo.pspimage new file mode 100644 index 0000000..e64baf3 Binary files /dev/null and b/src/site/resources/images/jintellitype-logo.pspimage differ diff --git a/src/site/resources/images/windows.png b/src/site/resources/images/windows.png new file mode 100644 index 0000000..ccb4ba3 Binary files /dev/null and b/src/site/resources/images/windows.png differ diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000..da6981b --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,56 @@ + + + + http://melloware.com/images/header.jpg + http://melloware.com/ + + + ./images/jintellitype-banner.png + http://melloware.com/products/jintellitype/ + + + + + com.melloware + melloware-skin + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/site/xdoc/contacts.xml b/src/site/xdoc/contacts.xml new file mode 100644 index 0000000..5ee5ea7 --- /dev/null +++ b/src/site/xdoc/contacts.xml @@ -0,0 +1,32 @@ + + + + + + Contacts + Emil A Lefkof III + + + + +
+

+ The preferred way of getting in touch with one of the developers of + JIntellitype is via the forums. + Please direct any matters of general user support, questions, suggestions, discussions, etc., + to the forums. +

+ + +

+ In special cases, you may try to contact directly one of the + developers or contributors. You + can always send request to info@melloware.com also. +

+
+ +
+ + + +
\ No newline at end of file diff --git a/src/site/xdoc/dev-cpp.xml b/src/site/xdoc/dev-cpp.xml new file mode 100644 index 0000000..20ed4b7 --- /dev/null +++ b/src/site/xdoc/dev-cpp.xml @@ -0,0 +1,37 @@ + + + + JIntellitype + Emil A Lefkof III + + + +
+ +

+ Jintellitype uses the Bloodshed Dev C++ IDE for compiling the JIntellitype.dll. +

+ +

+ 1. Once you have DevC++ installed, just open the JIntellitype.dev project file. +

+

+ 2. Navigate to the menu option Project->Options. +

+

+ 3. Make sure to set the entries in the screenshot below to your JDK location. +
+ Project Options +

+ +

+ 4. Change your Project->Options Build Options to point to an output directory of your choosing. + +

+ +

+ 5. Use the menu or toolbar button to build the DLL! +

+
+ +
\ No newline at end of file diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml new file mode 100644 index 0000000..4adb687 --- /dev/null +++ b/src/site/xdoc/index.xml @@ -0,0 +1,121 @@ + + + + Java API for Microsoft Intellitype + Emil A Lefkof III + + + +
+ + +

+ JIntellitype is a Java API for interacting with Microsoft Intellitype + commands as well as registering for Global Hotkeys in your Java application. + The API is a Java JNI library that uses a C++ DLL to do all the communication + with Windows. NOTE: This library ONLY works on Windows. If + you are looking for a Linux version please see JxGrabKey project on Sourceforge. +

+
+ + +

+ Have you ever wanted to have CTRL+SHIFT+G maximize your Swing application + on the desktop? Even if that application did not have focus? Well, now you can! By + registering a Windows Hotkey combination, your application will be alerted + when the combination you select is pressed anywhere in Windows. Windows has the + API call RegisterHotKey + for registering a global hotkey combination so that your app receives that message + no matter what else you are doing or even if your application has focus. This is + a commonly requested feature in Java that has now been implemented by JIntellitype. + + Check out the Quick Start Guide for an example on how to use JIntellitype. +

+ +
+ + + +

+ Have you ever wanted your Java application to react to those special Play, Pause, + Stop keys on some newer keyboards like Winamp and Windows Media Player do? Ever wonder how they do it? + If you want your application to "listen" for those special keys, now you can with JIntellitype! + Just register an IntellitypeListener and you will be notified when those messages are received. + To read more about these special commands see the MSDN Documentation + about the Intellitype commands. + + Check out the Quick Start Guide for an example on how to use JIntellitype. +

+ +
+ + +

+ Although JIntellitype is open source, small financial donations are appreciated. By supporting Melloware, you help fund the development + (mainly development tools and internet access etc) of Melloware's Software. To send money, simply click on the PayPal icon to the left. +

+
+ + +

+ Jukes cross platform music player and organizer. +

+

+ JaJuk cross platform swiss army knife music player including DJ mode and much more! +

+

+ C2TN C2TN is the first RSS Reader which integrates completely into your desktop. +

+

+ aTunes aTunes is a GPL audio player and manager. +

+

+ Topkeys emulates the mouse using the keyboard. +

+

+ MiniGen is a program that can generate text in any Windows-based (tested on XP/Vista) application based on the currently selected text in a non-invasive manner. +

+

+ Xtreme Media Player is a free cross-platform media player. +

+

+ MyTime is a simple time tracker, mostly controlled through the tray icon. +

+

+ RadiS is a cool-looking mouse menu that opens upon a global hot-key. Allows sub-menus which will be displayed in an adjacent partly circle. +

+

+ JShot is a free and multiplatform screen capture and uploader utility which allows you to capture a part of your screen and publish it in one step. +

+

+ OpenSoundboard plays sound files (currently only .wav) when the user presses hotkeys. +

+

+ Clipcomrade - simple and free open source windows clipboard manager tool +

+

+ Wordoholic Learner - a cross-platform language learning tool +

+
+ + +
    +
  • Can register global hotkey combinations in Java applications in Windows
  • +
  • Application is notified even if it does not have focus.
  • +
  • Can react to those Play, Pause, Stop, Next, Forward Media keys like Winamp
  • +
  • Very little code, easy to use API
  • +
  • Examples included in JIntellitypeTester.java
  • +
+
+ + + +
+ + + +
\ No newline at end of file diff --git a/src/site/xdoc/quick-start.xml b/src/site/xdoc/quick-start.xml new file mode 100644 index 0000000..4a626e5 --- /dev/null +++ b/src/site/xdoc/quick-start.xml @@ -0,0 +1,110 @@ + + + + JIntellitype + Emil A Lefkof III + + + +
+ +

+ Here is a simple quick start for getting up and running with JIntellitype quickly. + An Example is also included in the + distribution to show you how easy it is to use JIntellitype. +

+ + +

+ If you are familiar with Eclipse there is a full working example Eclipse project that can be + found here Eclipse Example. + In Eclipse just navigate to File->Import->Existing Project Into Workspace and you are ready to go. +

+
+ + +

+ 1. Make sure JIntellitype.dll is in your PATH or in \Windows\System32. +

+

+ 2. Initialize a JIntellitype object. + + // Initialize JIntellitype + ... + JIntellitype.getInstance(); + ... + // OPTIONAL: check to see if an instance of this application is already + // running, use the name of the window title of this JFrame for checking + if (JIntellitype.checkInstanceAlreadyRunning("MyApp")) { + LOG.error("An instance of this application is already running"); + System.exit(1); + } + +

+ +

+ 3. To listen to hotkey's, you need to register the combinations to listen for. + + // Assign global hotkeys to Windows+A and ALT+SHIFT+B + JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_WIN, (int)'A'); + JIntellitype.getInstance().registerHotKey(2, JIntellitype.MOD_ALT + JIntellitype.MOD_SHIFT, (int)'B'); + + //or you can use the Swing constants instead + JIntellitype.getInstance().registerSwingHotKey(3, Event.CTRL_MASK + Event.SHIFT_MASK, (int)'C'); + + // To unregister them just call unregisterHotKey with the unique identifier + JIntellitype.getInstance().unregisterHotKey(1); + JIntellitype.getInstance().unregisterHotKey(2); + JIntellitype.getInstance().unregisterHotKey(3); + +

+ +

+ 4. Make sure to add a HotKeyListener and implement the interface. + + //assign this class to be a HotKeyListener + JIntellitype.getInstance().addHotKeyListener(this); + + // listen for hotkey + public void onHotKey(int aIdentifier) { + if (aIdentifier == 1) + System.out.println("WINDOWS+A hotkey pressed"); + } + } + +

+ +

+ 5. To use Intellitype commands implement the IntellitypeListener interface. + + //assign this class to be a IntellitypeListener + JIntellitype.getInstance().addIntellitypeListener(this); + + // listen for intellitype play/pause command + public void onIntellitype(int aCommand) { + switch (aCommand) { + case JIntellitype.APPCOMMAND_MEDIA_PLAY_PAUSE: + System.out.println("Play/Pause message received " + Integer.toString(aCommand)); + break; + default: + System.out.println("Undefined INTELLITYPE message caught " + Integer.toString(aCommand)); + break; + } + } + +

+ +

+ 6. Don't forget to call the cleanup method to release the DLL resources. + + // Termination, make sure to call before exiting + ... + JIntellitype.getInstance().cleanUp(); + System.exit(0); + +

+
+ +
+ +
\ No newline at end of file diff --git a/src/test/java/com/melloware/JIntellitypeTester.java b/src/test/java/com/melloware/JIntellitypeTester.java new file mode 100644 index 0000000..2eae221 --- /dev/null +++ b/src/test/java/com/melloware/JIntellitypeTester.java @@ -0,0 +1,310 @@ +/* + * JIntellitype ----------------- Copyright 2005-2006 Emil A. Lefkof III + * + * I always give it my best shot to make a program useful and solid, but remeber + * that there is absolutely no warranty for using this program as stated in the + * following terms: + * + * Licensed 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. + */ +package com.melloware; + +import java.awt.BorderLayout; +import java.awt.Event; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.border.EtchedBorder; + +import com.melloware.jintellitype.HotkeyListener; +import com.melloware.jintellitype.IntellitypeListener; +import com.melloware.jintellitype.JIntellitype; + +/** + * Swing based test application to test all the functions of the JIntellitype + * library. + *

+ * Copyright (c) 2006 Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.0 + */ +public class JIntellitypeTester extends JFrame implements HotkeyListener, IntellitypeListener { + + private static JIntellitypeTester mainFrame; + private static final int WINDOWS_A = 88; + private static final int ALT_SHIFT_B = 89; + private static final int CTRL_SHIFT_C = 90; + private static final int PRINT_SCREEN = 91; + private static final int F9 = 92; + private static final int F12 = 93; + private static final int SEMICOLON = 94; + private JButton btnRegisterHotKey = new JButton(); + private JButton btnUnregisterHotKey = new JButton(); + private JPanel bottomPanel = new JPanel(); + private JPanel mainPanel = new JPanel(); + private JPanel topPanel = new JPanel(); + private JScrollPane scrollPane = new JScrollPane(); + private JTextArea textArea = new JTextArea(); + + /** + * Creates new form. + */ + public JIntellitypeTester() { + initComponents(); + } + + /** + * Main method to launch this application. + *

+ * @param args any command line arguments + */ + public static void main(String[] args) { + // first check to see if an instance of this application is already + // running, use the name of the window title of this JFrame for checking + if (JIntellitype.checkInstanceAlreadyRunning("JIntellitype Test Application")) { + System.exit(1); + } + + // next check to make sure JIntellitype DLL can be found and we are on + // a Windows operating System + if (!JIntellitype.isJIntellitypeSupported()) { + System.exit(1); + } + + mainFrame = new JIntellitypeTester(); + mainFrame.setTitle("JIntellitype Test Application"); + center(mainFrame); + mainFrame.setVisible(true); + mainFrame.initJIntellitype(); + } + + /* + * (non-Javadoc) + * @see com.melloware.jintellitype.HotkeyListener#onHotKey(int) + */ + public void onHotKey(int aIdentifier) { + output("WM_HOTKEY message received " + Integer.toString(aIdentifier)); + } + + /* + * (non-Javadoc) + * @see com.melloware.jintellitype.IntellitypeListener#onIntellitype(int) + */ + public void onIntellitype(int aCommand) { + + switch (aCommand) { + case JIntellitype.APPCOMMAND_BROWSER_BACKWARD: + output("BROWSER_BACKWARD message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_FAVOURITES: + output("BROWSER_FAVOURITES message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_FORWARD: + output("BROWSER_FORWARD message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_HOME: + output("BROWSER_HOME message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_REFRESH: + output("BROWSER_REFRESH message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_SEARCH: + output("BROWSER_SEARCH message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_BROWSER_STOP: + output("BROWSER_STOP message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_LAUNCH_APP1: + output("LAUNCH_APP1 message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_LAUNCH_APP2: + output("LAUNCH_APP2 message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_LAUNCH_MAIL: + output("LAUNCH_MAIL message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_MEDIA_NEXTTRACK: + output("MEDIA_NEXTTRACK message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_MEDIA_PLAY_PAUSE: + output("MEDIA_PLAY_PAUSE message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_MEDIA_PREVIOUSTRACK: + output("MEDIA_PREVIOUSTRACK message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_MEDIA_STOP: + output("MEDIA_STOP message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_VOLUME_DOWN: + output("VOLUME_DOWN message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_VOLUME_UP: + output("VOLUME_UP message received " + Integer.toString(aCommand)); + break; + case JIntellitype.APPCOMMAND_VOLUME_MUTE: + output("VOLUME_MUTE message received " + Integer.toString(aCommand)); + break; + default: + output("Undefined INTELLITYPE message caught " + Integer.toString(aCommand)); + break; + } + } + + /** + * Centers window on desktop. + *

+ * @param aFrame the Frame to center + */ + private static void center(JFrame aFrame) { + final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + final Point centerPoint = ge.getCenterPoint(); + final Rectangle bounds = ge.getMaximumWindowBounds(); + final int w = Math.min(aFrame.getWidth(), bounds.width); + final int h = Math.min(aFrame.getHeight(), bounds.height); + final int x = centerPoint.x - (w / 2); + final int y = centerPoint.y - (h / 2); + aFrame.setBounds(x, y, w, h); + if ((w == bounds.width) && (h == bounds.height)) { + aFrame.setExtendedState(Frame.MAXIMIZED_BOTH); + } + aFrame.validate(); + } + + /** + * Method to register a hotkey using the RegisterHotKey Windows API call. + *

+ * @param aEvent the ActionEvent fired. + */ + private void btnRegisterHotKey_actionPerformed(ActionEvent aEvent) { + // assign the WINDOWS+A key to the unique id 88 for identification + JIntellitype.getInstance().registerHotKey(WINDOWS_A, JIntellitype.MOD_WIN, (int) 'A'); + JIntellitype.getInstance().registerHotKey(ALT_SHIFT_B, JIntellitype.MOD_ALT + JIntellitype.MOD_SHIFT, (int) 'B'); + JIntellitype.getInstance().registerSwingHotKey(CTRL_SHIFT_C, Event.CTRL_MASK + Event.SHIFT_MASK, (int) 'C'); + + // use a 0 for the modifier if you just want a single keystroke to be a hotkey + JIntellitype.getInstance().registerHotKey(PRINT_SCREEN, 0, 44); + JIntellitype.getInstance().registerHotKey(F9, 0, 120); + JIntellitype.getInstance().registerHotKey(F12, JIntellitype.MOD_ALT, 123); + JIntellitype.getInstance().registerHotKey(SEMICOLON, 0, 186); + // clear the text area + textArea.setText(""); + output("RegisterHotKey WINDOWS+A was assigned uniqueID 88"); + output("RegisterHotKey ALT+SHIFT+B was assigned uniqueID 89"); + output("RegisterHotKey CTRL+SHIFT+C was assigned uniqueID 90"); + output("RegisterHotKey PRINT_SCREEN was assigned uniqueID 91"); + output("RegisterHotKey F9 was assigned uniqueID 92"); + output("RegisterHotKey F12 was assigned uniqueID 93"); + output("RegisterHotKey SEMICOLON was assigned uniqueID 94"); + output("Press WINDOWS+A or ALT+SHIFT+B or CTRL+SHIFT+C in another application and you will see the debug output in the textarea."); + } + + /** + * Method to unregister a hotkey using the UnregisterHotKey Windows API call. + *

+ * @param aEvent the ActionEvent fired. + */ + private void btnUnregisterHotKey_actionPerformed(ActionEvent aEvent) { + JIntellitype.getInstance().unregisterHotKey(WINDOWS_A); + JIntellitype.getInstance().unregisterHotKey(ALT_SHIFT_B); + JIntellitype.getInstance().unregisterHotKey(CTRL_SHIFT_C); + JIntellitype.getInstance().unregisterHotKey(PRINT_SCREEN); + JIntellitype.getInstance().unregisterHotKey(F9); + JIntellitype.getInstance().unregisterHotKey(F12); + JIntellitype.getInstance().unregisterHotKey(SEMICOLON); + output("UnregisterHotKey WINDOWS+A"); + output("UnregisterHotKey ALT+SHIFT+B"); + output("UnregisterHotKey CTRL+SHIFT+C"); + output("UnregisterHotKey PRINT_SCREEN"); + output("UnregisterHotKey F9"); + output("UnregisterHotKey F12"); + output("UnregisterHotKey SEMICOLON"); + output("Press WINDOWS+A or ALT+SHIFT+B in another application and you will NOT see the debug output in the textarea."); + } + + /** + * This method is called from within the constructor to initialize the form. + */ + private void initComponents() { + mainPanel.setLayout(new BorderLayout()); + topPanel.setBorder(new EtchedBorder(1)); + bottomPanel.setLayout(new BorderLayout()); + bottomPanel.setBorder(new EtchedBorder(1)); + btnRegisterHotKey.setText("RegisterHotKey"); + btnRegisterHotKey.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + btnRegisterHotKey_actionPerformed(e); + } + }); + btnUnregisterHotKey.setText("UnregisterHotKey"); + btnUnregisterHotKey.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + btnUnregisterHotKey_actionPerformed(e); + } + }); + topPanel.add(btnRegisterHotKey); + topPanel.add(btnUnregisterHotKey); + scrollPane.getViewport().add(textArea); + bottomPanel.add(scrollPane, BorderLayout.CENTER); + mainPanel.add(topPanel, BorderLayout.NORTH); + mainPanel.add(bottomPanel, BorderLayout.CENTER); + + this.addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + // don't forget to clean up any resources before close + JIntellitype.getInstance().cleanUp(); + System.exit(0); + } + }); + + this.getContentPane().add(mainPanel); + this.pack(); + this.setSize(800, 600); + } + + /** + * Initialize the JInitellitype library making sure the DLL is located. + * + */ + public void initJIntellitype() { + try { + + // initialize JIntellitype with the frame so all windows commands can + // be attached to this window + JIntellitype.getInstance().addHotKeyListener(this); + JIntellitype.getInstance().addIntellitypeListener(this); + output("JIntellitype initialized"); + } catch (RuntimeException ex) { + output("Either you are not on Windows, or there is a problem with the JIntellitype library!"); + } + } + + /** + * Send the output to the log and the text area. + *

+ * @param text the text to output + */ + private void output(String text) { + textArea.append(text); + textArea.append("\n"); + } + +} \ No newline at end of file diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties new file mode 100644 index 0000000..f1454f6 --- /dev/null +++ b/src/test/resources/log4j.properties @@ -0,0 +1,29 @@ +################################################################### +# # +# Copyright 2006 Melloware Inc # +# # +# http://www.melloware.com # +# # +################################################################### + +log4j.rootLogger=DEBUG,stdout + +######################################################################## +# +# Appenders +# +######################################################################## + + +#### Appender writes to console +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{MM/dd/yyyy HH:mm:ss} %-5p - [%C{1}.%M:%L] %m %n + +#### jukes.log +log4j.appender.MELLOWARE = org.apache.log4j.FileAppender +log4j.appender.MELLOWARE.file = ${user.home}/.jintellitype/jintellitype.log +log4j.appender.MELLOWARE.layout = org.apache.log4j.PatternLayout +log4j.appender.MELLOWARE.layout.conversionPattern = %d{MM/dd/yyyy HH:mm:ss} %-5p - [%C{1}.%M:%L] %m %n +log4j.appender.MELLOWARE.append = false +