pull vendor

This commit is contained in:
2012-05-28 21:04:04 +02:00
parent a50f873d39
commit fb8741aaf3
506 changed files with 94940 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
#include "stdafx.h"
#include "JXInputManager.h"
#include "JXInput.h"
//
// Globals
//
extern HINSTANCE g_hInst;
JXInputManager::JXInputManager( HWND hWnd ) :
mhWnd( hWnd ),
mDeviceCounter( 0 )
{
for ( int i = 0; i < MAX_JXINPUTS; ++i )
{
mDevices[ i ] = NULL;
}
if ( FAILED( InitDirectInput( hWnd ) ) )
{
FreeDirectInput();
}
}
JXInputManager::~JXInputManager()
{
for ( int i = 0; i < getNumberOfJXInputs(); ++i )
{
delete mDevices[ i ];
mDevices[ i ] = NULL;
}
FreeDirectInput();
}
int JXInputManager::getNumberOfJXInputs() const
{
return mDeviceCounter;
}
JXInput& JXInputManager::getJXInput( int idx ) const
{
assert( idx < mDeviceCounter );
return * mDevices[ idx ];
}
int JXInputManager::getMaxNumberOfAxes() const
{
return JXINPUT_MAX_AXES;
}
int JXInputManager::getMaxNumberOfButtons() const
{
return JXINPUT_MAX_BUTTONS;
}
int JXInputManager::getMaxNumberOfDirectionals() const
{
return JXINPUT_MAX_DIRECTIONALS;
}
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT JXInputManager::InitDirectInput( HWND hWnd )
{
HRESULT hr;
// Register with the DirectInput subsystem and get a pointer
// to a IDirectInput interface we can use.
// Create a DInput object
if( FAILED( hr = DirectInput8Create( g_hInst, DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&mpDI, NULL ) ) )
return hr;
// Look for a simple joystick we can use for this sample program.
if( FAILED( hr = mpDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
EnumJoysticksCallback,
(VOID*)this, DIEDFL_ALLDEVICES /*| DIEDFL_INCLUDEPHANTOMS*/ ) ) )
return hr;
// Look for a other devices
if( FAILED( hr = mpDI->EnumDevices( DI8DEVCLASS_DEVICE,
EnumJoysticksCallback,
(VOID*)this, DIEDFL_ALLDEVICES /*| DIEDFL_INCLUDEPHANTOMS*/ ) ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FreeDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT JXInputManager::FreeDirectInput()
{
if ( NULL != mpDI )
mpDI->Release();
mpDI = NULL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK JXInputManager::EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
HRESULT hr;
LPDIRECTINPUTDEVICE8 pJoystick;
JXInputManager* pThis = (JXInputManager*)pContext;
//
// if the maximum number of devices is already registered,
// issue a warning and stop enumeration.
//
if( MAX_JXINPUTS == pThis->mDeviceCounter )
{
OutputDebugString( "Max. number of devices exceeded!" );
return DIENUM_STOP;
}
// Obtain an interface to the enumerated joystick.
hr = pThis->mpDI->CreateDevice( pdidInstance->guidInstance, &pJoystick, NULL );
// If it failed, then we can't use this joystick. (Maybe the user unplugged
// it while we were in the middle of enumerating it.)
if( FAILED(hr) )
return DIENUM_CONTINUE;
JXInput* pJ = new JXInput( pJoystick, pThis->mhWnd );
//
// only register useful devices
//
if( pJ->getNumberOfAxes() + pJ->getNumberOfButtons() + pJ->getNumberOfDirectionals() > 0 )
{
pThis->addJXInput( pJ );
}
else
{
delete pJ;
}
return DIENUM_CONTINUE;
}
/**
* Register a JXInput device.
*/
void JXInputManager::addJXInput( JXInput* pJ )
{
assert( mDeviceCounter < MAX_JXINPUTS );
if( mDeviceCounter < MAX_JXINPUTS )
mDevices[ mDeviceCounter++ ] = pJ;
}

47
vendor/JXInput/0.3.4/c/JXInputManager.h vendored Normal file
View File

@@ -0,0 +1,47 @@
// JXInputManager.h: Schnittstelle f<>r die Klasse JXInputManager.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_JXINPUTMANAGER_H__24862402_14C9_407D_8532_A16A6E3A7D64__INCLUDED_)
#define AFX_JXINPUTMANAGER_H__24862402_14C9_407D_8532_A16A6E3A7D64__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define MAX_JXINPUTS 10
class JXInput;
class JXINPUT_API JXInputManager
{
public:
JXInputManager( HWND hWnd );
virtual ~JXInputManager();
int getNumberOfJXInputs() const;
JXInput& getJXInput( int idx ) const;
//
// Numbering methods
//
int getMaxNumberOfAxes() const;
int getMaxNumberOfButtons() const;
int getMaxNumberOfDirectionals() const;
private:
LPDIRECTINPUT8 mpDI;
HWND mhWnd;
JXInput* mDevices[ MAX_JXINPUTS ];
int mDeviceCounter;
HRESULT InitDirectInput( HWND hWnd = NULL );
HRESULT FreeDirectInput();
static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext );
void addJXInput( JXInput* pJ );
};
#endif // !defined(AFX_JXINPUTMANAGER_H__24862402_14C9_407D_8532_A16A6E3A7D64__INCLUDED_)

37
vendor/JXInput/0.3.4/c/ReadMe.txt vendored Normal file
View File

@@ -0,0 +1,37 @@
========================================================================
DYNAMIC LINK LIBRARY : jxinput
========================================================================
Diese jxinput-DLL hat der Anwendungs-Assistent f<>r Sie erstellt.
Diese Datei enth<74>lt eine Zusammenfassung dessen, was Sie in jeder der Dateien
finden, die Ihre jxinput-Anwendung bilden.
jxinput.dsp
Diese Datei (Projektdatei) enth<74>lt Informationen auf Projektebene und wird zur
Erstellung eines einzelnen Projekts oder Teilprojekts verwendet. Andere Benutzer k<>nnen
die Projektdatei (.dsp) gemeinsam nutzen, sollten aber die Makefiles lokal exportieren.
jxinput.cpp
Dies ist die Hauptquellcodedatei f<>r die DLL.
jxinput.h
Diese Datei enth<74>lt Ihre DLL-Exporte.
/////////////////////////////////////////////////////////////////////////////
Weitere Standarddateien:
StdAfx.h, StdAfx.cpp
Diese Dateien werden zum Erstellen einer vorkompilierten Header-Datei (PCH) namens
jxinput.pch und einer vorkompilierten Typdatei namens StdAfx.obj verwendet.
/////////////////////////////////////////////////////////////////////////////
Weitere Hinweise:
Der Anwendungs-Assistent verwendet "ZU ERLEDIGEN:", um Bereiche des Quellcodes zu
kennzeichnen, die Sie hinzuf<75>gen oder anpassen sollten.
/////////////////////////////////////////////////////////////////////////////

9
vendor/JXInput/0.3.4/c/StdAfx.cpp vendored Normal file
View File

@@ -0,0 +1,9 @@
// stdafx.cpp : Quelltextdatei, die nur die Standard-Includes einbindet
// jxinput.pch ist die vorkompilierte Header-Datei
// stdafx.obj enth<74>lt die vorkompilierte Typinformation
#include "stdafx.h"
// ZU ERLEDIGEN: Verweis auf alle zus<75>tzlichen Header-Dateien, die Sie in STDAFX.H
// und nicht in dieser Datei ben<65>tigen

32
vendor/JXInput/0.3.4/c/StdAfx.h vendored Normal file
View File

@@ -0,0 +1,32 @@
// stdafx.h : Include-Datei f<>r Standard-System-Include-Dateien,
// oder projektspezifische Include-Dateien, die h<>ufig benutzt, aber
// in unregelm<6C><6D>igen Abst<73>nden ge<67>ndert werden.
//
#if !defined(AFX_STDAFX_H__68E14C76_098F_47ED_932B_4C01E8E9EFFB__INCLUDED_)
#define AFX_STDAFX_H__68E14C76_098F_47ED_932B_4C01E8E9EFFB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// F<>gen Sie hier Ihre Header-Dateien ein
#define WIN32_LEAN_AND_MEAN // Selten benutzte Teile der Windows-Header nicht einbinden
#define STRICT
#include <windows.h>
// ZU ERLEDIGEN: Verweisen Sie hier auf zus<75>tzliche Header-Dateien, die Ihr Programm ben<65>tigt
#ifdef JXINPUT_EXPORTS
#define JXINPUT_API __declspec(dllexport)
#else
#define JXINPUT_API __declspec(dllimport)
#endif
#include <dinput.h>
#include <assert.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ f<>gt zus<75>tzliche Deklarationen unmittelbar vor der vorherigen Zeile ein.
#endif // !defined(AFX_STDAFX_H__68E14C76_098F_47ED_932B_4C01E8E9EFFB__INCLUDED_)

View File

@@ -0,0 +1,279 @@
#include "stdafx.h"
#include "de_hardcode_jxinput_directinput_DirectInputDriver.h"
#include "jxinput.h"
#include "JXInputManager.h"
//
// Globals
//
extern HINSTANCE g_hInst;
static JXInputManager* pJXInputManager = NULL;
static JXInput* apJXInput[ MAX_JXINPUTS ];
static HWND hWndJava;
//
// IDs of the static Java arrays.
//
static jfieldID sAxesFieldID;
static jfieldID sButtonsFieldID;
static jfieldID sDirectionsFieldID;
/**
* Remove all resources allocated by the Java binding.
*/
void shutdownJavaResources()
{
if ( NULL != pJXInputManager )
delete pJXInputManager;
if ( NULL != hWndJava )
DestroyWindow( hWndJava );
pJXInputManager = NULL;
for( int i = 0; i < MAX_JXINPUTS; ++i )
apJXInput[ i ] = NULL;
hWndJava = NULL;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
return JNI_VERSION_1_2;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
shutdownJavaResources();
}
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeinit
(JNIEnv * penv, jclass pClazz )
{
//
// Create a non-visible window as 'owner' of the DI device.
//
hWndJava = CreateWindowEx(
0/*WS_EX_APPWINDOW*/, // DWORD dwExStyle, // extended window style
"STATIC", // LPCTSTR lpClassName, // pointer to registered class name
NULL, // LPCTSTR lpWindowName, // pointer to window name
0/*WS_CAPTION*/, // DWORD dwStyle, // window style
0, // int x, // horizontal position of window
0, // int y, // vertical position of window
0, // int nWidth, // window width
0, // int nHeight, // window height
NULL, // HWND hWndParent, // handle to parent or owner window
NULL, // HMENU hMenu, // handle to menu, or child-window identifier
g_hInst, // HINSTANCE hInstance, // handle to application instance
NULL // LPVOID lpParam // pointer to window-creation data
);
if ( NULL == pJXInputManager )
{
pJXInputManager = new JXInputManager( hWndJava );
for( int i = 0; i < MAX_JXINPUTS; ++i )
apJXInput[ i ] = NULL;
for ( int i = 0; i < pJXInputManager->getNumberOfJXInputs(); ++i )
{
apJXInput[ i ] = & pJXInputManager->getJXInput( i );
}
}
return true;
}
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeexit
(JNIEnv *, jclass )
{
shutdownJavaResources();
}
/**
* Bind my field IDs to the Java variables.
*/
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_bind
(JNIEnv * penv, jclass pClazz)
{
//
// All fields are static.
//
sAxesFieldID = penv->GetStaticFieldID( pClazz, "sAxisValues", "[[D" );
sButtonsFieldID = penv->GetStaticFieldID( pClazz, "sButtonStates", "[[Z" );
sDirectionsFieldID = penv->GetStaticFieldID( pClazz, "sDirectionalValues", "[[I" );
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfDevices
(JNIEnv *penv, jclass)
{
return pJXInputManager->getNumberOfJXInputs();
}
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getName
(JNIEnv *penv, jclass, jint dev)
{
return penv->NewStringUTF( apJXInput[ dev ]->getName() );
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfAxes
(JNIEnv *, jclass, jint dev)
{
return apJXInput[ dev ]->getNumberOfAxes();
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfButtons
(JNIEnv *, jclass, jint dev)
{
return apJXInput[ dev ]->getNumberOfButtons();
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfDirectionals
(JNIEnv *, jclass, jint dev)
{
return apJXInput[ dev ]->getNumberOfDirectionals();
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfAxes
(JNIEnv *, jclass)
{
return pJXInputManager->getMaxNumberOfAxes();
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfButtons
(JNIEnv *, jclass)
{
return pJXInputManager->getMaxNumberOfButtons();
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfDirectionals
(JNIEnv *, jclass)
{
return pJXInputManager->getMaxNumberOfDirectionals();
}
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isAxisAvailable
(JNIEnv *, jclass, jint dev, jint idx )
{
return apJXInput[ dev ]->isAxisAvailable( idx );
}
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getAxisName
(JNIEnv *penv, jclass, jint dev, jint idx )
{
return penv->NewStringUTF( apJXInput[ dev ]->getAxisName( idx ) );
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getAxisType
(JNIEnv *, jclass, jint dev, jint idx )
{
return apJXInput[ dev ]->getAxisType( idx );
}
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isButtonAvailable
(JNIEnv *, jclass, jint dev, jint idx )
{
return apJXInput[ dev ]->isButtonAvailable( idx );
}
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getButtonName
(JNIEnv *penv, jclass, jint dev, jint idx )
{
return penv->NewStringUTF( apJXInput[ dev ]->getButtonName( idx ) );
}
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getButtonType
(JNIEnv *, jclass, jint dev, jint idx )
{
return apJXInput[ dev ]->getButtonType( idx );
}
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isDirectionalAvailable
(JNIEnv *, jclass, jint dev, jint idx )
{
return apJXInput[ dev ]->isDirectionalAvailable( idx );
}
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getDirectionalName
(JNIEnv *penv, jclass, jint dev, jint idx )
{
return penv->NewStringUTF( apJXInput[ dev ]->getDirectionalName( idx ) );
}
/**
* The main update method.
* Here, the actual work is done.
*/
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeupdate
(JNIEnv * penv, jclass pClazz )
{
static jdouble axes [ MAX_JXINPUTS ][ JXINPUT_MAX_AXES ];
static jboolean buttons [ MAX_JXINPUTS ][ JXINPUT_MAX_BUTTONS ];
static jint directions [ MAX_JXINPUTS ][ JXINPUT_MAX_DIRECTIONALS ];
static jobjectArray axisarrayarray;
static jobjectArray buttonarrayarray;
static jobjectArray directionarrayarray;
static jdoubleArray axisarray;
static jbooleanArray buttonarray;
static jintArray directionarray;
axisarrayarray = (jobjectArray)penv->GetStaticObjectField( pClazz, sAxesFieldID );
buttonarrayarray = (jobjectArray)penv->GetStaticObjectField( pClazz, sButtonsFieldID );
directionarrayarray = (jobjectArray)penv->GetStaticObjectField( pClazz, sDirectionsFieldID );
//
// For each device....
//
for ( int dev = 0; dev < pJXInputManager->getNumberOfJXInputs(); ++dev )
{
// Do the update of the device.
apJXInput[ dev ]->update();
//
// Copy all values into my arrays.
//
for ( int i = 0; i < JXINPUT_MAX_AXES; ++i )
axes[ dev ][ i ] = apJXInput[ dev ]->getAxisValue( i );
for ( int i = 0; i < JXINPUT_MAX_BUTTONS; ++i )
buttons[ dev ][ i ] = apJXInput[ dev ]->isButtonDown( i );
for ( int i = 0; i < JXINPUT_MAX_DIRECTIONALS; ++i )
directions[ dev ][ i ] = apJXInput[ dev ]->getDirection( i );
//
// Move my arrays to the Java arrays.
//
axisarray = (jdoubleArray)penv->GetObjectArrayElement( axisarrayarray, dev );
penv->SetDoubleArrayRegion( axisarray, 0, JXINPUT_MAX_AXES, axes[ dev ] );
buttonarray = (jbooleanArray)penv->GetObjectArrayElement( buttonarrayarray, dev );
penv->SetBooleanArrayRegion( buttonarray, 0, JXINPUT_MAX_BUTTONS, buttons[ dev ] );
directionarray = (jintArray)penv->GetObjectArrayElement( directionarrayarray, dev );
penv->SetIntArrayRegion( directionarray, 0, JXINPUT_MAX_DIRECTIONALS, directions[ dev ] );
}
}

View File

@@ -0,0 +1,183 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class de_hardcode_jxinput_directinput_DirectInputDriver */
#ifndef _Included_de_hardcode_jxinput_directinput_DirectInputDriver
#define _Included_de_hardcode_jxinput_directinput_DirectInputDriver
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: sIsOperational */
/* Inaccessible static: sAxisValues */
/* Inaccessible static: sButtonStates */
/* Inaccessible static: sDirectionalValues */
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: nativeinit
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeinit
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: nativeexit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeexit
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: bind
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_bind
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getNumberOfDevices
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfDevices
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getName
(JNIEnv *, jclass, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getNumberOfAxes
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfAxes
(JNIEnv *, jclass, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getNumberOfButtons
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfButtons
(JNIEnv *, jclass, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getNumberOfDirectionals
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getNumberOfDirectionals
(JNIEnv *, jclass, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getMaxNumberOfAxes
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfAxes
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getMaxNumberOfButtons
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfButtons
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getMaxNumberOfDirectionals
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getMaxNumberOfDirectionals
(JNIEnv *, jclass);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: isAxisAvailable
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isAxisAvailable
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getAxisName
* Signature: (II)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getAxisName
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getAxisType
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getAxisType
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: isButtonAvailable
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isButtonAvailable
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getButtonName
* Signature: (II)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getButtonName
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getButtonType
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getButtonType
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: isDirectionalAvailable
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_isDirectionalAvailable
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: getDirectionalName
* Signature: (II)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_getDirectionalName
(JNIEnv *, jclass, jint, jint);
/*
* Class: de_hardcode_jxinput_directinput_DirectInputDriver
* Method: nativeupdate
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_de_hardcode_jxinput_directinput_DirectInputDriver_nativeupdate
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif

24
vendor/JXInput/0.3.4/c/dllmain.cpp vendored Normal file
View File

@@ -0,0 +1,24 @@
#include "stdafx.h"
HINSTANCE g_hInst;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = (HINSTANCE)hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
g_hInst = NULL;
break;
}
return TRUE;
}

600
vendor/JXInput/0.3.4/c/jxinput.cpp vendored Normal file
View File

@@ -0,0 +1,600 @@
//
// jxinput.cpp
//
#include "stdafx.h"
#include "jxinput.h"
//
// Globals
//
extern HINSTANCE g_hInst;
/**
* Ctor: Connect with DI
*/
JXInput::JXInput( LPDIRECTINPUTDEVICE8 pJoystick, HWND hWnd ) :
mpJoystick( pJoystick ),
mSliderCount( 0 ),
mPOVCount( 0 ),
mButtonCount( 0 )
{
initAxisConfig();
initButtonsConfig();
initDirectionalsConfig();
if ( FAILED( InitDirectInput( hWnd ) ) )
{
FreeDirectInput();
}
}
/**
* Destructor:
* Free DirectInput.
*/
JXInput::~JXInput()
{
FreeDirectInput();
}
void JXInput::update()
{
UpdateInputState();
}
TCHAR * const JXInput::getName() const
{
return (TCHAR*)mdiDevInfo.tszInstanceName;
}
int JXInput::getNumberOfAxes() const
{
return mdiDevCaps.dwAxes;
}
int JXInput::getNumberOfButtons() const
{
return mButtonCount;
}
int JXInput::getNumberOfDirectionals() const
{
return mPOVCount;
}
double JXInput::getAxisValueHelper( LONG val, int idx ) const
{
const AxisConfig& cfg = mAxisConfig[ idx ];
double span = (double)( cfg.mMaxValue - cfg.mMinValue );
double ret = (double)(val - cfg.mMinValue) / span;
if ( TYPE_SLIDER != cfg.mType )
return ret*2.0 - 1.0;
return ret;
}
double JXInput::getX() const
{
return getAxisValueHelper( mJS.lX, ID_X );
}
double JXInput::getY() const
{
return getAxisValueHelper( mJS.lY, ID_Y );
}
double JXInput::getZ() const
{
return getAxisValueHelper( mJS.lZ, ID_Z );
}
double JXInput::getRotX() const
{
return getAxisValueHelper( mJS.lRx, ID_ROTX );
}
double JXInput::getRotY() const
{
return getAxisValueHelper( mJS.lRy, ID_ROTY );
}
double JXInput::getRotZ() const
{
return getAxisValueHelper( mJS.lRz, ID_ROTZ );
}
double JXInput::getSlider0() const
{
return getAxisValueHelper( mJS.rglSlider[ 0 ], ID_SLIDER0 );
}
double JXInput::getSlider1() const
{
return getAxisValueHelper( mJS.rglSlider[ 1 ], ID_SLIDER1 );
}
bool JXInput::isAxisAvailable( int idx ) const
{
assert( idx < JXINPUT_MAX_AXES );
return mAxisConfig[ idx ].mIsAvailable;
}
TCHAR * const JXInput::getAxisName( int idx ) const
{
assert( idx < JXINPUT_MAX_AXES );
return (char*const)mAxisConfig[ idx ].mName;
}
int JXInput::getAxisType( int idx ) const
{
assert( idx < JXINPUT_MAX_AXES );
return mAxisConfig[ idx ].mType;
}
double JXInput::getAxisValue( int idx ) const
{
assert( idx < JXINPUT_MAX_AXES );
// Failsafe if called accidentally
if ( ! mAxisConfig[ idx ].mIsAvailable )
return 0.0;
return (this->*mAxisConfig[ idx ].mGetValueMethod)();
}
bool JXInput::isButtonAvailable( int idx ) const
{
assert( idx < JXINPUT_MAX_BUTTONS );
return mButtonConfig[ idx ].mIsAvailable;
}
TCHAR * const JXInput::getButtonName( int idx ) const
{
assert( idx < JXINPUT_MAX_BUTTONS );
return (char*const)mButtonConfig[ idx ].mName;
}
int JXInput::getButtonType( int idx ) const
{
assert( idx < JXINPUT_MAX_BUTTONS );
return mButtonConfig[ idx ].mType;
}
bool JXInput::isButtonDown( int idx ) const
{
assert( idx < JXINPUT_MAX_BUTTONS );
return 0 != mJS.rgbButtons[ idx ] ;
}
bool JXInput::isDirectionalAvailable( int idx ) const
{
assert( idx < JXINPUT_MAX_DIRECTIONALS );
return mDirectionalConfig[ idx ].mIsAvailable;
}
TCHAR * const JXInput::getDirectionalName( int idx ) const
{
assert( idx < JXINPUT_MAX_DIRECTIONALS );
return (char*const)mDirectionalConfig[ idx ].mName;
}
int JXInput::getDirection( int idx ) const
{
assert( idx < JXINPUT_MAX_DIRECTIONALS );
return mJS.rgdwPOV[ idx ] ;
}
/**
* Initialize axis configuration array.
*/
void JXInput::initAxisConfig()
{
mAxisConfig[ ID_X ].mIsAvailable = false;
mAxisConfig[ ID_X ].mType = TYPE_TRANSLATION;
mAxisConfig[ ID_X ].mGetValueMethod = &JXInput::getX;
mAxisConfig[ ID_Y ].mIsAvailable = false;
mAxisConfig[ ID_Y ].mType = TYPE_TRANSLATION;
mAxisConfig[ ID_Y ].mGetValueMethod = &JXInput::getY;
mAxisConfig[ ID_Z ].mIsAvailable = false;
mAxisConfig[ ID_Z ].mType = TYPE_TRANSLATION;
mAxisConfig[ ID_Z ].mGetValueMethod = &JXInput::getZ;
mAxisConfig[ ID_ROTX ].mIsAvailable = false;
mAxisConfig[ ID_ROTX ].mType = TYPE_ROTATION;
mAxisConfig[ ID_ROTX ].mGetValueMethod = &JXInput::getRotX;
mAxisConfig[ ID_ROTY ].mIsAvailable = false;
mAxisConfig[ ID_ROTY ].mType = TYPE_ROTATION;
mAxisConfig[ ID_ROTY ].mGetValueMethod = &JXInput::getRotY;
mAxisConfig[ ID_ROTZ ].mIsAvailable = false;
mAxisConfig[ ID_ROTZ ].mType = TYPE_ROTATION;
mAxisConfig[ ID_ROTZ ].mGetValueMethod = &JXInput::getRotZ;
mAxisConfig[ ID_SLIDER0 ].mIsAvailable = false;
mAxisConfig[ ID_SLIDER0 ].mType = TYPE_SLIDER;
mAxisConfig[ ID_SLIDER0 ].mGetValueMethod = &JXInput::getSlider0;
mAxisConfig[ ID_SLIDER1 ].mIsAvailable = false;
mAxisConfig[ ID_SLIDER1 ].mType = TYPE_SLIDER;
mAxisConfig[ ID_SLIDER1 ].mGetValueMethod = &JXInput::getSlider1;
}
/**
* Initialize buttons configuration array.
*/
void JXInput::initButtonsConfig()
{
for ( int i = 0; i < JXINPUT_MAX_BUTTONS; ++i )
{
mButtonConfig[ i ].mIsAvailable = false;
mButtonConfig[ i ].mName[ 0 ] = '\0';
mButtonConfig[ i ].mType = TYPE_PUSHBUTTON;
}
}
/**
* Initialize directionals configuration array.
*/
void JXInput::initDirectionalsConfig()
{
for ( int i = 0; i < JXINPUT_MAX_DIRECTIONALS; ++i )
{
mDirectionalConfig[ i ].mIsAvailable = false;
mDirectionalConfig[ i ].mName[ 0 ] = '\0';
}
}
//-----------------------------------------------------------------------------
// Name: EnumAxesCallback()
// Desc: Callback function for enumerating the axes on a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK JXInput::EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
JXInput* pThis = (JXInput*)pContext;
AxisConfig* pAxCfg = NULL;
// Set the UI to reflect what objects the joystick supports
// Code derived from M$ samples, really sucks, eh?
if (pdidoi->guidType == GUID_XAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_X ];
}
if (pdidoi->guidType == GUID_YAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_Y ];
}
if (pdidoi->guidType == GUID_ZAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_Z ];
}
if (pdidoi->guidType == GUID_RxAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_ROTX ];
}
if (pdidoi->guidType == GUID_RyAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_ROTY ];
}
if (pdidoi->guidType == GUID_RzAxis)
{
pAxCfg = & pThis->mAxisConfig[ ID_ROTZ ];
}
if (pdidoi->guidType == GUID_Slider)
{
switch( pThis->mSliderCount++ )
{
case 0 :
pAxCfg = & pThis->mAxisConfig[ ID_SLIDER0 ];
break;
case 1 :
pAxCfg = & pThis->mAxisConfig[ ID_SLIDER1 ];
break;
}
}
// fail-safe
if( NULL == pAxCfg ) // e.g. GUID_Unknown
return DIENUM_CONTINUE;
//
// Perform config.
//
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
// Get the range for the axis
if( FAILED( pThis->mpJoystick->GetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_CONTINUE;
pAxCfg->mMinValue = diprg.lMin;
pAxCfg->mMaxValue = diprg.lMax;
strcpy( (char*)pAxCfg->mName, (char*)pdidoi->tszName );
pAxCfg->mIsAvailable = true;
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumButtonsCallback()
// Desc: Callback function for enumerating the axes on a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK JXInput::EnumButtonsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
JXInput* pThis = (JXInput*)pContext;
//
// if the maximum number of buttons is already registered,
// issue a warning and stop enumeration.
//
if( JXINPUT_MAX_BUTTONS == pThis->mButtonCount )
{
OutputDebugString( "Max. number of buttons exceeded!" );
return DIENUM_STOP;
}
ButtonConfig* pBtCfg = NULL;
if ( pdidoi->guidType == GUID_Button )
{
assert( JXINPUT_MAX_BUTTONS > pThis->mButtonCount );
pBtCfg = & pThis->mButtonConfig[ pThis->mButtonCount++ ];
}
// fail-safe
if( NULL == pBtCfg ) // e.g. unknown stuff
return DIENUM_CONTINUE;
assert( NULL != pBtCfg );
//
// Perform config.
//
strcpy( (char*)pBtCfg->mName, (char*)pdidoi->tszName );
pBtCfg->mIsAvailable = true;
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumPOVsCallback()
// Desc: Callback function for enumerating the axes on a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK JXInput::EnumPOVsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
JXInput* pThis = (JXInput*)pContext;
//
// if the maximum number of buttons is already registered,
// issue a warning and stop enumeration.
//
if( JXINPUT_MAX_DIRECTIONALS == pThis->mPOVCount )
{
OutputDebugString( "Max. number of POVs exceeded!" );
return DIENUM_STOP;
}
DirectionalConfig* pDirCfg = NULL;
if (pdidoi->guidType == GUID_POV)
{
assert( JXINPUT_MAX_DIRECTIONALS > pThis->mPOVCount );
pDirCfg = & pThis->mDirectionalConfig[ pThis->mPOVCount++ ];
}
// fail-safe
if( NULL == pDirCfg ) // e.g. unknown stuff
return DIENUM_CONTINUE;
assert( NULL != pDirCfg );
//
// Perform config.
//
strcpy( (char*)pDirCfg->mName, (char*)pdidoi->tszName );
pDirCfg->mIsAvailable = true;
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumEffectsCallback()
// Desc: Callback function for enumerating the effects of a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK JXInput::EnumEffectsCallback( const DIEFFECTINFO* pdidoi,
VOID* pContext )
{
JXInput* pThis = (JXInput*)pContext;
//
// Work on that!!
//
return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT JXInput::InitDirectInput( HWND hWnd )
{
HRESULT hr;
// Make sure we got a joystick
if( NULL == mpJoystick )
{
return E_FAIL;
}
//
// Ask the device for some useful information.
//
mdiDevInfo.dwSize = sizeof( DIDEVICEINSTANCE );
hr = mpJoystick->GetDeviceInfo( &mdiDevInfo );
if( FAILED(hr) )
return hr;
// Set the data format to "simple joystick" - a predefined data format
//
// A data format specifies which controls on a device we are interested in,
// and how they should be reported. This tells DInput that we will be
// passing a DIJOYSTATE structure to IDirectInputDevice::GetDeviceState().
hr = mpJoystick->SetDataFormat( &c_dfDIJoystick2 );
if( FAILED(hr) )
return hr;
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
// hr = g_pJoystick->SetCooperativeLevel( hDlg, DISCL_EXCLUSIVE|DISCL_FOREGROUND );
DWORD mode = ( NULL == hWnd ? DISCL_NONEXCLUSIVE|DISCL_BACKGROUND : DISCL_EXCLUSIVE|DISCL_BACKGROUND );
hr = mpJoystick->SetCooperativeLevel( hWnd, mode );
if( FAILED(hr) )
return hr;
// Determine how many axis the joystick has (so we don't error out setting
// properties for unavailable axis)
mdiDevCaps.dwSize = sizeof(DIDEVCAPS);
hr = mpJoystick->GetCapabilities(&mdiDevCaps);
if ( FAILED(hr) )
return hr;
// Enumerate the axes of the joyctick and set the range of each axis. Note:
// we could just use the defaults, but we're just trying to show an example
// of enumerating device objects (axes, buttons, etc.).
mpJoystick->EnumObjects( EnumAxesCallback, (VOID*)this, DIDFT_AXIS );
mpJoystick->EnumObjects( EnumButtonsCallback, (VOID*)this, DIDFT_BUTTON );
mpJoystick->EnumObjects( EnumPOVsCallback, (VOID*)this, DIDFT_POV );
mpJoystick->EnumEffects( EnumEffectsCallback, (VOID*)this, DIEFT_ALL );
// For FF sticks, switch on autocenter as long as we do not use real FF
SwitchAutoCenter( true );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: UpdateInputState()
// Desc: Get the input device's state and display it.
//-----------------------------------------------------------------------------
HRESULT JXInput::UpdateInputState()
{
HRESULT hr;
if( mpJoystick )
{
// Poll the device to read the current state
hr = mpJoystick->Poll();
if( FAILED(hr) )
{
// DInput is telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We
// just re-acquire and try again.
hr = mpJoystick->Acquire();
while( hr == DIERR_INPUTLOST )
hr = mpJoystick->Acquire();
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return S_OK;
}
// Get the input's device state
if( FAILED( hr = mpJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &mJS ) ) )
return hr; // The device should have been acquired during the Poll()
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FreeDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT JXInput::FreeDirectInput()
{
// Unacquire and release any DirectInputDevice objects.
if( NULL != mpJoystick )
{
// Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired.
mpJoystick->Unacquire();
mpJoystick->Release();
mpJoystick = NULL;
}
return S_OK;
}
HRESULT JXInput::SwitchAutoCenter( bool onoff )
{
HRESULT hr;
DIPROPDWORD DIPropAutoCenter;
DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter);
DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
DIPropAutoCenter.diph.dwObj = 0;
DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
DIPropAutoCenter.dwData = ( onoff ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF );
hr = mpJoystick->SetProperty( DIPROP_AUTOCENTER, &DIPropAutoCenter.diph );
return hr;
}

175
vendor/JXInput/0.3.4/c/jxinput.dsp vendored Normal file
View File

@@ -0,0 +1,175 @@
# Microsoft Developer Studio Project File - Name="jxinput" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=jxinput - Win32 Debug
!MESSAGE Dies ist kein g<>ltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f<>hren Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "jxinput.mak".
!MESSAGE
!MESSAGE Sie k<>nnen beim Ausf<73>hren von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "jxinput.mak" CFG="jxinput - Win32 Debug"
!MESSAGE
!MESSAGE F<>r die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "jxinput - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE "jxinput - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "jxinput - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JXINPUT_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\j2sdk1.4.2\include" /I "C:\j2sdk1.4.2\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JXINPUT_EXPORTS" /FR /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 dxguid.lib dinput8.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\build\jxinput.dll"
!ELSEIF "$(CFG)" == "jxinput - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JXINPUT_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\j2sdk1.4.2\include" /I "C:\j2sdk1.4.2\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JXINPUT_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 dxguid.lib dinput8.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\Classes\jxinput.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "jxinput - Win32 Release"
# Name "jxinput - Win32 Debug"
# Begin Group "Quellcodedateien"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\de_hardcode_jxinput_directinput_DirectInputDriver.cpp
# End Source File
# Begin Source File
SOURCE=.\dllmain.cpp
# End Source File
# Begin Source File
SOURCE=.\jxinput.cpp
# End Source File
# Begin Source File
SOURCE=.\JXInputManager.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header-Dateien"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\de_hardcode_jxinput_directinput_DirectInputDriver.h
!IF "$(CFG)" == "jxinput - Win32 Release"
# PROP Ignore_Default_Tool 1
USERDEP__DE_HA="..\classes\de\hardcode\jxinput\directinput\DirectInputDriver.class"
# Begin Custom Build
InputPath=.\de_hardcode_jxinput_directinput_DirectInputDriver.h
"de_hardcode_jxinput_directinput_DirectInputDriver.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cd ..\Classes
C:\j2sdk1.4.2\bin\javah -classpath . -d ..\win32 de.hardcode.jxinput.directinput.DirectInputDriver
cd ..\win32
# End Custom Build
!ELSEIF "$(CFG)" == "jxinput - Win32 Debug"
# PROP Ignore_Default_Tool 1
USERDEP__DE_HA="..\classes\de\hardcode\jxinput\directinput\DirectInputDriver.class"
# Begin Custom Build
InputPath=.\de_hardcode_jxinput_directinput_DirectInputDriver.h
"de_hardcode_jxinput_directinput_DirectInputDriver.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cd ..\Classes
C:\j2sdk1.4.2\bin\javah -classpath . -d ..\win32 de.hardcode.jxinput.directinput.DirectInputDriver
cd ..\win32
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\jxinput.h
# End Source File
# Begin Source File
SOURCE=.\JXInputManager.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Ressourcendateien"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

29
vendor/JXInput/0.3.4/c/jxinput.dsw vendored Normal file
View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GEL<45>SCHT WERDEN!
###############################################################################
Project: "jxinput"=".\jxinput.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

183
vendor/JXInput/0.3.4/c/jxinput.h vendored Normal file
View File

@@ -0,0 +1,183 @@
#define JXINPUT_MAX_AXES 8
#define JXINPUT_MAX_BUTTONS 256
#define JXINPUT_MAX_DIRECTIONALS 4
/**
* This class will be exported by jxinput.dll.
*/
class JXINPUT_API JXInput
{
public:
typedef enum AXISTYPE
{
TYPE_TRANSLATION,
TYPE_ROTATION,
TYPE_SLIDER
};
typedef enum BUTTONTYPE
{
TYPE_PUSHBUTTON,
TYPE_TOGGLEBUTTON
};
typedef enum AXISID
{
ID_X, ID_Y, ID_Z,
ID_ROTX, ID_ROTY, ID_ROTZ,
ID_SLIDER0, ID_SLIDER1
};
//
// Ctor
//
JXInput( LPDIRECTINPUTDEVICE8 pJoystick, HWND hWnd = NULL );
//
// Dtor
//
virtual ~JXInput();
//
// Operational methods
//
void update();
// Ask for the name
TCHAR * const getName() const;
//
// Numbering methods
//
int getNumberOfAxes() const;
int getNumberOfButtons() const;
int getNumberOfDirectionals() const;
//
// Access axes
//
double getX() const; /** -1.0 .... 1.0 */
double getY() const; /** -1.0 .... 1.0 */
double getZ() const; /** -1.0 .... 1.0 */
double getRotX() const; /** -1.0 .... 1.0 */
double getRotY() const; /** -1.0 .... 1.0 */
double getRotZ() const; /** -1.0 .... 1.0 */
double getSlider0() const; /** 0.0 .... 1.0 */
double getSlider1() const; /** 0.0 .... 1.0 */
//
// Axis methods
//
bool isAxisAvailable( int idx ) const;
TCHAR* const getAxisName( int idx ) const;
int getAxisType( int idx ) const;
double getAxisValue( int idx ) const;
//
// Button methods
//
bool isButtonAvailable( int idx ) const;
TCHAR* const getButtonName( int idx ) const;
int getButtonType( int idx ) const;
bool isButtonDown( int idx ) const;
//
// Directional methods
//
bool isDirectionalAvailable( int idx ) const;
TCHAR* const getDirectionalName( int idx ) const;
int getDirection( int idx ) const;
private://-----------------------------------------------------------------------------------------
LPDIRECTINPUTDEVICE8 mpJoystick;
DIDEVICEINSTANCE mdiDevInfo;
DIDEVCAPS mdiDevCaps;
DIJOYSTATE2 mJS; // DInput joystick state
int mSliderCount;
int mPOVCount;
int mButtonCount;
double getAxisValueHelper( LONG val, int idx ) const;
HRESULT SwitchAutoCenter( bool onoff = true );
HRESULT InitDirectInput( HWND hWnd = NULL );
HRESULT FreeDirectInput();
HRESULT UpdateInputState();
static BOOL CALLBACK EnumAxesCallback
(
const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext
);
static BOOL CALLBACK EnumButtonsCallback
(
const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext
);
static BOOL CALLBACK EnumPOVsCallback
(
const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext
);
static BOOL CALLBACK EnumEffectsCallback
(
const DIEFFECTINFO* pdidoi,
VOID* pContext
);
class JXINPUT_API AxisConfig
{
public:
bool mIsAvailable;
CHAR mName[MAX_PATH];
AXISTYPE mType;
LONG mMinValue;
LONG mMaxValue;
double (JXInput::*mGetValueMethod)() const;
} mAxisConfig [ JXINPUT_MAX_AXES ];
void initAxisConfig();
class JXINPUT_API ButtonConfig
{
public:
bool mIsAvailable;
CHAR mName[MAX_PATH];
BUTTONTYPE mType;
} mButtonConfig[ JXINPUT_MAX_BUTTONS ];
void initButtonsConfig();
class JXINPUT_API DirectionalConfig
{
public:
bool mIsAvailable;
CHAR mName[MAX_PATH];
} mDirectionalConfig[ JXINPUT_MAX_DIRECTIONALS ];
void initDirectionalsConfig();
};

20
vendor/JXInput/0.3.4/c/jxinput.sln vendored Normal file
View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jxinput", "jxinput.vcproj", "{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}.Debug|Win32.ActiveCfg = Debug|Win32
{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}.Debug|Win32.Build.0 = Debug|Win32
{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}.Release|Win32.ActiveCfg = Release|Win32
{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

367
vendor/JXInput/0.3.4/c/jxinput.vcproj vendored Normal file
View File

@@ -0,0 +1,367 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="jxinput"
ProjectGUID="{8AEA84DC-D8F0-4425-BEBF-A84E91115F76}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/jxinput.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="C:\Programme\Java\jdk1.5.0_06\include;C:\Programme\Java\jdk1.5.0_06\include\win32"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JXINPUT_EXPORTS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/jxinput.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1031"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib user32.lib"
OutputFile="..\build\jxinput.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/jxinput.pdb"
ImportLibrary=".\Release/jxinput.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/jxinput.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\classes"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/jxinput.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="C:\Programme\Java\jdk1.5.0_06\include;C:\Programme\Java\jdk1.5.0_06\include\win32"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JXINPUT_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/jxinput.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1031"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib dinput8.lib user32.lib"
OutputFile="..\Classes\jxinput.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/jxinput.pdb"
ImportLibrary=".\Debug/jxinput.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/jxinput.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Quellcodedateien"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="de_hardcode_jxinput_directinput_DirectInputDriver.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="dllmain.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="jxinput.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="JXInputManager.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="StdAfx.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header-Dateien"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="de_hardcode_jxinput_directinput_DirectInputDriver.h"
>
</File>
<File
RelativePath="jxinput.h"
>
</File>
<File
RelativePath="JXInputManager.h"
>
</File>
<File
RelativePath="StdAfx.h"
>
</File>
</Filter>
<Filter
Name="Ressourcendateien"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
<File
RelativePath="ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,72 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 19. Dezember 2001, 21:58
//**********************************************************************************************
package de.hardcode.jxinput;
/**
* The Axis interface describes the most common feature of a joystick or other input devices.
*
* @author Herkules
*/
public interface Axis extends Feature
{
// Enumeration of axes.
final static int ID_X = 0;
final static int ID_Y = 1;
final static int ID_Z = 2;
final static int ID_ROTX = 3;
final static int ID_ROTY = 4;
final static int ID_ROTZ = 5;
final static int ID_SLIDER0 = 6;
final static int ID_SLIDER1 = 7;
final static int NUMBER_OF_ID = 8;
// Enumeration of axis types
final static int TRANSLATION = 0;
final static int ROTATION = 1;
final static int SLIDER = 2;
/**
* Retrieve the type of the axis.
* The type is describes the meaning and the range of values of the axis.
* <p>
* <code>TRANSLATION</code> typed axes denote a translational deviation from a center
* position. This can be e.g. the common, basic joystick axes.
* The range of <code>getValue()</code> is <code>[-1.0,1.0]</code>.
* <p>
* <code>ROTATION</code> typed axes denote a rotational deviation from a center
* position. Something on the stick is turned or twisted.
* The range of <code>getValue()</code> is <code>[-1.0,1.0]</code>.
* <p>
* <code>SLIDER</code> typed axes denote a shifting device without a center position.
* A good sample is a throttle control.
* The range of <code>getValue()</code> is <code>[0.0,1.0]</code>.
*
* @return [ TRANSLATION | ROTATION | SLIDER ]
*/
int getType();
/**
* Returns the current value of the axis.
* The range of the result depends on the axis type.
*
* @return value [-1.0,1.0] or [0.0,1.0]
*/
double getValue();
/**
* Inform about the resolution of the axis.
*
* @return resolution, e.g. 2^-16
*/
double getResolution();
}

View File

@@ -0,0 +1,35 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 19. Dezember 2001, 21:58
//**********************************************************************************************
package de.hardcode.jxinput;
/**
*
* @author Herkules
*/
public interface Button extends Feature
{
// Enumeration of button types
final static int PUSHBUTTON = 0;
final static int TOGGLEBUTTON = 1;
/**
* Retrieve the type of the button.
* Pushbutton will deliver <code>true==getState()</code> as long as they are pressed down.
* Togglebuttons will change their state once they are pressed and keep that state
* until they are pressed again.
* @return [ PUSHBUTTON | TOGGLEBUTTON ]
*/
int getType();
/**
* Tells the state of the button at last update.
*/
boolean getState();
}

View File

@@ -0,0 +1,45 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 27. Dezember 2001, 23:33
//**********************************************************************************************
package de.hardcode.jxinput;
/**
*
* @author Herkules
*/
public interface Directional extends Feature
{
/**
* If the Directional has a center position where it points to no direction, this
* flag is true when this position is reached.
*/
boolean isCentered();
/**
* Retrieve the direction pointed to.
* Value is given in 1/100 degree, [0,36000]
*/
int getDirection();
/**
* Retrieve the analog value pointing to the angle described by
* <code>getDirection()</code>.
* For coolie hats this will be either 1,0 for any direction or 0.0
* when <code>isCentered()==true</code>.
*/
double getValue();
/**
* Inform about the resolution of the value returned by <code>getValue()</code>.
*
* @return resolution, e.g. 1.0 for coolie hats
*/
double getResolution();
}

View File

@@ -0,0 +1,38 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 27. Dezember 2001, 00:19
//**********************************************************************************************
package de.hardcode.jxinput;
/**
* An input device offers a set of features (otherwise it would be pretty useless).
* Features in this sense can be axes, buttons and a feature callede <e>directional</e> here.
* Coolie hats are typical directionals because they control a direction (to look at e.g.).
* <p>
* There are no concrete classes directly derived from <code>Feature</code> - it only
* provides a basis for other interfaces.
*
* @see Axis
* @see Button
* @see Directional
*
* @author Herkules
*/
public abstract interface Feature
{
/**
* Features may have a name provided e.g. by the driver.
*/
String getName();
/**
* Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
boolean hasChanged();
}

View File

@@ -0,0 +1,71 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 19. Dezember 2001, 21:47
//**********************************************************************************************
package de.hardcode.jxinput;
/**
* The <code>JXInputDevise</code> is the main entrypoint to the jxinput package.
* <p>
* A JXInputDevice represents one physical device like a joystick, a gamepad or
* even some emulation (e.g. using keyboard) that implements the interface.
* <p>
* The basis task of a <code>JXInputDevise</code> is to maintain a consistent state of all its features.
* <br>
* It is save to distribute the <code>Feature</code> objects into application without worrying
* about someone else performing an <code>update</code> method and thereby destructing the consistent state.
* <p>
* An additional task is to provide basic device features information like number of axes, buttons
* and directional features.
*
* @see Feature
* @see JXInputManager
*
* @author Herkules
* @version 0.2beta
*/
public interface JXInputDevice
{
/**
* @directed
*/
/*#Features lnkFeatures;*/
/**
*@link aggregationByValue
*/
/*#Feature lnkFeature;*/
/**
* Devices may have a name.
* This name might be provided by a system dependant driver.
*/
String getName();
/** Actual number of available axes. */
int getNumberOfAxes();
/** Actual number of available buttons. */
int getNumberOfButtons();
/** Actual number of available directional features. */
int getNumberOfDirectionals();
/** Maximum number of axes as an upper bound for index values. */
int getMaxNumberOfAxes();
/** Maximum number of buttons as an upper bound for index values. */
int getMaxNumberOfButtons();
/** Maximum number of directional features as an upper bound for index values. */
int getMaxNumberOfDirectionals();
Axis getAxis( int idx );
Button getButton( int idx );
Directional getDirectional( int idx );
}

View File

@@ -0,0 +1,233 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 29. Dezember 2001, 02:17
//**********************************************************************************************
package de.hardcode.jxinput;
//
// Import driver stuff
//
import de.hardcode.jxinput.directinput.DirectInputDevice;
import de.hardcode.jxinput.event.JXInputEventManager;
import de.hardcode.jxinput.keyboard.JXKeyboardInputDevice;
import de.hardcode.jxinput.virtual.JXVirtualInputDevice;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.Component;
/**
* Manages the available instances of JXInputDevice.
* It holds the one central update method which synchronizes with the physical device.
* @author Herkules
*/
public class JXInputManager
{
/** Remember when the last update took place. */
private static long mTimeOfLastUpdate;
/** Maintain a list of devices. */
private final static ArrayList mDevices = new ArrayList();
/** Maintain a list of direct input devices. */
private final static ArrayList mDIDevices = new ArrayList();
/** Maintain a list of virtual devices. */
private final static ArrayList mVirtualDevices = new ArrayList();
/** Maintain a list of keyboard devices. */
private final static ArrayList mKBDevices = new ArrayList();
/**
* Statically retrieve all DirectInputDevices available.
*/
static
{
reset();
}
/**
* @directed
*/
/*#JXInputDevice lnkJXInputDevice;*/
/**
* Creates a new instance of JXInputManager.
* This is prohibited - it only has static members.
*/
private JXInputManager()
{
}
/**
* Retrieve the number of available input devices.
*/
public static int getNumberOfDevices()
{
return mDevices.size();
}
/**
* Delivers the JXInputDevice with the desired index.
* <p>
* Take care that <code>idx < getNumberOfDevices()</code>!
*/
public static JXInputDevice getJXInputDevice( int idx )
{
//
// Be well-behaved even if idx is out of range.
//
if ( idx >= mDevices.size() )
return null;
return (JXInputDevice)mDevices.get( idx );
}
/**
* Master reset for all devices and events.
* After calling reset(), better forget all devices created or retrieved.
* They are no longer valid.
* Event listeners will no longer be called and should be discarded.
*/
synchronized public static void reset()
{
JXInputEventManager.reset();
mDevices.clear();
mVirtualDevices.clear();
mDIDevices.clear();
DirectInputDevice.reset();
for ( int i = 0; i < DirectInputDevice.getNumberOfDevices(); ++i )
{
DirectInputDevice dev = new DirectInputDevice( i );
mDevices.add( dev );
mDIDevices.add( dev );
}
// I have to call updateFeatures one time here during initialization
// bc. I experienced difficulties otherwise while running with the
// J3D sensoring stuff!
// updateFeatures();
DirectInputDevice.update();
int n = mKBDevices.size();
for ( int i = 0; i < n; ++i )
((JXKeyboardInputDevice)mKBDevices.get( i )).shutdown();
mKBDevices.clear();
}
/**
* Update the (shared) state of all features in one step.
* This method asks the actual device for a consistant state.
* After calling this method, all features may have new values.
* updateFeatures() is meant to be called e.g. once per frame in a gaming environment.
*/
public static void updateFeatures()
{
// Get timing
long now = System.currentTimeMillis();
long deltaT = now - mTimeOfLastUpdate;
// Update available driver
DirectInputDevice.update();
//
// Update the virtual devices.
//
Iterator vdevices = mVirtualDevices.iterator();
while ( vdevices.hasNext() )
{
((JXVirtualInputDevice)vdevices.next()).update( deltaT );
}
// Remember time
mTimeOfLastUpdate = now;
// Fire all events.
JXInputEventManager.trigger();
}
/**
* Get time when last update occurred.
* @return tickervalue in milliseconds
*/
public static long getLastUpdateTime()
{
return mTimeOfLastUpdate;
}
/**
* Create a new pseudo-device.
*/
public static JXKeyboardInputDevice createKeyboardDevice()
{
JXKeyboardInputDevice d = new JXKeyboardInputDevice();
mDevices.add( d );
mKBDevices.add( d );
return d;
}
/**
* Create a new pseudo-device listening to a Swing component.
* Make sure that the component also has the keyboard focus!!
*/
public static JXKeyboardInputDevice createKeyboardDevice( Component comp )
{
JXKeyboardInputDevice d = new JXKeyboardInputDevice( comp );
mDevices.add( d );
mKBDevices.add( d );
return d;
}
/**
* Delete a keyboard device again e.g. when the corresponding
* JComponent gets deleted.
*/
public static void deleteKeyboardDevice( JXKeyboardInputDevice dev )
{
mDevices.remove( dev );
mKBDevices.remove( dev );
((JXKeyboardInputDevice)dev).shutdown();
}
/**
* Create a new pseudo-device.
*/
public static JXVirtualInputDevice createVirtualDevice()
{
JXVirtualInputDevice d = new JXVirtualInputDevice();
mDevices.add( d );
mVirtualDevices.add( d );
return d;
}
/**
* Delete a virtual device again.
*/
public static void deleteVirtualDevice( JXVirtualInputDevice dev )
{
mDevices.remove( dev );
mVirtualDevices.remove( dev );
}
}

View File

@@ -0,0 +1,70 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 27. Dezember 2001, 00:14
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import de.hardcode.jxinput.Axis;
/**
*
* @author Herkules
*/
class DIAxis implements Axis
{
private final int mDeviceIdx;
private final int mIdx;
/**
* Creates a new instance of DIAxis.
*/
DIAxis( int devidx, int idx )
{
mDeviceIdx = devidx;
mIdx = idx;
}
public String getName()
{
return DirectInputDriver.getAxisName( mDeviceIdx, mIdx );
}
/**
* Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
public double getValue()
{
return DirectInputDriver.getAxisValue( mDeviceIdx, mIdx );
}
public int getType()
{
return DirectInputDriver.getAxisType( mDeviceIdx, mIdx );
}
/**
* Inform about the resolution of the axis.
*
* @return resolution, e.g. 2^-16
*/
public double getResolution()
{
// extend the driver here!!
// Here I assume typical 16 bit resolution
return ( getType() == Axis.SLIDER ? 1.0/65536.0 : 2.0/65536.0 ) ;
}
}

View File

@@ -0,0 +1,55 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 27. Dezember 2001, 00:14
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import de.hardcode.jxinput.Button;
/**
*
* @author Herkules
*/
class DIButton implements Button
{
private final int mDeviceIdx;
private final int mIdx;
/**
* Creates a new instance of DIButton.
*/
DIButton( int devidx, int idx )
{
mDeviceIdx = devidx;
mIdx = idx;
}
public String getName()
{
return DirectInputDriver.getButtonName( mDeviceIdx, mIdx );
}
/**
* Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
public int getType()
{
return DirectInputDriver.getButtonType( mDeviceIdx, mIdx );
}
public boolean getState()
{
return DirectInputDriver.getButtonState( mDeviceIdx, mIdx );
}
}

View File

@@ -0,0 +1,78 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 27. Dezember 2001, 23:40
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import de.hardcode.jxinput.Directional;
/**
*
* @author Herkules
*/
class DIDirectional implements Directional
{
private final int mDeviceIdx;
private final int mIdx;
/**
* Creates a new instance of DIDirectional.
*/
DIDirectional( int devidx, int idx )
{
mDeviceIdx = devidx;
mIdx = idx;
}
/** Features may have a name provided e.g. by the driver. */
public String getName()
{
return DirectInputDriver.getDirectionalName( mDeviceIdx, mIdx );
}
/**
* Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
public boolean isCentered()
{
return ( 0xffff == (DirectInputDriver.getDirection( mDeviceIdx, mIdx ) & 0xffff) );
}
public int getDirection()
{
return isCentered() ? 0 : DirectInputDriver.getDirection( mDeviceIdx, mIdx );
}
public double getValue()
{
if ( isCentered() )
return 0.0;
return 1.0;
}
/**
* Inform about the resolution of the value returned by <code>getValue()</code>.
*
* @return resolution, e.g. 1.0 for coolie hats
*/
public double getResolution()
{
// DI POV always return 0.0 or 1.0, so the resolution is 1.0.
return 1.0;
}
}

View File

@@ -0,0 +1,170 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 26. Dezember 2001, 00:40
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import de.hardcode.jxinput.JXInputDevice;
import de.hardcode.jxinput.Axis;
import de.hardcode.jxinput.Directional;
import de.hardcode.jxinput.Button;
/**
*
* @author Herkules
*/
public class DirectInputDevice implements JXInputDevice
{
int mDeviceIdx;
private DIAxis[] mAxes;
private DIButton[] mButtons;
private DIDirectional[] mDirectionals;
/**
* The number of DirectInput devices available with the driver.
*/
public static int getNumberOfDevices()
{
if ( DirectInputDriver.isAvailable() )
return DirectInputDriver.getNumberOfDevices();
return 0;
}
/**
* Update the state of all devices.
*/
public static void update()
{
if ( DirectInputDriver.isAvailable() )
DirectInputDriver.nativeupdate();
}
/**
* Creates a new instance of DirectInputDevice.
*/
public DirectInputDevice( int devidx )
{
mDeviceIdx = devidx;
init();
}
/**
* Reset the DirectInput connection.
*/
public static void reset()
{
if ( DirectInputDriver.isAvailable() )
DirectInputDriver.reset();
}
/**
* Initialisation of fields.
*/
private final void init()
{
//
// Allocate arrays for max. number of features
//
mAxes = new DIAxis [ getMaxNumberOfAxes() ];
mButtons = new DIButton [ getMaxNumberOfButtons() ];
mDirectionals = new DIDirectional [ getMaxNumberOfDirectionals() ];
//
// Fill arrays due to the state of the driver.
//
for ( int i = 0; i < mAxes.length; ++i )
{
if ( DirectInputDriver.isAxisAvailable( mDeviceIdx, i ) )
mAxes[ i ] = new DIAxis( mDeviceIdx, i );
}
for ( int i = 0; i < mButtons.length; ++i )
{
if ( DirectInputDriver.isButtonAvailable( mDeviceIdx, i ) )
mButtons[ i ] = new DIButton( mDeviceIdx, i );
}
for ( int i = 0; i < mDirectionals.length; ++i )
{
if ( DirectInputDriver.isDirectionalAvailable( mDeviceIdx, i ) )
mDirectionals[ i ] = new DIDirectional( mDeviceIdx, i );
}
}
/** Devices may have a name. */
public String getName()
{
String name = DirectInputDriver.getName( mDeviceIdx );
if ( null == name )
return "Win32 DirectInput Joystick";
return name;
}
/** Actual number of available buttons. */
public int getNumberOfButtons()
{
return DirectInputDriver.getNumberOfButtons( mDeviceIdx );
}
/** Actual number of available axes. */
public int getNumberOfAxes()
{
return DirectInputDriver.getNumberOfAxes( mDeviceIdx );
}
/** Actual number of available directional features. */
public int getNumberOfDirectionals()
{
return DirectInputDriver.getNumberOfDirectionals( mDeviceIdx );
}
/** Maximum number of buttons as an upper bound for index values. */
public int getMaxNumberOfButtons()
{
return DirectInputDriver.getMaxNumberOfButtons();
}
/** Maximum number of axes as an upper bound for index values. */
public int getMaxNumberOfAxes()
{
return DirectInputDriver.getMaxNumberOfAxes();
}
/** Maximum number of available directional features. */
public int getMaxNumberOfDirectionals()
{
return DirectInputDriver.getMaxNumberOfDirectionals();
}
public Axis getAxis(int idx)
{
return mAxes[ idx ];
}
public Button getButton(int idx)
{
return mButtons[ idx ];
}
public Directional getDirectional(int idx)
{
return mDirectionals[ idx ];
}
}

View File

@@ -0,0 +1,184 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 19. Dezember 2001, 22:44
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import java.lang.reflect.Array;
/**
* DirectInputDriver: the connection to the Win32 joystick.
* There is only one allowed, so the layout of this class is merely static.
*
* History:
*
* Changes since 0.1beta:
* - support of multiple devices addressed by the <code>dev</code> index
*
*
* @author Herkules
* @version 0.2beta
*/
class DirectInputDriver
{
private final static String NATIVE_LIB_NAME = "jxinput";
/** Remember wether nativeinit() succeeded. */
static boolean sIsOperational = false;
//
// Static arrays to hold the values.
//
private static double [][] sAxisValues;
private static boolean [][] sButtonStates;
private static int [][] sDirectionalValues;
/**
* Perform the static initialization.
*/
static
{
try
{
// Load the native lib.
System.loadLibrary( NATIVE_LIB_NAME );
init();
}
catch( SecurityException e )
{
Log.logger.warning("Native library jxinput not loaded due to a SecurityException.");
}
catch( UnsatisfiedLinkError e )
{
Log.logger.info("Native library jxinput not loaded due to an UnsatisfiedLinkError.");
}
}
private final static void init()
{
sIsOperational = false;
//
// Initialize it.
//
if ( nativeinit() )
{
int devs = getNumberOfDevices();
sAxisValues = new double [ devs ][ DirectInputDriver.getMaxNumberOfAxes() ];
sButtonStates = new boolean [ devs ][ DirectInputDriver.getMaxNumberOfButtons() ];
sDirectionalValues = new int [ devs ][ DirectInputDriver.getMaxNumberOfDirectionals() ];
// Bind the native lib to my variables.
bind();
// Remember I am fine.
sIsOperational = true;
}
}
/**
* Static ctor of DirectInputDriver.
* No object will be created due to the static layout.
*/
private DirectInputDriver()
{
}
// Administration
private static native boolean nativeinit();
private static native void nativeexit();
private static native void bind();
static native int getNumberOfDevices();
// Configuration
static native String getName( int dev );
static native int getNumberOfAxes( int dev );
static native int getNumberOfButtons( int dev );
static native int getNumberOfDirectionals( int dev );
static native int getMaxNumberOfAxes();
static native int getMaxNumberOfButtons();
static native int getMaxNumberOfDirectionals();
static native boolean isAxisAvailable( int dev, int idx );
static native String getAxisName( int dev, int idx );
static native int getAxisType( int dev, int idx );
static native boolean isButtonAvailable( int dev, int idx );
static native String getButtonName( int dev, int idx );
static native int getButtonType( int dev, int idx );
static native boolean isDirectionalAvailable( int dev, int idx );
static native String getDirectionalName( int dev, int idx );
// Operation
static native void nativeupdate();
public static boolean isAvailable()
{
return sIsOperational;
}
/**
* Shutdown the device and free all Win32 resources.
* It is not a good idea to access any joystick features after
* <code>shutdown()</code>.
*/
static void shutdown()
{
nativeexit();
sAxisValues = null;
sButtonStates = null;
sDirectionalValues = null;
}
/**
* Reset the device and free all Win32 resources.
*/
static void reset()
{
shutdown();
init();
}
static double getAxisValue( int dev, int idx )
{
return sAxisValues[ dev ][ idx ];
}
static boolean getButtonState( int dev, int idx )
{
return sButtonStates[ dev ][ idx ];
}
static int getDirection( int dev, int idx )
{
return sDirectionalValues[ dev ][ idx ];
}
/**
* @param args the command line arguments
*/
public static void main (String args[])
{
if ( ! sIsOperational )
return;
for( int i = 0; i < 5000; ++i )
nativeupdate();
shutdown();
}
}

View File

@@ -0,0 +1,34 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 29. Oktober 2002, 22:57
//**********************************************************************************************
package de.hardcode.jxinput.directinput;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Herkules
*/
public class Log
{
public final static Logger logger = Logger.getLogger( Log.class.getPackage().getName() );
// static
// {
// logger.setLevel( Level.ALL );
// }
/**
* Creates a new instance of Log.
*/
private Log()
{
}
}

View File

@@ -0,0 +1,48 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:33
//**********************************************************************************************
package de.hardcode.jxinput.event;
import de.hardcode.jxinput.JXInputDevice;
import de.hardcode.jxinput.Axis;
/**
* Represents an event coming from an axis.
* @author Joerg Plewe
*/
public class JXInputAxisEvent
{
private final Axis mAxis;
double mDelta;
/**
* Creates a new instance of JXInputEvent.
*/
JXInputAxisEvent( Axis axis )
{
mAxis = axis;
}
/**
* The feature that caused the event.
*/
public final Axis getAxis()
{
return mAxis;
}
/**
* Return the change in value that caused the event.
*/
public double getDelta()
{
return mDelta;
}
}

View File

@@ -0,0 +1,19 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:54
//**********************************************************************************************
package de.hardcode.jxinput.event;
/**
*
* @author Herkules
*/
public interface JXInputAxisEventListener
{
void changed( JXInputAxisEvent ev );
}

View File

@@ -0,0 +1,38 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:33
//**********************************************************************************************
package de.hardcode.jxinput.event;
import de.hardcode.jxinput.JXInputDevice;
import de.hardcode.jxinput.Button;
/**
* Represents event coming from a button.
* @author Joerg Plewe
*/
public class JXInputButtonEvent
{
final Button mButton;
/**
* Creates a new instance of JXInputEvent.
*/
JXInputButtonEvent( Button button )
{
mButton = button;
}
/**
* The feature that caused the event.
*/
public final Button getButton()
{
return mButton;
}
}

View File

@@ -0,0 +1,19 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:54
//**********************************************************************************************
package de.hardcode.jxinput.event;
/**
*
* @author Herkules
*/
public interface JXInputButtonEventListener
{
void changed( JXInputButtonEvent ev );
}

View File

@@ -0,0 +1,56 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:33
//**********************************************************************************************
package de.hardcode.jxinput.event;
import de.hardcode.jxinput.JXInputDevice;
import de.hardcode.jxinput.Directional;
/**
* Represents an event coming from an axis.
* @author Joerg Plewe
*/
public class JXInputDirectionalEvent
{
private final Directional mDirectional;
double mValueDelta;
int mDirectionDelta;
/**
* Creates a new instance of JXInputEvent.
*/
JXInputDirectionalEvent( Directional directional )
{
mDirectional = directional;
}
/**
* The feature that caused the event.
*/
public final Directional getDirectional()
{
return mDirectional;
}
/**
* Return the change in value that caused the event.
*/
public double getValueDelta()
{
return mValueDelta;
}
/**
* Return the change in direction that caused the event.
*/
public int getDirectionDelta()
{
return mDirectionDelta;
}
}

View File

@@ -0,0 +1,19 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:54
//**********************************************************************************************
package de.hardcode.jxinput.event;
/**
*
* @author Herkules
*/
public interface JXInputDirectionalEventListener
{
void changed( JXInputDirectionalEvent ev );
}

View File

@@ -0,0 +1,284 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 31. Januar 2002, 23:42
//**********************************************************************************************
package de.hardcode.jxinput.event;
import de.hardcode.jxinput.JXInputManager;
import de.hardcode.jxinput.JXInputDevice;
import java.util.ArrayList;
import de.hardcode.jxinput.Axis;
import java.util.Iterator;
import de.hardcode.jxinput.Button;
import de.hardcode.jxinput.Directional;
/**
* Handles all events and listeners.
* <code>JXInputEventManager</code> is layed out a static singleton.
* @author Herkules
*/
public class JXInputEventManager
{
private final static ArrayList mAxisEventListeners = new ArrayList();
private final static ArrayList mButtonEventListeners = new ArrayList();
private final static ArrayList mDirectionalEventListeners = new ArrayList();
private static autotrigger mAutoTrigger = null;
/**
* Inner class combining a listener with its scheduling parameters.
*/
private static class axislistener
{
final JXInputAxisEventListener mListener;
final double mTreshold;
final JXInputAxisEvent mEvent;
double mLastValueFired = 0.0;
axislistener( JXInputAxisEventListener l, Axis axis, double treshold )
{
mListener = l;
mTreshold = treshold;
mEvent = new JXInputAxisEvent( axis );
}
final void checkTrigger()
{
double curval = mEvent.getAxis().getValue();
double delta = curval - mLastValueFired;
if ( Math.abs( delta ) >= mTreshold )
{
mLastValueFired = curval;
mEvent.mDelta = delta;
mListener.changed( mEvent );
}
}
}
/**
* Inner class combining a listener with its scheduling parameters.
*/
private static class buttonlistener
{
final JXInputButtonEventListener mListener;
final JXInputButtonEvent mEvent;
boolean mLastValueFired = false;
buttonlistener( JXInputButtonEventListener l, Button button )
{
mListener = l;
mEvent = new JXInputButtonEvent( button );
}
final void checkTrigger()
{
boolean curstate = mEvent.getButton().getState();
if ( curstate != mLastValueFired )
{
mLastValueFired = curstate;
mListener.changed( mEvent );
}
}
}
private static class directionallistener
{
final JXInputDirectionalEventListener mListener;
final double mValueTreshold;
final JXInputDirectionalEvent mEvent;
double mLastValueFired = 0.0;
boolean mLastCenteredFired = true;
int mLastDirectionFired = 0;
directionallistener( JXInputDirectionalEventListener l, Directional directional, double valuetreshold )
{
mListener = l;
mValueTreshold = valuetreshold;
mEvent = new JXInputDirectionalEvent( directional );
}
final void checkTrigger()
{
double curval = mEvent.getDirectional().getValue();
int curdir = mEvent.getDirectional().getDirection();
boolean curctr = mEvent.getDirectional().isCentered();
double delta = curval - mLastValueFired;
int dirdelta = curdir - mLastDirectionFired;
boolean centeredchanged = mLastCenteredFired != curctr;
if ( Math.abs( delta ) >= mValueTreshold
|| Math.abs( dirdelta ) > 0
|| centeredchanged )
{
mLastValueFired = curval;
mLastDirectionFired = curdir;
mLastCenteredFired = curctr;
mEvent.mValueDelta = delta;
mEvent.mDirectionDelta = dirdelta;
mListener.changed( mEvent );
}
}
}
/**
* Creates a new instance of JXInputEventManager.
*/
private JXInputEventManager()
{
}
/**
* Remove all listeners at once.
*/
public static void reset()
{
mAxisEventListeners.clear();
mButtonEventListeners.clear();
mDirectionalEventListeners.clear();
}
/**
* Query devices and fire all occuring events.
* <code>trigger()</code> is thought to be called by <code>JXInputManager#updateFeatures()</code>.
*/
public static void trigger()
{
int n = mAxisEventListeners.size();
for ( int i = 0; i < n; i++ )
{
axislistener l = (axislistener)mAxisEventListeners.get( i );
l.checkTrigger();
}
n = mButtonEventListeners.size();
for ( int i = 0; i < n; i++ )
{
buttonlistener l = (buttonlistener)mButtonEventListeners.get( i );
l.checkTrigger();
}
n = mDirectionalEventListeners.size();
for ( int i = 0; i < n; i++ )
{
directionallistener l = (directionallistener)mDirectionalEventListeners.get( i );
l.checkTrigger();
}
}
private final static class autotrigger extends Thread
{
boolean mFinish = false;
final int mDelay;
autotrigger( int delay )
{
mDelay = delay;
}
public void run()
{
while ( ! mFinish )
{
try
{
Thread.sleep( mDelay );
JXInputManager.updateFeatures();
}
catch ( InterruptedException ex )
{
}
}
}
}
/**
* Set the intervall in ms that is used to check for new values of the features.
* Set it to <= 0 to prohibit automatic triggering. Events will then only be fired
* when somebody invokes <code>JXInputManager#updateFeatures()</code>.
*/
public static void setTriggerIntervall( int ms )
{
//
// Kill current thread, if any
//
if ( null != mAutoTrigger )
{
mAutoTrigger.mFinish = true;
try
{
mAutoTrigger.join();
}
catch ( InterruptedException ex )
{
}
}
mAutoTrigger = null;
if ( ms > 0 )
{
mAutoTrigger = new autotrigger( ms );
mAutoTrigger.start();
}
}
public static void addListener( JXInputAxisEventListener l, Axis axis, double treshold )
{
mAxisEventListeners.add( new JXInputEventManager.axislistener( l, axis, treshold ) );
}
public static void addListener( JXInputAxisEventListener l, Axis axis )
{
mAxisEventListeners.add( new JXInputEventManager.axislistener( l, axis, axis.getResolution() ) );
}
public static void removeListener( JXInputAxisEventListener l )
{
mAxisEventListeners.remove( l );
}
public static void addListener( JXInputButtonEventListener l, Button button )
{
mButtonEventListeners.add( new JXInputEventManager.buttonlistener( l, button ) );
}
public static void removeListener( JXInputButtonEventListener l )
{
mButtonEventListeners.remove( l );
}
public static void addListener( JXInputDirectionalEventListener l, Directional directional, double valuetreshold )
{
mDirectionalEventListeners.add( new JXInputEventManager.directionallistener( l, directional, valuetreshold ) );
}
public static void addListener( JXInputDirectionalEventListener l, Directional directional )
{
mDirectionalEventListeners.add( new JXInputEventManager.directionallistener( l, directional, directional.getResolution() ) );
}
public static void removeListener( JXInputDirectionalEventListener l )
{
mDirectionalEventListeners.remove( l );
}
}

View File

@@ -0,0 +1,95 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 23. Februar 2002, 14:05
//**********************************************************************************************
package de.hardcode.jxinput.j3d;
import de.hardcode.jxinput.Axis;
/**
* Connects JXInput with J3DInputDevice.
*
* @author Herkules
*/
public class DeviceConfiguration
{
public final static int AXIS_X = 0;
public final static int AXIS_Y = 1;
public final static int AXIS_Z = 2;
private final static class axisvalue
{
private final Axis mAxis;
private final IsActiveCondition mIsActive;
private final IsActiveCondition mIsIncremental;
private final double mScale;
private final double mOffset;
private double mValue;
axisvalue( Axis axis, IsActiveCondition active, IsActiveCondition incremental, double offset, double scale )
{
mAxis = axis;
mIsActive = active;
mIsIncremental = incremental;
mValue = mOffset = offset;
mScale = scale;
}
double value()
{
if ( mIsActive.isActive() )
{
double newval = mAxis.getValue() * mScale;
if ( mIsIncremental.isActive() )
mValue += newval;
else
mValue = newval + mOffset;
}
return mValue;
}
}
DeviceConfiguration.axisvalue [] mAxisTrans = new DeviceConfiguration.axisvalue[ 3 ];
DeviceConfiguration.axisvalue [] mAxisRot = new DeviceConfiguration.axisvalue[ 3 ];
/**
* Creates a new instance of DeviceConfiguration.
*/
public DeviceConfiguration()
{
}
double getTranslational( int axisid )
{
DeviceConfiguration.axisvalue val = mAxisTrans[ axisid ];
return null == val ? 0.0 : val.value();
}
double getRotational( int axisid )
{
DeviceConfiguration.axisvalue val = mAxisRot[ axisid ];
return null == val ? 0.0 : val.value();
}
public void setTranslational( int axisid, Axis axis, IsActiveCondition active, IsActiveCondition incremental, double offset, double scale )
{
if ( axisid < 0 || axisid > AXIS_Z )
throw new IllegalArgumentException();
mAxisTrans[ axisid ] = new DeviceConfiguration.axisvalue( axis, active, incremental, offset, scale );
}
public void setRotational( int axisid, Axis axis, IsActiveCondition active, IsActiveCondition incremental, double offset, double scale )
{
if ( axisid < 0 || axisid > AXIS_Z )
throw new IllegalArgumentException();
mAxisRot[ axisid ] = new DeviceConfiguration.axisvalue( axis, active, incremental, offset, scale );
}
}

View File

@@ -0,0 +1,25 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 25. Februar 2002, 22:41
//**********************************************************************************************
package de.hardcode.jxinput.j3d;
/**
*
* @author Herkules
*/
public interface IsActiveCondition
{
public final static IsActiveCondition ALWAYS = IsAlwaysActiveCondition.ALWAYS;
public final static IsActiveCondition NEVER = IsAlwaysActiveCondition.NEVER;
/**
* Tell wether a certain thing is active.
*/
boolean isActive();
}

View File

@@ -0,0 +1,39 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 25. Februar 2002, 22:43
//**********************************************************************************************
package de.hardcode.jxinput.j3d;
import de.hardcode.jxinput.Button;
/**
*
* @author Herkules
*/
public class IsActiveOnButtonCondition implements IsActiveCondition
{
private final boolean mActiveState;
private final Button mButton;
/**
* Creates a new instance of IsAlwayActiveCondition.
*/
public IsActiveOnButtonCondition( Button button, boolean activestate )
{
mActiveState = activestate;
mButton = button;
}
/**
* Tell wether a certain thing is active.
*/
public boolean isActive()
{
return mButton.getState() == mActiveState;
}
}

View File

@@ -0,0 +1,38 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 25. Februar 2002, 22:43
//**********************************************************************************************
package de.hardcode.jxinput.j3d;
/**
*
* @author Herkules
*/
final class IsAlwaysActiveCondition implements IsActiveCondition
{
private final boolean mIsActive;
public final static IsActiveCondition ALWAYS = new IsAlwaysActiveCondition( true );
public final static IsActiveCondition NEVER = new IsAlwaysActiveCondition( false );
/**
* Creates a new instance of IsAlwayActiveCondition.
*/
private IsAlwaysActiveCondition(boolean isactive)
{
mIsActive = isactive;
}
/**
* Tell wether a certain thing is active.
*/
public boolean isActive()
{
return mIsActive;
}
}

View File

@@ -0,0 +1,171 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 22. Februar 2002, 13:21
//**********************************************************************************************
package de.hardcode.jxinput.j3d;
import javax.media.j3d.InputDevice;
import javax.media.j3d.Sensor;
import javax.media.j3d.SensorRead;
import javax.vecmath.Vector3d;
import javax.media.j3d.Transform3D;
import de.hardcode.jxinput.JXInputManager;
/**
* Implementation of Java3D's InputDevice
*
* @author Herkules
*/
public class J3DInputDevice
implements InputDevice
{
private Vector3d mPosition = new Vector3d();
private Transform3D mNewTransform = new Transform3D();
private Transform3D mRotTransX = new Transform3D();
private Transform3D mRotTransY = new Transform3D();
private Transform3D mRotTransZ = new Transform3D();
private Vector3d mInitPos = new Vector3d( 0.0, 0.0, 0.0 );
private Sensor mSensor = new Sensor( this );
private SensorRead mSensorRead = new SensorRead();
private DeviceConfiguration mConfig;
/**
* Creates a new instance of J3DInputDevice.
*/
public J3DInputDevice( DeviceConfiguration config )
{
mConfig = config;
setNominalPositionAndOrientation();
}
public void close()
{
// Intentionally empty
}
/**
* Retrieve processing mode.
* For this device, it always is NON_BLOCKING.
*/
public int getProcessingMode()
{
return InputDevice.NON_BLOCKING;
}
/**
* Don't care for the index, I only support one sensor.
* And I deliver that.
*/
public Sensor getSensor( int param )
{
return mSensor;
}
/**
* Tell the world about the only one sensor I support.
*/
public int getSensorCount()
{
return 1;
}
/**
* Well - initialize!
* Nothing to do here.
*/
public boolean initialize()
{
return true;
}
/**
* The main update method.
*/
public void pollAndProcessInput()
{
JXInputManager.updateFeatures();
mSensorRead.setTime( JXInputManager.getLastUpdateTime() );
mRotTransX.rotX( mConfig.getRotational( DeviceConfiguration.AXIS_X ) );
mRotTransY.rotY( mConfig.getRotational( DeviceConfiguration.AXIS_Y ) );
mRotTransZ.rotZ( mConfig.getRotational( DeviceConfiguration.AXIS_Z ) );
mPosition.set(
mConfig.getTranslational( DeviceConfiguration.AXIS_X ),
mConfig.getTranslational( DeviceConfiguration.AXIS_Y ),
mConfig.getTranslational( DeviceConfiguration.AXIS_Z )
);
mNewTransform.set( mPosition );
mNewTransform.mul( mRotTransX );
mNewTransform.mul( mRotTransY );
mNewTransform.mul( mRotTransZ );
mSensorRead.set( mNewTransform );
mSensor.setNextSensorRead( mSensorRead );
}
/**
* Not called by current j3d implementation.
*/
public void processStreamInput()
{
// Intentionally empty
}
/**
* Reset state.
*/
public void setNominalPositionAndOrientation()
{
mSensorRead.setTime( JXInputManager.getLastUpdateTime() );
mRotTransX.rotX( 0.0 );
mRotTransY.rotY( 0.0 );
mRotTransZ.rotZ( 0.0 );
mPosition.set( mInitPos );
mNewTransform.set( mPosition );
mNewTransform.mul( mRotTransX );
mNewTransform.mul( mRotTransY );
mNewTransform.mul( mRotTransZ );
mSensorRead.set( mNewTransform );
mSensor.setNextSensorRead( mSensorRead );
}
/**
* Set the processing mode.
* Only NON_BLOCKING is allowed!
*/
public void setProcessingMode(int param)
{
if ( param != InputDevice.NON_BLOCKING )
throw new IllegalArgumentException("Processing mode must be NON_BLOCKING");
}
}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
Connecting JXInput to Java3D by implementing the interface
javax.media.j3d.InputDevice.
</BODY>
</HTML>

View File

@@ -0,0 +1,205 @@
/*
* @(#)HelloUniverse.java 1.15 02/02/07 14:48:36
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed,licensed or intended
* for use in the design, construction, operation or maintenance of
* any nuclear facility.
*/
package de.hardcode.jxinput.j3d.test;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import de.hardcode.jxinput.j3d.DeviceConfiguration;
import de.hardcode.jxinput.Axis;
import de.hardcode.jxinput.JXInputManager;
import de.hardcode.jxinput.j3d.IsActiveCondition;
import de.hardcode.jxinput.j3d.J3DInputDevice;
import de.hardcode.jxinput.j3d.IsActiveOnButtonCondition;
public class HelloUniverse extends Applet
{
private SimpleUniverse u = null;
TransformGroup objTrans;
public BranchGroup createSceneGraph()
{
BranchGroup objRoot = new BranchGroup();
objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objTrans);
objTrans.addChild(new ColorCube(0.4));
// Transform3D yAxis = new Transform3D();
// Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
// 0, 0,
// 4000, 0, 0,
// 0, 0, 0);
// RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans, yAxis,
// 0.0f, (float) Math.PI*2.0f);
// BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
// rotator.setSchedulingBounds(bounds);
// objTrans.addChild(rotator);
return objRoot;
}
public HelloUniverse()
{
}
public void init()
{
// These are the string arguments given to the VirtualInputDevice
// constructor. These are settable parameters. Look in the
// VirtualInputDevice constructor for a complete list.
String[] args = new String[10];
args[0] = "printvalues";
args[1] = "true";
args[2] = "yscreeninitloc";
args[3] = "50";
args[4] = null;
// now create the HelloUniverse Canvas
setLayout(new BorderLayout());
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
add("Center", c);
// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);
//
// Use the inputdevice
//
InputDevice device = createInputDevice();
// Register the VirtualInputDevice with Java 3D
u.getViewer().getPhysicalEnvironment().addInputDevice( device );
// TransformGroup viewTrans = u.getViewingPlatform().getViewPlatformTransform();
// Put the behavoir to teh object
SensorBehavior s = new SensorBehavior( objTrans, device.getSensor(0) );
s.setSchedulingBounds( new BoundingSphere( new Point3d(0.0,0.0,0.0), Float.MAX_VALUE ) );
objTrans.addChild( s );
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public void destroy()
{
u.removeAllLocales();
}
/**
* Setup an input device.
*/
private InputDevice createInputDevice()
{
IsActiveCondition button1down = new IsActiveOnButtonCondition(JXInputManager.getJXInputDevice( 0 ).getButton( 0 ), true );
IsActiveCondition button1up = new IsActiveOnButtonCondition(JXInputManager.getJXInputDevice( 0 ).getButton( 0 ), false );
Axis xaxis = JXInputManager.getJXInputDevice( 0 ).getAxis( Axis.ID_X );
Axis yaxis = JXInputManager.getJXInputDevice( 0 ).getAxis( Axis.ID_Y );
DeviceConfiguration cnf = new DeviceConfiguration();
//
// Setup the configuration to use joysticks x/y for rotation is not button is pressed
// and for translation if button1 is pressed.
//
cnf.setRotational(
DeviceConfiguration.AXIS_Y,
xaxis,
button1up,
IsActiveCondition.NEVER,
0.0, Math.PI
);
cnf.setRotational(
DeviceConfiguration.AXIS_X,
yaxis,
button1up,
IsActiveCondition.NEVER,
0.0, Math.PI
);
cnf.setTranslational(
DeviceConfiguration.AXIS_Z,
yaxis,
button1down,
IsActiveCondition.NEVER,
-5.0, 4.0
);
cnf.setTranslational(
DeviceConfiguration.AXIS_X,
xaxis,
button1down,
IsActiveCondition.NEVER,
0.0, 4.0
);
// We have the config, create the device...
J3DInputDevice d = new J3DInputDevice( cnf );
// The InputDevice must be initialized before registering it
// with the PhysicalEnvironment object.
d.initialize();
return d;
}
public static void main(String[] args)
{
new MainFrame(new HelloUniverse(), 350, 350);
}
}

View File

@@ -0,0 +1,70 @@
package de.hardcode.jxinput.j3d.test;
/*
* @(#)SensorBehavior.java 1.8 02/02/07 14:48:34
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed,licensed or intended
* for use in the design, construction, operation or maintenance of
* any nuclear facility.
*/
import javax.media.j3d.*;
import java.util.*;
public class SensorBehavior extends Behavior
{
private WakeupOnElapsedFrames conditions = new WakeupOnElapsedFrames(0);
private TransformGroup transformGroup;
private Sensor sensor;
private Transform3D transform = new Transform3D();
public SensorBehavior( TransformGroup tg, Sensor sensor )
{
transformGroup = tg;
this.sensor = sensor;
}
public void initialize()
{
wakeupOn( conditions );
}
public void processStimulus( Enumeration criteria )
{
sensor.getRead( transform );
transformGroup.setTransform( transform );
wakeupOn( conditions );
}
}

View File

@@ -0,0 +1,35 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 16. April 2002, 23:31
//**********************************************************************************************
package de.hardcode.jxinput.keyboard;
/**
* Exeception to be thrown if keycode is not in then range [0,255].
*
* @author Herkules
*/
public class InvalidKeyCodeException
extends IllegalArgumentException
{
/**
* Creates a new instance of InvalidKeyCodeException.
*/
public InvalidKeyCodeException()
{
}
/**
* Creates a new instance of InvalidKeyCodeException.
*/
public InvalidKeyCodeException( String s )
{
super( s );
}
}

View File

@@ -0,0 +1,175 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 9. April 2002, 22:40
//**********************************************************************************************
package de.hardcode.jxinput.keyboard;
import de.hardcode.jxinput.*;
import java.awt.Component;
/**
* Virtual input device treating a AWT keyboard as a source for Buttons.
*
* @author Herkules
*/
public class JXKeyboardInputDevice
implements JXInputDevice
{
private static final String DEVICENAME = "Swing Keyboard";
/** The driver doing all the real work. */
private final KeyboardDriver mDriver = new KeyboardDriver();
/** The Component I am listening to. */
private Component mComponent = null;
/** Hold the biggest keycode for which a button has been created. */
private int mMaxIdxCreated = 0;
/**
* Creates a new instance of JXKeyboardInputDevice.
*/
public JXKeyboardInputDevice()
{
}
/**
* Creates a new instance of JXKeyboardInputDevice
* immediately listening to a JComponent.
*/
public JXKeyboardInputDevice( Component comp )
{
listenTo( comp );
}
/**
* Makes this device listen to a certain JComponent.
*/
public final void listenTo( Component comp )
{
shutdown();
mComponent = comp;
mComponent.addKeyListener( mDriver );
}
/**
* Shut down. No longer listen to my JComponent.
*/
public final void shutdown()
{
if ( null != mComponent )
mComponent.removeKeyListener( mDriver );
}
/**
* Create a button object for a certain keycode.
*/
public Button createButton( int keycode )
{
if ( 0 > keycode || 0x100 < keycode )
throw new InvalidKeyCodeException();
KeyButton b;
if ( null == (b = mDriver.getButton( keycode ) ) )
{
b = new KeyButton( keycode );
mDriver.registerKeyButton( b );
if ( keycode > mMaxIdxCreated )
mMaxIdxCreated = keycode;
}
return b;
}
public void removeButton( Button b )
{
mDriver.unregisterKeyButton( (KeyButton) b );
}
//*********************************************************************************************
//
// Implement JXInputDevice
//
//*********************************************************************************************
public Axis getAxis(int idx)
{
// No axes on keyboard.
return null;
}
public Button getButton(int idx)
{
// idx is interpreted as the keycode
return mDriver.getButton( idx );
}
public Directional getDirectional(int idx)
{
// No directionals on keyboard.
return null;
}
/** Maximum number of axes as an upper bound for index values. */
public int getMaxNumberOfAxes()
{
// No axes on keyboard.
return 0;
}
/** Maximum number of buttons as an upper bound for index values. */
public int getMaxNumberOfButtons()
{
// Return biggest keycode (inclusive).
return mMaxIdxCreated + 1;
}
/** Maximum number of directional features as an upper bound for index values. */
public int getMaxNumberOfDirectionals()
{
// No directionals on keyboard.
return 0;
}
/**
* Devices may have a name.
* This name might be provided by a system dependant driver.
*/
public String getName()
{
return DEVICENAME;
}
/** Actual number of available axes. */
public int getNumberOfAxes()
{
// No axes on keyboard.
return 0;
}
/** Actual number of available buttons. */
public int getNumberOfButtons()
{
return mDriver.getNumberOfButtons();
}
/** Actual number of available directional features. */
public int getNumberOfDirectionals()
{
// No directionals on keyboard.
return 0;
}
}

View File

@@ -0,0 +1,94 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 9. April 2002, 22:51
//**********************************************************************************************
package de.hardcode.jxinput.keyboard;
import de.hardcode.jxinput.Button;
import java.awt.event.KeyEvent;
/**
* Associates a keycode with a Button and handles the current state of that button.
*
* @author Herkules
*/
class KeyButton
implements Button
{
private final int mKeyCode;
private boolean mIsPressed;
private boolean mHasChanged;
/**
* Creates a new instance of KeyButton.
*/
public KeyButton( int keycode )
{
mKeyCode = keycode;
}
/**
* Return the keycode assigned with this button.
*/
public final int getKeyCode()
{
return mKeyCode;
}
final void setIsPressed( boolean flag )
{
mIsPressed = flag;
}
//*********************************************************************************************
//
// Implement Button
//
//*********************************************************************************************
/**
* Features may have a name provided e.g. by the driver.
*/
public String getName()
{
return KeyEvent.getKeyText( mKeyCode );
}
/**
* Tells the state of the button at last update.
*/
public boolean getState()
{
return mIsPressed;
}
/**
* Retrieve the type of the button.
* Pushbutton will deliver <code>true==getState()</code> as long as they are pressed down.
* Togglebuttons will change their state once they are pressed and keep that state
* until they are pressed again.
* @return [ PUSHBUTTON | TOGGLEBUTTON ]
*/
public int getType()
{
return Button.PUSHBUTTON;
}
/**
* Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
}

View File

@@ -0,0 +1,141 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 9. April 2002, 22:43
//**********************************************************************************************
package de.hardcode.jxinput.keyboard;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.security.InvalidParameterException;
/**
* Listen to a JComponent handle handle all associated button objects.
* This is the main worker class for JXKeyboardInputDevice.
*
* @author Herkules
*/
class KeyboardDriver implements KeyListener
{
// HashMap mKeysToObserveMap = new HashMap();
int mNumberOfKeysObserved = 0;
KeyButton [] mKeysObserved = new KeyButton [ 0x100 ];
/**
* Creates a new instance of KeyboardDriver.
*/
public KeyboardDriver()
{
}
/**
* How many buttons are registered?
*/
final int getNumberOfButtons()
{
return mNumberOfKeysObserved;
// return mKeysToObserveMap.size();
}
/**
* Place a new button under my observation.
*/
final boolean registerKeyButton( KeyButton b )
{
final int keycode = b.getKeyCode();
if ( 0 > keycode || 0x100 < keycode )
throw new InvalidKeyCodeException();
if ( null == mKeysObserved[ keycode ] )
{
mKeysObserved[ keycode ] = b;
mNumberOfKeysObserved++;
return true;
}
else
{
return false;
}
// Integer code = new Integer( b.getKeyCode() );
// if ( ! mKeysToObserveMap.containsKey( code ) )
// {
// mKeysToObserveMap.put( code, b );
// return true;
// }
// else
// {
// return false;
// }
}
final void unregisterKeyButton( KeyButton b )
{
final int keycode = b.getKeyCode();
if ( 0 > keycode || 0x100 < keycode )
throw new InvalidKeyCodeException();
if ( null != mKeysObserved[ b.getKeyCode() ] )
{
mKeysObserved[ keycode ] = null;
mNumberOfKeysObserved--;
}
// Integer code = new Integer( b.getKeyCode() );
// mKeysToObserveMap.remove( code );
}
/**
* Retrieve the button from its keycode.
*/
final KeyButton getButton( int keycode )
{
if ( 0 > keycode || 0x100 < keycode )
throw new InvalidKeyCodeException();
return mKeysObserved[ keycode ];
// Integer code = new Integer( keycode );
// return (KeyButton)mKeysToObserveMap.get( code );
}
//*********************************************************************************************
//
// Implement KeyListener
//
//*********************************************************************************************
public void keyPressed( KeyEvent keyEvent )
{
KeyButton b = getButton( keyEvent.getKeyCode() );
if ( null != b )
b.setIsPressed( true );
}
public void keyReleased( KeyEvent keyEvent )
{
KeyButton b = getButton( keyEvent.getKeyCode() );
if ( null != b )
b.setIsPressed( false );
}
public void keyTyped( KeyEvent keyEvent )
{
// Intentionally empty.
}
}

View File

@@ -0,0 +1,10 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>de.hardcode.jxinput.keyboard</TITLE>
</HEAD>
<BODY>
Connects Swing keyboard handling to the JXInput infrastructure.
</BODY>
</HTML>

View File

@@ -0,0 +1,39 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 20. Februar 2002, 22:19
//**********************************************************************************************
package de.hardcode.jxinput.test;
import de.hardcode.jxinput.event.JXInputEventManager;
import de.hardcode.jxinput.event.JXInputAxisEventListener;
import de.hardcode.jxinput.event.JXInputAxisEvent;
import de.hardcode.jxinput.Axis;
/**
* Example listener to an axis.
*
* @author Herkules
*/
public class AxisListener
implements JXInputAxisEventListener
{
/**
* Creates a new instance of AxisListener.
*/
public AxisListener( Axis axis )
{
JXInputEventManager.addListener( this, axis, 0.1 );
}
public void changed( JXInputAxisEvent ev )
{
System.out.println( "Axis " + ev.getAxis().getName() + " changed : value=" + ev.getAxis().getValue() + ", event causing delta=" + ev.getDelta() );
}
}

View File

@@ -0,0 +1,38 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 20. Februar 2002, 22:19
//**********************************************************************************************
package de.hardcode.jxinput.test;
import de.hardcode.jxinput.event.JXInputEventManager;
import de.hardcode.jxinput.event.JXInputButtonEventListener;
import de.hardcode.jxinput.event.JXInputButtonEvent;
import de.hardcode.jxinput.Button;
/**
* Sample button listener.
*
* @author Herkules
*/
public class ButtonListener implements JXInputButtonEventListener
{
/**
* Creates a new instance of AxisListener.
*/
public ButtonListener( Button button )
{
JXInputEventManager.addListener( this, button );
}
public void changed( JXInputButtonEvent ev )
{
System.out.println( "Button " + ev.getButton().getName() + " changed : state=" + ev.getButton().getState() );
}
}

View File

@@ -0,0 +1,37 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 20. Februar 2002, 22:19
//**********************************************************************************************
package de.hardcode.jxinput.test;
import de.hardcode.jxinput.event.JXInputEventManager;
import de.hardcode.jxinput.event.JXInputDirectionalEventListener;
import de.hardcode.jxinput.event.JXInputDirectionalEvent;
import de.hardcode.jxinput.Directional;
/**
* Sample directional listener.
*
* @author Herkules
*/
public class DirectionalListener implements JXInputDirectionalEventListener
{
/**
* Creates a new instance of AxisListener.
*/
public DirectionalListener( Directional directional )
{
JXInputEventManager.addListener( this, directional, 1.0 );
}
public void changed( JXInputDirectionalEvent ev )
{
System.out.println( "Directional " + ev.getDirectional().getName() + " changed : direction=" + ev.getDirectional().getDirection() + ", value=" + ev.getDirectional().getValue() + ", event causing delta=" + ev.getDirectionDelta() );
}
}

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.0" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Events>
<EventHandler event="componentShown" listener="java.awt.event.ComponentListener" parameters="java.awt.event.ComponentEvent" handler="OnShow"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout">
<Property name="horizontalGap" type="int" value="2"/>
<Property name="verticalGap" type="int" value="2"/>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="mAxesPanelContainer">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.BevelBorderInfo">
<BevelBorder/>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="mAxesPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="North"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="1"/>
<Property name="rows" type="int" value="1"/>
<Property name="verticalGap" type="int" value="20"/>
</Layout>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="mDirectionalPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.BevelBorderInfo">
<BevelBorder/>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="South"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="1"/>
<Property name="rows" type="int" value="1"/>
</Layout>
</Container>
<Container class="javax.swing.JScrollPane" name="mButtonScrollPane">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="East"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="mButtonsPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.BevelBorderInfo">
<BevelBorder/>
</Border>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
<Property name="columns" type="int" value="1"/>
<Property name="rows" type="int" value="1"/>
</Layout>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@@ -0,0 +1,296 @@
/*
* JXInputDevicePanel.java
*
* Created on 23. Januar 2002, 22:19
*/
package de.hardcode.jxinput.test;
import de.hardcode.jxinput.JXInputManager;
import de.hardcode.jxinput.JXInputDevice;
import de.hardcode.jxinput.Axis;
import de.hardcode.jxinput.Directional;
import de.hardcode.jxinput.Button;
import javax.swing.*;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.BorderLayout;
import java.awt.Font;
import java.util.Dictionary;
import java.util.Enumeration;
/**
*
* @author Herkules
*/
public class JXInputDevicePanel extends javax.swing.JPanel
{
private static final Font AXIS_SLIDER_FONT = new Font( "Verdana", Font.PLAIN, 9 );
private final JXInputDevice mDev;
private final ArrayList mAxisSliders = new ArrayList();
private final ArrayList mButtonCheckboxes = new ArrayList();
private final ArrayList mDirectionalLabels = new ArrayList();
/** Creates new form JXInputDevicePanel */
public JXInputDevicePanel( JXInputDevice dev )
{
mDev = dev;
initComponents();
initFromDevice();
}
/**
* Helper class connecting a JSlider with an Axis.
*/
private class AxisSlider extends JSlider
{
Axis mAxis;
AxisSlider( Axis axis )
{
super( ( Axis.SLIDER == axis.getType() ? 0 : -100 ), 100 );
this.setMajorTickSpacing( Axis.SLIDER == axis.getType() ? 25 : 50 );
this.setMinorTickSpacing( 5 );
this.setPaintTicks( true );
this.setPaintLabels( true );
this.setEnabled( false );
Dictionary labeldict = this.getLabelTable();
Enumeration labels = labeldict.elements();
while ( labels.hasMoreElements() )
{
JLabel label = (JLabel)labels.nextElement();
label.setFont( AXIS_SLIDER_FONT );
label.setSize( 32, 12 );
label.setHorizontalAlignment( SwingConstants.LEFT );
}
mAxis = axis;
}
void update()
{
int ax = (int)(mAxis.getValue() * 100.0);
//
// Only if value really changes
//
if ( ax != this.getValue() )
{
this.setValue( ax );
this.setToolTipText( mAxis.getName() + ": " + Double.toString( mAxis.getValue() ) );
}
}
}
private class ButtonCheckbox extends JCheckBox
{
Button mButton;
ButtonCheckbox( Button button )
{
super( button.getName() );
this.setEnabled( false );
mButton = button;
}
void update()
{
boolean state = mButton.getState();
//
// Only if value really changes
//
if ( state != this.isSelected() )
{
this.setSelected( state );
}
}
}
private class DirectionalLabel extends JLabel
{
Directional mDirectional;
int mCurrent = 0;
DirectionalLabel( Directional directional )
{
super( directional.getName() );
mDirectional = directional;
}
void update()
{
int dir = mDirectional.getDirection();
//
// Only if value really changes
//
if ( dir != mCurrent )
{
this.setText( mDirectional.getName() + ": " + ( mDirectional.isCentered() ? "-" : Integer.toString( dir ) ) );
mCurrent = dir;
}
}
}
/**
* Setup the dialogs content from the JXInputDevice.
*/
void initFromDevice()
{
if ( null != mDev )
{
((GridLayout)mAxesPanel.getLayout()).setRows( mDev.getNumberOfAxes() );
for ( int i = 0; i < mDev.getMaxNumberOfAxes(); ++i )
{
if ( null != mDev.getAxis( i ) )
{
AxisSlider slider = new AxisSlider( mDev.getAxis( i ) );
JLabel name = new JLabel( mDev.getAxis( i ).getName() );
name.setVerticalAlignment( SwingConstants.TOP );
name.setHorizontalAlignment( SwingConstants.CENTER );
name.setPreferredSize( new java.awt.Dimension( 90, 0 ) );
JPanel p = new JPanel();
p.setLayout( new BorderLayout() );
p.add( name, BorderLayout.WEST );
p.add( slider, BorderLayout.CENTER );
mAxesPanel.add( p );
// Add to list of all AxisSlider controls
mAxisSliders.add( slider );
// Add an event listener:
new AxisListener( mDev.getAxis( i ) );
}
}
((GridLayout)mButtonsPanel.getLayout()).setRows( mDev.getNumberOfButtons() );
for ( int i = 0; i < mDev.getMaxNumberOfButtons(); ++i )
{
if ( null != mDev.getButton( i ) )
{
ButtonCheckbox chk = new ButtonCheckbox( mDev.getButton( i ) );
mButtonCheckboxes.add( chk );
mButtonsPanel.add( chk );
// Add an event listener:
new ButtonListener( mDev.getButton( i ) );
}
}
((GridLayout)mDirectionalPanel.getLayout()).setRows( mDev.getNumberOfDirectionals() / 2 );
for ( int i = 0; i < mDev.getMaxNumberOfDirectionals(); ++i )
{
if ( null != mDev.getDirectional( i ) )
{
DirectionalLabel lbl = new DirectionalLabel( mDev.getDirectional( i ) );
mDirectionalLabels.add( lbl );
mDirectionalPanel.add( lbl );
// Add an event listener:
new DirectionalListener( mDev.getDirectional( i ) );
}
}
}
}
public void update()
{
Iterator it = mAxisSliders.iterator();
while ( it.hasNext() )
{
((AxisSlider)it.next()).update();
}
it = mButtonCheckboxes.iterator();
while ( it.hasNext() )
{
((ButtonCheckbox)it.next()).update();
}
it = mDirectionalLabels.iterator();
while ( it.hasNext() )
{
((DirectionalLabel)it.next()).update();
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents()
{
mAxesPanelContainer = new javax.swing.JPanel();
mAxesPanel = new javax.swing.JPanel();
mDirectionalPanel = new javax.swing.JPanel();
mButtonScrollPane = new javax.swing.JScrollPane();
mButtonsPanel = new javax.swing.JPanel();
setLayout(new java.awt.BorderLayout(2, 2));
addComponentListener(new java.awt.event.ComponentAdapter()
{
public void componentShown(java.awt.event.ComponentEvent evt)
{
OnShow(evt);
}
});
mAxesPanelContainer.setLayout(new java.awt.BorderLayout());
mAxesPanelContainer.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
mAxesPanel.setLayout(new java.awt.GridLayout(1, 1, 0, 20));
mAxesPanelContainer.add(mAxesPanel, java.awt.BorderLayout.NORTH);
add(mAxesPanelContainer, java.awt.BorderLayout.CENTER);
mDirectionalPanel.setLayout(new java.awt.GridLayout(1, 1));
mDirectionalPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
add(mDirectionalPanel, java.awt.BorderLayout.SOUTH);
mButtonsPanel.setLayout(new java.awt.GridLayout(1, 1));
mButtonsPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
mButtonScrollPane.setViewportView(mButtonsPanel);
add(mButtonScrollPane, java.awt.BorderLayout.EAST);
}// </editor-fold>//GEN-END:initComponents
private void OnShow(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_OnShow
{//GEN-HEADEREND:event_OnShow
// Commented: the focus is held by a parent component
// System.out.println("OnShow");
// this.requestFocus();
}//GEN-LAST:event_OnShow
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel mAxesPanel;
private javax.swing.JPanel mAxesPanelContainer;
private javax.swing.JScrollPane mButtonScrollPane;
private javax.swing.JPanel mButtonsPanel;
private javax.swing.JPanel mDirectionalPanel;
// End of variables declaration//GEN-END:variables
}

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.0" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="title" type="java.lang.String" value="JXInput (C) 2001-2006 HARDCODE Dev."/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<Events>
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="closeDialog"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="mMainPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout">
<Property name="horizontalGap" type="int" value="10"/>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="mLabelNoDevice">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="No JXInputDevice available!"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.SoftBevelBorderInfo">
<BevelBorder/>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="North"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JTabbedPane" name="mDevicesTabbedPane">
<Events>
<EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="mDevicesTabbedPaneFocusGained"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
</Container>
<Component class="javax.swing.JButton" name="mButtonReset">
<Properties>
<Property name="text" type="java.lang.String" value="Reset "/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mButtonResetActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="South"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@@ -0,0 +1,286 @@
//**********************************************************************************************
// Dipl. Phys. Joerg Plewe, HARDCODE Development
// Created on 27. Dezember 2001, 01:15
//**********************************************************************************************
package de.hardcode.jxinput.test;
import de.hardcode.jxinput.*;
import de.hardcode.jxinput.event.*;
import de.hardcode.jxinput.keyboard.JXKeyboardInputDevice;
import de.hardcode.jxinput.virtual.JXVirtualInputDevice;
import de.hardcode.jxinput.virtual.VirtualAxis;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
/**
* Test dialog showing some features of JXInput.
* @author Herkules
*/
public class JXInputTestDialog extends javax.swing.JDialog
implements ActionListener
{
private JXKeyboardInputDevice mKeyboardDevice = null;
private JXVirtualInputDevice mVirtualDevice = null;
Button mButtonUp;
Button mButtonDown;
Button mButtonLeft;
Button mButtonRight;
Button mButtonFire;
Button mButtonSpace;
/** Creates new form JXInputTestDialog */
public JXInputTestDialog(java.awt.Frame parent, boolean modal)
{
super(parent, modal);
initComponents();
configureKeyboardInputDevice();
configureVirtualInputDevice();
initDevicePanels();
pack();
// Request the focus so that the keyboarddevice can work
mMainPanel.requestFocus();
new Timer( 50, this ).start();
// Uncomment this line as an alternative to the Timer above.
// Don't use both!!
//JXInputEventManager.setTriggerIntervall( 50 );
}
/**
* Implement ActionListener#actionPerformed().
* This is called by the Timer.
*/
public void actionPerformed( ActionEvent e )
{
JXInputManager.updateFeatures();
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
for ( int i = 0; i < mDevicesTabbedPane.getComponentCount(); ++i )
{
((JXInputDevicePanel)mDevicesTabbedPane.getComponent( i )).update();
}
}
}
);
}
/**
* Configure a test JXKeyboardInputdevice.
*/
void configureKeyboardInputDevice()
{
mKeyboardDevice = JXInputManager.createKeyboardDevice();
mKeyboardDevice.createButton( KeyEvent.VK_ESCAPE );
mKeyboardDevice.createButton( KeyEvent.VK_F1 );
mKeyboardDevice.createButton( KeyEvent.VK_F2 );
mKeyboardDevice.createButton( KeyEvent.VK_F3 );
mKeyboardDevice.createButton( KeyEvent.VK_F4 );
mKeyboardDevice.createButton( KeyEvent.VK_LEFT );
mKeyboardDevice.createButton( KeyEvent.VK_RIGHT );
mKeyboardDevice.createButton( KeyEvent.VK_UP );
mKeyboardDevice.createButton( KeyEvent.VK_DOWN );
mKeyboardDevice.createButton( KeyEvent.VK_PAGE_UP );
mKeyboardDevice.createButton( KeyEvent.VK_PAGE_DOWN );
mButtonSpace = mKeyboardDevice.createButton( KeyEvent.VK_SPACE );
mButtonLeft = mKeyboardDevice.createButton( KeyEvent.VK_A );
mButtonRight = mKeyboardDevice.createButton( KeyEvent.VK_D );
mButtonDown = mKeyboardDevice.createButton( KeyEvent.VK_S );
mButtonUp = mKeyboardDevice.createButton( KeyEvent.VK_W );
// Configure it to make it listen to the main panel.
// I try to keep the kbd focus on it.
mKeyboardDevice.listenTo( mMainPanel );
}
/**
* Configure a test JXVirtualInputdevice.
*/
void configureVirtualInputDevice()
{
mVirtualDevice = JXInputManager.createVirtualDevice();
Button firebutton;
//
// Remember 'fire' button of first device for use
// in the virtual device.
// For we ran configureKeyboardInputDevice() before,
// getJXInputDevice( 0 ) should not return null
//
firebutton = JXInputManager.getJXInputDevice( 0 ).getButton( 0 );
VirtualAxis x = mVirtualDevice.createAxis( Axis.ID_X );
x.setButtons( mButtonRight, mButtonLeft );
x.setName( "x: A-D" );
VirtualAxis y = mVirtualDevice.createAxis( Axis.ID_Y );
y.setButtons( mButtonUp, mButtonDown );
y.setSpringSpeed( 0.0 );
y.setName( "y: S|W" );
VirtualAxis slider = mVirtualDevice.createAxis( Axis.ID_SLIDER0 );
slider.setIncreaseButton( mButtonSpace );
slider.setTimeFor0To1( 2000 );
slider.setName( "<space>" );
slider.setType( Axis.SLIDER );
if ( null != firebutton )
{
slider = mVirtualDevice.createAxis( Axis.ID_SLIDER1 );
slider.setIncreaseButton( firebutton );
slider.setTimeFor0To1( 2000 );
slider.setName( "JoyButton 0" );
}
}
/**
* Initialize one panel for each device available.
*/
void initDevicePanels()
{
int cnt = JXInputManager.getNumberOfDevices();
mLabelNoDevice.setVisible( cnt == 0 );
mDevicesTabbedPane.setVisible( cnt != 0 );
for ( int i = 0; i < cnt; ++i )
{
JXInputDevice dev = JXInputManager.getJXInputDevice( i );
if ( null != dev )
{
//
// Setup an own panel for each device.
//
JPanel panel = new JXInputDevicePanel( dev );
mDevicesTabbedPane.addTab( dev.getName(), panel );
}
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents()
{
mMainPanel = new javax.swing.JPanel();
mLabelNoDevice = new javax.swing.JLabel();
mDevicesTabbedPane = new javax.swing.JTabbedPane();
mButtonReset = new javax.swing.JButton();
setTitle("JXInput (C) 2001-2006 HARDCODE Dev.");
addWindowListener(new java.awt.event.WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent evt)
{
closeDialog(evt);
}
});
mMainPanel.setLayout(new java.awt.BorderLayout(10, 0));
mLabelNoDevice.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
mLabelNoDevice.setText("No JXInputDevice available!");
mLabelNoDevice.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
mMainPanel.add(mLabelNoDevice, java.awt.BorderLayout.NORTH);
mDevicesTabbedPane.addFocusListener(new java.awt.event.FocusAdapter()
{
public void focusGained(java.awt.event.FocusEvent evt)
{
mDevicesTabbedPaneFocusGained(evt);
}
});
mMainPanel.add(mDevicesTabbedPane, java.awt.BorderLayout.CENTER);
mButtonReset.setText("Reset ");
mButtonReset.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
mButtonResetActionPerformed(evt);
}
});
mMainPanel.add(mButtonReset, java.awt.BorderLayout.SOUTH);
getContentPane().add(mMainPanel, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>//GEN-END:initComponents
private void mButtonResetActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_mButtonResetActionPerformed
{//GEN-HEADEREND:event_mButtonResetActionPerformed
while ( this.mDevicesTabbedPane.getTabCount() > 0 )
this.mDevicesTabbedPane.removeTabAt( 0 );
JXInputManager.reset();
configureKeyboardInputDevice();
configureVirtualInputDevice();
initDevicePanels();
pack();
// Request the focus so that the keyboarddevice can work
mMainPanel.requestFocus();
}//GEN-LAST:event_mButtonResetActionPerformed
private void mDevicesTabbedPaneFocusGained(java.awt.event.FocusEvent evt)//GEN-FIRST:event_mDevicesTabbedPaneFocusGained
{//GEN-HEADEREND:event_mDevicesTabbedPaneFocusGained
// Switch focus back to main panel!
this.mMainPanel.requestFocus();
}//GEN-LAST:event_mDevicesTabbedPaneFocusGained
/** Closes the dialog */
private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
setVisible(false);
dispose();
System.exit( 0 );
}//GEN-LAST:event_closeDialog
/**
* Allow the dialog to run standalone.
* @param args the command line arguments
*/
public static void main(String args[])
{
new JXInputTestDialog(new javax.swing.JFrame(), true).setVisible(true);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton mButtonReset;
private javax.swing.JTabbedPane mDevicesTabbedPane;
private javax.swing.JLabel mLabelNoDevice;
private javax.swing.JPanel mMainPanel;
// End of variables declaration//GEN-END:variables
}

View File

@@ -0,0 +1,98 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 17. April 2002, 23:24
//**********************************************************************************************
package de.hardcode.jxinput.util;
import de.hardcode.jxinput.Axis;
/**
*
* @author Herkules
*/
public class LatestChangedValueAxis implements Axis
{
private final Axis mAxis1;
private final Axis mAxis2;
private Axis mAxisInUse;
private double mSaved1;
private double mSaved2;
/**
* Creates a new instance of MeanValueAxis.
*/
public LatestChangedValueAxis(Axis a1, Axis a2)
{
mAxis1 = a1;
mAxis2 = a2;
mAxisInUse = a1;
mSaved1 = a1.getValue();
mSaved2 = a2.getValue();
}
/**
* Features may have a name provided e.g. by the driver.
*/
public String getName()
{
return mAxis1.getName();
}
/** Inform about the resolution of the axis.
*
* @return resolution, e.g. 2^-16
*/
public double getResolution()
{
return mAxis1.getResolution();
}
/**
* Retrieve the type of the axis.
*
* @return [ TRANSLATION | ROTATION | SLIDER ]
*/
public int getType()
{
return mAxis1.getType();
}
/** Returns the current value of the axis.
* The range of the result depends on the axis type.
*s
* @return value [-1.0,1.0] or [0.0,1.0]
*/
public double getValue()
{
double v1 = mAxis1.getValue();
double v2 = mAxis2.getValue();
if ( Math.abs( v2 - mSaved2 ) > 0.2 )
{
mAxisInUse = mAxis2;
mSaved2 = v2;
}
if ( Math.abs( v1 - mSaved1 ) > 0.2 )
{
mAxisInUse = mAxis1;
mSaved1 = v1;
}
return mAxisInUse.getValue();
}
/** Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
}

View File

@@ -0,0 +1,52 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 23. Dezember 2002, 19:21
//**********************************************************************************************
package de.hardcode.jxinput.util;
import de.hardcode.jxinput.Button;
/**
*
* @author Herkules
*/
public class OrButton implements Button
{
private final Button mButton1;
private final Button mButton2;
/**
* Creates a new instance of OrButton.
*/
public OrButton( Button b1, Button b2 )
{
mButton1 = b1;
mButton2 = b2;
}
public String getName()
{
return mButton1.getName();
}
public boolean getState()
{
return mButton1.getState() || mButton2.getState();
}
public int getType()
{
return mButton1.getType();
}
public boolean hasChanged()
{
return mButton1.hasChanged() || mButton2.hasChanged();
}
}

View File

@@ -0,0 +1,140 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 9. April 2002, 22:40
//**********************************************************************************************
package de.hardcode.jxinput.virtual;
import de.hardcode.jxinput.*;
/**
* Virtual input device.
*
* @author Herkules
*/
public class JXVirtualInputDevice implements JXInputDevice
{
private static final String DEVICENAME = "Virtual Device";
/** The driver doing all the real work. */
private final VirtualDriver mDriver = new VirtualDriver();
/**
* Creates a new instance of JXKeyboardInputDevice.
*/
public JXVirtualInputDevice()
{
}
/**
* The virtual input device needs to be updated regularly.
*/
public final void update( long deltaT )
{
//
// Delegate the update call to the driver.
//
mDriver.update( deltaT );
}
/**
* Create a virtual axis object with a certain ID, e.g. Axis.ID_X.
*/
public VirtualAxis createAxis( int id )
{
VirtualAxis a;
a = new VirtualAxis( id );
mDriver.registerVirtualAxis( id, a );
return a;
}
public void removeAxis( VirtualAxis a )
{
mDriver.unregisterVirtualAxis( a );
}
//*********************************************************************************************
//
// Implement JXInputDevice
//
//*********************************************************************************************
public Axis getAxis(int idx)
{
return mDriver.getAxis( idx );
}
public Button getButton(int idx)
{
// No virtual buttons.
return null;
}
public Directional getDirectional(int idx)
{
// No virtual directionals.
return null;
}
/** Maximum number of axes as an upper bound for index values. */
public int getMaxNumberOfAxes()
{
return Axis.NUMBER_OF_ID;
}
/** Maximum number of buttons as an upper bound for index values. */
public int getMaxNumberOfButtons()
{
// No virtual buttons.
return 0;
}
/** Maximum number of directional features as an upper bound for index values. */
public int getMaxNumberOfDirectionals()
{
// No virtual directionals.
return 0;
}
/**
* Devices may have a name.
* This name might be provided by a system dependant driver.
*/
public String getName()
{
return DEVICENAME;
}
/** Actual number of available axes. */
public int getNumberOfAxes()
{
// No axes on keyboard.
return mDriver.getNumberOfAxes();
}
/** Actual number of available buttons. */
public int getNumberOfButtons()
{
return 0;
}
/** Actual number of available directional features. */
public int getNumberOfDirectionals()
{
// No directionals on keyboard.
return 0;
}
}

View File

@@ -0,0 +1,207 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 11. April 2002, 23:40
//**********************************************************************************************
package de.hardcode.jxinput.virtual;
import de.hardcode.jxinput.Axis;
import de.hardcode.jxinput.Button;
import java.security.InvalidParameterException;
/**
*
* @author J<>rg Plewe
*/
public class VirtualAxis
implements Axis
{
private int mType = Axis.TRANSLATION;
private final int mID;
private String mName = "VirtualAxis";
private double mCurrentValue = 0;
private Button mButtonIncrease = null;
private Button mButtonDecrease = null;
private double mSpeed = 1.0 / 500.0;
private double mSpringSpeed = 1.0 / 500.0;
/**
* Creates a new instance of VirtualAxis.
*/
public VirtualAxis( int id )
{
mID = id;
}
/**
* Set the type of this axis to be either <code>Axis.ROTATION</code>,
* <code>Axis.TRANSLATION</code> or <code>Axis.SLIDER</code>.
*/
public void setType( int type )
{
if ( Axis.ROTATION != type
&& Axis.TRANSLATION != type
&& Axis.SLIDER != type
)
throw new InvalidParameterException( "Invalid type for axis!" );
mType = type;
}
/**
* Update features under my control.
*/
final void update( long deltaT )
{
double change = mSpeed * deltaT;
double springchange = mSpringSpeed * deltaT;
boolean doincrease = ( null != mButtonIncrease && mButtonIncrease.getState() );
boolean dodecrease = ( null != mButtonDecrease && mButtonDecrease.getState() );
boolean iscontrolled = doincrease || dodecrease;
double controlledchange = 0.0;
if ( doincrease )
controlledchange += change;
if ( dodecrease )
controlledchange -= change;
mCurrentValue += controlledchange;
if ( mCurrentValue > 0.0 && ! doincrease )
{
springchange = Math.min( mCurrentValue, springchange );
mCurrentValue -= springchange;
}
if ( mCurrentValue < 0.0 && ! dodecrease )
{
springchange = Math.min( -mCurrentValue, springchange );
mCurrentValue += springchange;
}
//
// Hold value within range
//
if ( mCurrentValue > 1.0 )
mCurrentValue = 1.0;
double lowerlimit = Axis.SLIDER == mType ? 0.0 : -1.0;
if ( mCurrentValue < lowerlimit )
mCurrentValue = lowerlimit;
}
/**
* Set the button to increase the axis for a single button axis.
*/
public final void setIncreaseButton( Button b )
{
if ( null == b )
throw new InvalidParameterException( "Button may not be null!" );
mButtonIncrease = b;
}
/**
* Set the buttons to increase and descrease the axis.
*/
public final void setButtons( Button increase, Button decrease )
{
if ( null == increase || null == decrease )
throw new InvalidParameterException( "Buttons may not be null!" );
mButtonIncrease = increase;
mButtonDecrease = decrease;
}
public final void setSpeed( double speed )
{
mSpeed = speed;
}
public final void setSpringSpeed( double springspeed )
{
mSpringSpeed = springspeed;
}
public final void setTimeFor0To1( int ms )
{
if ( 0 >= ms )
mSpeed = 0.0;
else
mSpeed = 1.0/ ms;
}
public final void setTimeFor1To0( int ms )
{
if ( 0 >= ms )
mSpringSpeed = 0.0;
else
mSpringSpeed = 1.0/ ms;
}
public final void setName( String name )
{
mName = name;
}
//*********************************************************************************************
//
// Implement Axis
//
//*********************************************************************************************
/**
* Features may have a name provided e.g. by the driver.
*/
public String getName()
{
return mName;
}
/**
* Inform about the resolution of the axis.
*
* @return resolution, e.g. 2^-16
*/
public double getResolution()
{
return 1.0/65536.0;
}
/**
* Retrieve the type of the axis.
* @return [ TRANSLATION | ROTATION | SLIDER ]
*/
public int getType()
{
return mType;
}
/** Returns the current value of the axis.
* The range of the result depends on the axis type.
*
* @return value [-1.0,1.0] or [0.0,1.0]
*/
public double getValue()
{
return mCurrentValue;
}
/** Denote wether this feature has changed beyond it's resolution since it got last
* updated.
*/
public boolean hasChanged()
{
return true;
}
}

View File

@@ -0,0 +1,95 @@
//**********************************************************************************************
// (C) Copyright 2002 by Dipl. Phys. Joerg Plewe, HARDCODE Development
// All rights reserved. Copying, modification,
// distribution or publication without the prior written
// consent of the author is prohibited.
//
// Created on 9. April 2002, 22:43
//**********************************************************************************************
package de.hardcode.jxinput.virtual;
import java.util.ArrayList;
import de.hardcode.jxinput.Axis;
/**
* This is the main worker class for JXVirtualInputDevice.
*
* @author Herkules
*/
class VirtualDriver
{
private final VirtualAxis[] mVAxes = new VirtualAxis[ Axis.NUMBER_OF_ID ];
/**
* Creates a new instance of KeyboardDriver.
*/
VirtualDriver()
{
}
/**
* Update features under my control.
*/
final void update( long deltaT )
{
//
// Delegate the update call to the axes in use.
//
for ( int i = 0; i < mVAxes.length; i++ )
{
if ( null != mVAxes[ i ] )
mVAxes[ i ].update( deltaT );
}
}
/**
* How many axes are registered?
*/
final int getNumberOfAxes()
{
int ctr = 0;
for ( int i = 0; i < mVAxes.length; i++ )
{
if ( null != mVAxes[ i ] )
ctr++;
}
return ctr;
}
Axis getAxis(int idx)
{
return mVAxes[ idx ];
}
/**
* Place a new axis under my observation.
*/
final void registerVirtualAxis( int id, VirtualAxis a )
{
mVAxes[ id ] = a;
}
/**
* Remove an axis from my control.
*/
final void unregisterVirtualAxis( VirtualAxis a )
{
for ( int i = 0; i < mVAxes.length; ++i )
{
if ( mVAxes[ i ] == a )
{
mVAxes[ i ] = null;
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>de.hardcode.jxinput.virtual</TITLE>
</HEAD>
<BODY>
Allows to define virtual axes that are not derived from any device
but from other JXInput feature objects.
</BODY>
</HTML>

BIN
vendor/JXInput/0.3.4/jxinput.dll vendored Normal file

Binary file not shown.

BIN
vendor/JXInput/0.3.4/jxinput.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,34 @@
# Project: wpcom
# Makefile created by Dev-C++ 4.9.9.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES =
OBJ = WinampController.o $(RES)
LINKOBJ = WinampController.o $(RES)
LIBS = -L"E:/java/Dev-Cpp/lib" --no-export-all-symbols --add-stdcall-alias
INCS = -I"E:/java/Dev-Cpp/include" -I"E:/Program Files/Java/jdk1.6.0_11/include" -I"E:/Program Files/Java/jdk1.6.0_11/include/win32"
CXXINCS = -I"E:/java/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"E:/java/Dev-Cpp/include/c++/3.4.2/backward" -I"E:/java/Dev-Cpp/include/c++/3.4.2/mingw32" -I"E:/java/Dev-Cpp/include/c++/3.4.2" -I"E:/java/Dev-Cpp/include" -I"E:/Program Files/Java/jdk1.6.0_11/include" -I"E:/Program Files/Java/jdk1.6.0_11/include/win32"
BIN = ../../wpcom.dll
CXXFLAGS = $(CXXINCS) -DBUILDING_DLL=1
CFLAGS = $(INCS) -DBUILDING_DLL=1
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before ../../wpcom.dll all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
DLLWRAP=dllwrap.exe
DEFFILE=../../libwpcom.def
STATICLIB=../../libwpcom.a
$(BIN): $(LINKOBJ)
$(DLLWRAP) --output-def $(DEFFILE) --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
WinampController.o: WinampController.c
$(CC) -c WinampController.c -o WinampController.o $(CFLAGS)

View File

@@ -0,0 +1,62 @@
#define WINAMP_FILE_QUIT 40001
#define WINAMP_OPTIONS_PREFS 40012
#define WINAMP_OPTIONS_AOT 40019
#define WINAMP_FILE_REPEAT 40022
#define WINAMP_FILE_SHUFFLE 40023
#define WINAMP_HIGH_PRIORITY 40025
#define WINAMP_FILE_PLAY 40029
#define WINAMP_OPTIONS_EQ 40036
#define WINAMP_OPTIONS_ELAPSED 40037
#define WINAMP_OPTIONS_REMAINING 40038
#define WINAMP_OPTIONS_PLEDIT 40040
#define WINAMP_HELP_ABOUT 40041
#define WINAMP_MAINMENU 40043
#define WINAMP_BUTTON1 40044
#define WINAMP_BUTTON2 40045
#define WINAMP_BUTTON3 40046
#define WINAMP_BUTTON4 40047
#define WINAMP_BUTTON5 40048
#define WINAMP_VOLUMEUP 40058
#define WINAMP_VOLUMEDOWN 40059
#define WINAMP_FFWD5S 40060
#define WINAMP_REW5S 40061
#define WINAMP_NEXT_WINDOW 40063
#define WINAMP_OPTIONS_WINDOWSHADE 40064
#define WINAMP_BUTTON1_SHIFT 40144
#define WINAMP_BUTTON2_SHIFT 40145
#define WINAMP_BUTTON3_SHIFT 40146
#define WINAMP_BUTTON4_SHIFT 40147
#define WINAMP_BUTTON5_SHIFT 40148
#define WINAMP_BUTTON1_CTRL 40154
#define WINAMP_BUTTON2_CTRL 40155
#define WINAMP_BUTTON3_CTRL 40156
#define WINAMP_BUTTON4_CTRL 40157
#define WINAMP_BUTTON5_CTRL 40158
#define WINAMP_OPTIONS_DSIZE 40165
#define IDC_SORT_FILENAME 40166
#define IDC_SORT_FILETITLE 40167
#define IDC_SORT_ENTIREFILENAME 40168
#define IDC_SELECTALL 40169
#define IDC_SELECTNONE 40170
#define IDC_SELECTINV 40171
#define IDM_EQ_LOADPRE 40172
#define IDM_EQ_LOADMP3 40173
#define IDM_EQ_LOADDEFAULT 40174
#define IDM_EQ_SAVEPRE 40175
#define IDM_EQ_SAVEMP3 40176
#define IDM_EQ_SAVEDEFAULT 40177
#define IDM_EQ_DELPRE 40178
#define IDM_EQ_DELMP3 40180
#define IDC_PLAYLIST_PLAY 40184
#define WINAMP_FILE_LOC 40185
#define WINAMP_OPTIONS_EASYMOVE 40186
#define WINAMP_FILE_DIR 40187
#define WINAMP_EDIT_ID3 40188
#define WINAMP_TOGGLE_AUTOSCROLL 40189
#define WINAMP_VISSETUP 40190
#define WINAMP_PLGSETUP 40191
#define WINAMP_VISPLUGIN 40192
#define WINAMP_JUMP 40193
#define WINAMP_JUMPFILE 40194
#define WINAMP_JUMP10FWD 40195
#define WINAMP_JUMP10BACK 40197

View File

@@ -0,0 +1,587 @@
/* meu .h */
#include "WinampController.h"
/* mingw */
#include <windows.h>
#include <w32api.h>
#include <winuser.h>
/* winamp sdk */
#include "wa_ipc.h"
#include "WINAMPCMD.H"
const int WA_CLOSE = 40001 ;
const int WA_PLAY = WINAMP_BUTTON2;
const int WA_STOP = WINAMP_BUTTON4;
const int WA_PAUSE = WINAMP_BUTTON3;
const int WA_PREVTRACK = WINAMP_BUTTON1;
const int WA_NEXTTRACK = WINAMP_BUTTON5;
const int WA_FWD5SECS = WINAMP_FFWD5S;
const int WA_REW5SECS = WINAMP_REW5S;
const int WA_PLAYLISTLEN = IPC_GETLISTLENGTH;
const int WA_SETVOLUME = IPC_SETVOLUME;
const int WA_SETPLAYLISTPOS = IPC_SETPLAYLISTPOS;
const int WA_WRITEPLAYLIST = IPC_WRITEPLAYLIST;
const int WA_ENQUEUEFILE = IPC_ENQUEUEFILE;
const int WA_VOLUMEUP = WINAMP_VOLUMEUP;
const int WA_VOLUMEDOWN = WINAMP_VOLUMEDOWN;
const int WA_CLEARPLAYLIST = IPC_DELETE;
const int WA_NOTHING = 0;
const int WA_TRACK_LENGTH = 1;
const int WA_RESTART = IPC_RESTARTWINAMP;
const int WA_REFRESHPLCACHE = IPC_REFRESHPLCACHE;
const int WA_GETSHUFFLESTATUS = IPC_GET_SHUFFLE;
const int WA_GETREPEATSTATUS = IPC_GET_REPEAT;
const int WA_SETSHUFFLESTATUS = IPC_SET_SHUFFLE;
const int WA_SETREPEATSTATUS = IPC_SET_REPEAT;
const int WA_GETSTATUS = IPC_ISPLAYING;
const int WA_GETLISTPOS = IPC_GETLISTPOS;
const int WA_GETTITLE = IPC_GETPLAYLISTTITLE;
const int WA_VERSION = IPC_GETVERSION;
const int WA_FILENAMEINLIST = IPC_GETPLAYLISTFILE;
const int WA_GETFILEINFO = IPC_GET_EXTENDED_FILE_INFO;
HWND hwnd_winamp = NULL;
INT position = 0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
char messageReturn[255];
wchar_t* wMessageReturn;
LPDWORD temp;
void initWinampHandle() {
hwnd_winamp = NULL;
if (hwnd_winamp == NULL) {
hwnd_winamp = FindWindow("Winamp v1.x", NULL);
}
if (hwnd_winamp == NULL) {
hwnd_winamp = FindWindow("Winamp v2.x", NULL);
}
if (hwnd_winamp == NULL) {
hwnd_winamp = FindWindow("Winamp v3.x", NULL);
}
}
jboolean runWinamp(unsigned char* pathWinamp) {
/* STARTUPINFO si;
PROCESS_INFORMATION pi;*/
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if(!CreateProcess(pathWinamp,
NULL,
0,
0,
FALSE,
CREATE_NEW_CONSOLE,
0,
0,
&si,
&pi))
{
return FALSE;
}
DWORD dwResult = WaitForInputIdle(pi.hProcess,INFINITE);
if (dwResult != 0) return FALSE;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
int getListPos() {
initWinampHandle();
if (hwnd_winamp != NULL) {
return SendMessage(hwnd_winamp,WM_USER,WA_NOTHING,WA_GETLISTPOS);
}
return -1;
}
void getPluginMessage(int param, int sendMessage)
{
LPCVOID message = (LPCVOID)SendMessageW(hwnd_winamp, WM_USER, param, sendMessage);
ZeroMemory( &pi, sizeof(pi));
GetWindowThreadProcessId(hwnd_winamp, &pi.dwThreadId);
pi.hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pi.dwThreadId);
ReadProcessMemory(pi.hProcess, message, messageReturn,2056,temp);
free(temp);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_run
(JNIEnv *env, jobject obj) {
initWinampHandle();
if ( hwnd_winamp == NULL ) {
unsigned char path[MAX_PATH]="";
DWORD size = MAX_PATH;
HKEY key;
DWORD tipo;
if (!RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Clients\\Media\\Winamp\\shell\\open\\command",&key)==ERROR_SUCCESS)
{
printf("0");
return FALSE;
}
if (!(RegQueryValueEx(key,"",NULL,&tipo,path,&size))==ERROR_SUCCESS)
{
RegCloseKey(key);
return FALSE;
}
if (!runWinamp(path))
{
RegCloseKey(key);
return FALSE;
}
return TRUE;
}
int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
return TRUE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_exit
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_CLOSE, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_play
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_PLAY, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_stop
(JNIEnv *env, jobject obj)
{
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_STOP, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_resume
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_PAUSE, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_pause
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_PAUSE, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_previousTrack
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_PREVTRACK, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_nextTrack
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_NEXTTRACK, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_fwd5Secs
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_FWD5SECS, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_rew5Secs
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_REW5SECS, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_increaseVolume
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_VOLUMEUP, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_decreaseVolume
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_VOLUMEDOWN, WA_NOTHING);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_increaseVolumePercent
(JNIEnv *env, jobject obj, jint percent) {
initWinampHandle();
int i = 0;
if (hwnd_winamp != NULL) {
for(i=0;i<percent;i++) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_VOLUMEUP, WA_NOTHING);
}
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_decreaseVolumePercent
(JNIEnv *env, jobject obj, jint percent) {
initWinampHandle();
int i = 0;
if (hwnd_winamp != NULL) {
for(i=0;i<percent;i++) {
SendMessageA(hwnd_winamp, WM_COMMAND, WA_VOLUMEDOWN, WA_NOTHING);
}
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setVolume
(JNIEnv *env, jobject obj, jint pos) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, pos, WA_SETVOLUME);
return TRUE;
}
return FALSE;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getVolume
(JNIEnv *env, jobject obj, jint pos) {
jint curVolume = -1;
initWinampHandle();
if (hwnd_winamp != NULL) {
curVolume = (jint)SendMessageA(hwnd_winamp, WM_USER, -666, WA_SETVOLUME);
}
return curVolume;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_restart
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_RESTART);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setPlaylistPosition
(JNIEnv *env, jobject obj, jint pos) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, pos, WA_SETPLAYLISTPOS);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_clearPlayList
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_CLEARPLAYLIST);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_refreshPlayListCache
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_REFRESHPLCACHE);
return TRUE;
}
return FALSE;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getPlayListLength
(JNIEnv *env, jobject obj) {
jint length = -1;
initWinampHandle();
if (hwnd_winamp != NULL) {
length = (jint)SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_PLAYLISTLEN);
}
return length;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_writePlayListToFile
(JNIEnv *env, jobject obj) {
jint length = -1;
initWinampHandle();
if (hwnd_winamp != NULL) {
length = SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_WRITEPLAYLIST);
}
return length;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_isShuffleStatusOn
(JNIEnv *env, jobject obj) {
jint status = 0;
initWinampHandle();
if (hwnd_winamp != NULL) {
status = (jint)SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_GETSHUFFLESTATUS);
} else
return -1;
return status>0?1:0;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_isRepeatStatusOn
(JNIEnv *env, jobject obj) {
jint status = 0;
initWinampHandle();
if (hwnd_winamp != NULL) {
status = (jint)SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_GETREPEATSTATUS);
} else
return -1;
return status>0?1:0;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setRepeatStatusOn
(JNIEnv *env, jobject obj, jboolean status) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, status, WA_SETREPEATSTATUS);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setShuffleStatusOn
(JNIEnv *env, jobject obj, jboolean status) {
initWinampHandle();
if (hwnd_winamp != NULL) {
SendMessageA(hwnd_winamp, WM_USER, status, WA_SETSHUFFLESTATUS);
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_appendToPlayList
(JNIEnv *env, jobject obj, jstring mp3filename) {
initWinampHandle();
jboolean iscopy;
if (hwnd_winamp != NULL) {
wMessageReturn = (wchar_t*)(*env)->GetStringChars(env, mp3filename, &iscopy);
int length = wcslen(wMessageReturn);
COPYDATASTRUCT cds;
cds.dwData = IPC_PLAYFILEW;
cds.lpData = (void*)wMessageReturn;
cds.cbData = length * 2 + 2 ; // it sums white space
SendMessageW(hwnd_winamp, WM_COPYDATA, WA_NOTHING, (LPARAM)&cds);
return TRUE;
}
return FALSE;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getStatus
(JNIEnv *env, jobject obj) {
jint status = -1;
initWinampHandle();
if (hwnd_winamp != NULL) {
status = SendMessageA(hwnd_winamp, WM_USER, WA_NOTHING, WA_GETSTATUS);
}
return status;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getListPos
(JNIEnv *env, jobject obj) {
return getListPos();
}
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getTitle
(JNIEnv *env, jobject obj) {
initWinampHandle();
if (hwnd_winamp != NULL) {
char title[500] = "";
GetWindowText(hwnd_winamp,title,500);
return (*env)->NewStringUTF(env,title);
}
return NULL;
}
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getTime
(JNIEnv *env, jobject obj, jint mode) {
initWinampHandle();
if (hwnd_winamp != NULL) {
return SendMessage(hwnd_winamp,WM_USER,mode,IPC_GETOUTPUTTIME);
}
return -2;
}
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getFileNameInList
(JNIEnv *env, jobject obj, jint index)
{
initWinampHandle();
if (hwnd_winamp != NULL) {
getPluginMessage(index, WA_FILENAMEINLIST);
char* filePath = messageReturn;
jstring strReturn = (*env)->NewStringUTF(env,filePath);
return strReturn;
}
return NULL;
}
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getFileNamePlaying
(JNIEnv *env, jobject obj)
{
initWinampHandle();
if (hwnd_winamp != NULL) {
getPluginMessage(WA_NOTHING, IPC_GET_PLAYING_FILENAME);
wchar_t* fileName = (wchar_t*)messageReturn;
int length = wcslen(fileName);
jstring strReturn = (*env)->NewString(env,fileName,length);
return strReturn;
}
return NULL;
}

View File

@@ -0,0 +1,285 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class WinampController */
#ifndef _Included_WinampController
#define _Included_WinampController
#ifdef __cplusplus
extern "C" {
#endif
void initWinampHandle();
jboolean runWinamp(unsigned char* pathWinamp);
int getListPos();
void getPluginMessage(int param, int sendMessage);
/*
* Class: WinampController
* Method: run
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_run
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: exit
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_exit
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: play
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_play
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: stop
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_stop
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: resume
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_resume
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: pause
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_pause
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: previousTrack
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_previousTrack
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: nextTrack
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_nextTrack
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: fwd5Secs
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_fwd5Secs
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: fwd5Secs
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_rew5Secs
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: increaseVolume
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_increaseVolume
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: decreaseVolume
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_decreaseVolume
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: increaseVolumePercent
* Signature: (I)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_increaseVolumePercent
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: decreaseVolumePercent
* Signature: (I)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_decreaseVolumePercent
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: setVolume
* Signature: (I)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setVolume
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: setVolume
* Signature: (I)V
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getVolume
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: restart
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_restart
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: setPlaylistPosition
* Signature: (I)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setPlaylistPosition
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: clearPlayList
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_clearPlayList
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: refreshPlayListCache
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_refreshPlayListCache
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: getPlayListLength
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getPlayListLength
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: writePlayListToFile
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_writePlayListToFile
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: isShuffleStatusOn
* Signature: ()Z
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_isShuffleStatusOn
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: isRepeatStatusOn
* Signature: ()Z
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_isRepeatStatusOn
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: setRepeatStatusOn
* Signature: (Z)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setRepeatStatusOn
(JNIEnv *, jclass, jboolean);
/*
* Class: WinampController
* Method: setShuffleStatusOn
* Signature: (Z)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_setShuffleStatusOn
(JNIEnv *, jclass, jboolean);
/*
* Class: WinampController
* Method: appendToPlayList
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT jboolean JNICALL Java_com_qotsa_jni_controller_JNIWinamp_appendToPlayList
(JNIEnv *, jclass, jstring);
/*
* Class: WinampController
* Method: getStatus
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getStatus
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: getListPos
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getListPos
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: getTitle
* Signature: ()I
*/
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getTitle
(JNIEnv *, jclass);
/*
* Class: WinampController
* Method: getTime
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getTime
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: getFileNameInList
* Signature: ()I
*/
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getFileNameInList
(JNIEnv *, jclass, jint);
/*
* Class: WinampController
* Method: getFileNamePlaying
* Signature: ()I
*/
JNIEXPORT jstring JNICALL Java_com_qotsa_jni_controller_JNIWinamp_getFileNamePlaying
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

1
vendor/JavaWinampApi/1.1/cpp/cpy.bat vendored Normal file
View File

@@ -0,0 +1 @@
copy /y wpcom.dll c:\winnt\system32\

View File

@@ -0,0 +1,58 @@
; dlltool --base-file C:\DOCUME~1\FRANCI~1\CONFIG~1\Temp/cca03628.base --output-exp wpcom.exp --dllname wpcom.dll --output-def libwpcom.def --no-export-all-symbols --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def C:\DOCUME~1\FRANCI~1\CONFIG~1\Temp/cca03628.def --output-lib libwpcom.a
EXPORTS
Java_controller_JNIWinampController_appendToPlayList = Java_controller_JNIWinampController_appendToPlayList@12 @ 1
Java_controller_JNIWinampController_appendToPlayList@12 @ 2
Java_controller_JNIWinampController_clearPlayList = Java_controller_JNIWinampController_clearPlayList@8 @ 3
Java_controller_JNIWinampController_clearPlayList@8 @ 4
Java_controller_JNIWinampController_clearPlayListCache = Java_controller_JNIWinampController_clearPlayListCache@8 @ 5
Java_controller_JNIWinampController_clearPlayListCache@8 @ 6
Java_controller_JNIWinampController_decreaseVolume = Java_controller_JNIWinampController_decreaseVolume@8 @ 7
Java_controller_JNIWinampController_decreaseVolume@8 @ 8
Java_controller_JNIWinampController_decreaseVolumePercent = Java_controller_JNIWinampController_decreaseVolumePercent@12 @ 9
Java_controller_JNIWinampController_decreaseVolumePercent@12 @ 10
Java_controller_JNIWinampController_exit = Java_controller_JNIWinampController_exit@8 @ 11
Java_controller_JNIWinampController_exit@8 @ 12
Java_controller_JNIWinampController_getListPos = Java_controller_JNIWinampController_getListPos@8 @ 13
Java_controller_JNIWinampController_getListPos@8 @ 14
Java_controller_JNIWinampController_getPlayListLength = Java_controller_JNIWinampController_getPlayListLength@8 @ 15
Java_controller_JNIWinampController_getPlayListLength@8 @ 16
Java_controller_JNIWinampController_getSeconds = Java_controller_JNIWinampController_getSeconds@8 @ 17
Java_controller_JNIWinampController_getSeconds@8 @ 18
Java_controller_JNIWinampController_getStatus = Java_controller_JNIWinampController_getStatus@8 @ 19
Java_controller_JNIWinampController_getStatus@8 @ 20
Java_controller_JNIWinampController_getTitle = Java_controller_JNIWinampController_getTitle@8 @ 21
Java_controller_JNIWinampController_getTitle@8 @ 22
Java_controller_JNIWinampController_increaseVolume = Java_controller_JNIWinampController_increaseVolume@8 @ 23
Java_controller_JNIWinampController_increaseVolume@8 @ 24
Java_controller_JNIWinampController_increaseVolumePercent = Java_controller_JNIWinampController_increaseVolumePercent@12 @ 25
Java_controller_JNIWinampController_increaseVolumePercent@12 @ 26
Java_controller_JNIWinampController_isRepeatStatusOn = Java_controller_JNIWinampController_isRepeatStatusOn@8 @ 27
Java_controller_JNIWinampController_isRepeatStatusOn@8 @ 28
Java_controller_JNIWinampController_isShuffleStatusOn = Java_controller_JNIWinampController_isShuffleStatusOn@8 @ 29
Java_controller_JNIWinampController_isShuffleStatusOn@8 @ 30
Java_controller_JNIWinampController_nextTrack = Java_controller_JNIWinampController_nextTrack@8 @ 31
Java_controller_JNIWinampController_nextTrack@8 @ 32
Java_controller_JNIWinampController_pause = Java_controller_JNIWinampController_pause@8 @ 33
Java_controller_JNIWinampController_pause@8 @ 34
Java_controller_JNIWinampController_play = Java_controller_JNIWinampController_play@8 @ 35
Java_controller_JNIWinampController_play@8 @ 36
Java_controller_JNIWinampController_previousTrack = Java_controller_JNIWinampController_previousTrack@8 @ 37
Java_controller_JNIWinampController_previousTrack@8 @ 38
Java_controller_JNIWinampController_restart = Java_controller_JNIWinampController_restart@8 @ 39
Java_controller_JNIWinampController_restart@8 @ 40
Java_controller_JNIWinampController_resume = Java_controller_JNIWinampController_resume@8 @ 41
Java_controller_JNIWinampController_resume@8 @ 42
Java_controller_JNIWinampController_run = Java_controller_JNIWinampController_run@8 @ 43
Java_controller_JNIWinampController_run@8 @ 44
Java_controller_JNIWinampController_setPlaylistPosition = Java_controller_JNIWinampController_setPlaylistPosition@12 @ 45
Java_controller_JNIWinampController_setPlaylistPosition@12 @ 46
Java_controller_JNIWinampController_setRepeatStatusOn = Java_controller_JNIWinampController_setRepeatStatusOn@12 @ 47
Java_controller_JNIWinampController_setRepeatStatusOn@12 @ 48
Java_controller_JNIWinampController_setShuffleStatusOn = Java_controller_JNIWinampController_setShuffleStatusOn@12 @ 49
Java_controller_JNIWinampController_setShuffleStatusOn@12 @ 50
Java_controller_JNIWinampController_setVolume = Java_controller_JNIWinampController_setVolume@12 @ 51
Java_controller_JNIWinampController_setVolume@12 @ 52
Java_controller_JNIWinampController_stop = Java_controller_JNIWinampController_stop@8 @ 53
Java_controller_JNIWinampController_stop@8 @ 54
Java_controller_JNIWinampController_writePlayListToFile = Java_controller_JNIWinampController_writePlayListToFile@8 @ 55
Java_controller_JNIWinampController_writePlayListToFile@8 @ 56

1620
vendor/JavaWinampApi/1.1/cpp/wa_ipc.h vendored Normal file

File diff suppressed because it is too large Load Diff

69
vendor/JavaWinampApi/1.1/cpp/wpcom.dev vendored Normal file
View File

@@ -0,0 +1,69 @@
[Project]
FileName=wpcom.dev
Name=wpcom
UnitCount=2
Type=3
Ver=1
ObjFiles=
Includes="E:\Program Files\Java\jdk1.6.0_11\include";"E:\Program Files\Java\jdk1.6.0_11\include\win32"
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=-DBUILDING_DLL=1_@@_
CppCompiler=-DBUILDING_DLL=1_@@_
Linker=--no-export-all-symbols --add-stdcall-alias_@@_
IsCpp=0
Icon=
ExeOutput=..\..\..\JavaWinampAPI
ObjectOutput=
OverrideOutput=1
OverrideOutputName=wpcom.dll
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000
[Unit1]
FileName=WinampController.c
CompileCpp=0
Folder=wacon
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c WinampController.c -o WinampController.o $(CFLAGS)
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
[Unit2]
FileName=WinampController.h
CompileCpp=0
Folder=wacon
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@@ -0,0 +1,17 @@
[Editor_0]
CursorCol=32
CursorRow=359
TopLine=338
LeftChar=1
Open=1
Top=1
[Editors]
Focused=0
Order=1,0
[Editor_1]
Open=1
Top=0
CursorCol=73
CursorRow=143
TopLine=127
LeftChar=1

View File

@@ -0,0 +1,40 @@
/*
* InvalidHandle.java
*
* Created on 9 de Outubro de 2007, 14:18
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.qotsa.exception;
/**
* Exception to throw when Winamp Handle Fails.
*
* @author Francisco
*/
public class InvalidHandle extends Exception{
private static final String defaultMessage = "Invalid Handle. Please Verify if Winamp is running.";
/**
* Creates a new instance of InvalidHandle
* @param message Message to print in the stack.
*/
public InvalidHandle(String message) {
super(message);
}
/**
* Creates a new instance of InvalidHandle with the default message
*/
public InvalidHandle() {
super(defaultMessage);
}
}

View File

@@ -0,0 +1,40 @@
/*
* InvalidParameter.java
*
* Created on 11 de Outubro de 2007, 10:53
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.qotsa.exception;
/**
* Exception to throw when any parameter is invalid.
*
* @author Francisco
*/
public class InvalidParameter extends Exception {
private static final String defaultMessage = "Invalid Parameter";
/**
* Creates a new instance of NegativeValueException
* @param message Message to print in the stack.
*/
public InvalidParameter(String message) {
super(message);
}
/**
* Creates a new instance of NegativeValueException with the default message
*/
public InvalidParameter() {
super(defaultMessage);
}
}

View File

@@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!--
@(#)package.html 1.60 98/01/27
-->
</head>
<body bgcolor="white">
Package containing the Exception Class used in the WinampController Class.
<h2>Package Specification</h2>
<!-- Put @see and @since tags down here. -->
</body>
</html>

View File

@@ -0,0 +1,227 @@
/*
* JNIWinamp.java
*
* Created on 23 de Abril de 2007, 20:41
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package com.qotsa.jni.controller;
import java.io.IOException;
/**
*
* @author Francisco Guimar<61>es
*/
final class JNIWinamp {
static {
System.loadLibrary("wpcom");
}
/**
* Verify if Winamp is started
* and if not started, starts it
* @return True - if successful run Winamp
* False - if not successful run Winamp
*/
protected static native boolean run() throws UnsatisfiedLinkError;
/*
* Exit Winamp
* @return True - if successful exit
* False - if not successful exit
*/
protected static native boolean exit() throws UnsatisfiedLinkError;
/**
* Play Winamp.
*
*/
protected static native boolean play() throws UnsatisfiedLinkError;
/**
* Stop Winamp.
*
*/
protected static native boolean stop() throws UnsatisfiedLinkError;
/**
* Resume Winamp.
*
*/
protected static native boolean resume() throws UnsatisfiedLinkError;
/**
* Pause Winamp.
*
*/
protected static native boolean pause() throws UnsatisfiedLinkError;
/**
* Go to Previous Track.
*
*/
protected static native boolean previousTrack() throws UnsatisfiedLinkError;
/**
* Go to Next Track.
*
*/
protected static native boolean nextTrack() throws UnsatisfiedLinkError;
/**
* Fowards 5 seconds on the current song.
*
*/
protected static native boolean fwd5Secs() throws UnsatisfiedLinkError;
/**
* Rewinds 5 seconds on the current song.
*
*/
protected static native boolean rew5Secs() throws UnsatisfiedLinkError;
/**
* Increase Volume.
*
*/
protected static native boolean increaseVolume() throws UnsatisfiedLinkError;
/**
* Decrease Volume.
*
*/
protected static native boolean decreaseVolume() throws UnsatisfiedLinkError;
/**
* Increase Volume.
* @param percent Percent to Increase.
*/
protected static native boolean increaseVolumePercent(int percent) throws UnsatisfiedLinkError;
/**
* Decrease Volume.
* @param percent Percent to Decrease.
*/
protected static native boolean decreaseVolumePercent(int percent) throws UnsatisfiedLinkError;
/**
* Adjust Volume
* @param pos Position to Set Volume between 0 and 99.
*/
protected static native boolean setVolume(int pos) throws UnsatisfiedLinkError;
/**
* Get Volume.
* @return volume.
*/
protected static native int getVolume() throws UnsatisfiedLinkError;
/**
* Go to a Specified Position in the List.
* @param pos Position.
*/
protected static native boolean setPlaylistPosition(int pos) throws UnsatisfiedLinkError;
/**
* Clear List.
*
*/
protected static native boolean clearPlayList() throws UnsatisfiedLinkError;
/**
* Refresh List<73>s Cache.
*
*/
protected static native boolean refreshPlayListCache() throws UnsatisfiedLinkError;
/**
* Return the PlayListLength.
* @return List Length.
*/
protected static native int getPlayListLength() throws UnsatisfiedLinkError;
/**
* Write a Playlist in <winampdir>\\Winamp.m3u.
* @return List Position.
*/
protected static native int writePlayListToFile() throws UnsatisfiedLinkError;
/**
* Verify if Shuffle is On.
* @return True - On throws UnsatisfiedLinkError; False - Off.
*/
protected static native int isShuffleStatusOn() throws UnsatisfiedLinkError;
/**
* Verify if Repeat is On.
* @return True - On throws UnsatisfiedLinkError; False - Off.
*/
protected static native int isRepeatStatusOn() throws UnsatisfiedLinkError;
/**
* Turn on Repeat.
* @param True - Turn on Repeat throws UnsatisfiedLinkError; False - Turn off Repeat.
*/
protected static native boolean setRepeatStatusOn(boolean mode) throws UnsatisfiedLinkError;
/**
* Turn on Shuffle.
* @param True - Turn on Shuffle throws UnsatisfiedLinkError; False - Turn off Shuffle.
*/
protected static native boolean setShuffleStatusOn(boolean mode) throws UnsatisfiedLinkError;
/**
* Append a File in the List
* @param filename FileName to Append.
*/
protected static native boolean appendToPlayList(String filename) throws UnsatisfiedLinkError;
/**
* Get Winamp Status.
* @return STOPPED - Stop
* PLAYING - play
* PAUSED - Paused
*/
protected static native int getStatus() throws UnsatisfiedLinkError;
/**
* Get Current List Pos.
* @return Current List Position.
*/
protected static native int getListPos() throws UnsatisfiedLinkError;
/**
* Get Current Track Title
* @return Current Track Title
*/
protected static native String getTitle() throws UnsatisfiedLinkError;
/**
* Get Track FileName in List<73>s index.
* @param index Track Index in the Current PlayList
* @return Current Track FileName
*/
protected static native String getFileNameInList(int index) throws UnsatisfiedLinkError;
/**
* Get Song Time
* @param mode CURRENTTIME - Currently Time in Milliseconds
* TIMELENGHT - Song Time Length in seconds
* @return Song Time in Seconds
*/
protected static native int getTime(int mode) throws UnsatisfiedLinkError;
/**
* Get File Name Playing In Winamp.
*
* @return Current File Name.
*/
protected static native String getFileNamePlaying() throws UnsatisfiedLinkError;
}

View File

@@ -0,0 +1,592 @@
/*
* WinampController.java
*
* Created on 9 de Outubro de 2007, 14:06
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
/**
* Package containing the Controller Class to communicate with Winamp.
*
* @author Francisco Guimar<61>es
*/
package com.qotsa.jni.controller;
import com.qotsa.exception.InvalidHandle;
import com.qotsa.exception.InvalidParameter;
import java.io.File;
/**
* This class is a wrapper to call JNI functions
* to send Message to Winamp Window.
*
* @author Francisco Guimar<61>es
*
*
*/
public class WinampController {
/**
* Constant used as return in getTime()
* Value = -1
*/
public static final int ISNOTPLAYING = -1;
/**
* Constant used as parameter in getTime() method
* Value = 0
*/
public static final int CURRENTTIME = 0;
/**
* Constant used as parameter in getTime() method
* Value = 1
*/
public static final int TIMELENGTH = 1;
/**
* Constant used as return in getStatus() method
* Value = 0
*/
public static final int STOPPED = 0;
/**
* Constant used as return in getStatus() method
* Value = 1
*/
public static final int PLAYING = 1;
/**
* Constant used as return in getStatus() method
* Value = 3
*/
public static final int PAUSED = 3;
/**
* Verify if Winamp is started
* and if not started, starts it.
*
* @throws java.lang.Exception When the key HKEY_LOCAL_MACHINE\Software\Clients\Media\Winamp\shell\open\command
* is not found in the register. This key is used to find Winamp Directory installation to execute it.
*/
public static void run() throws Exception{
if (!JNIWinamp.run())
throw new Exception("Unable to run Winamp. Verify if it is properly installed");
}
/**
* Exit Winamp.
*
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void exit() throws InvalidHandle {
if (!JNIWinamp.exit())
throw new InvalidHandle();
}
/**
* Play current file in Winamp.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void play() throws InvalidHandle {
if (!JNIWinamp.play())
throw new InvalidHandle();
}
/**
* Stop current file in Winamp.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void stop() throws InvalidHandle {
if (!JNIWinamp.stop())
throw new InvalidHandle();
}
/**
* Resume current file in Winamp.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void resume() throws InvalidHandle {
if (!JNIWinamp.resume())
throw new InvalidHandle();
}
/**
* Pause Winamp.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void pause() throws InvalidHandle {
if (!JNIWinamp.pause())
throw new InvalidHandle();
}
/**
*
* Go to Previous Track in the play list.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void previousTrack() throws InvalidHandle {
if (!JNIWinamp.previousTrack())
throw new InvalidHandle();
}
/**
* Go to Next Track in the play list.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void nextTrack() throws InvalidHandle {
if (!JNIWinamp.nextTrack())
throw new InvalidHandle();
}
/**
* Fowards 5 seconds on the current song.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void fwd5Secs() throws InvalidHandle {
if (!JNIWinamp.fwd5Secs())
throw new InvalidHandle();
}
/**
* Rewinds 5 seconds on the current song.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void rew5Secs() throws InvalidHandle {
if (!JNIWinamp.rew5Secs())
throw new InvalidHandle();
}
/**
* Increase Volume a little bit.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void increaseVolume() throws InvalidHandle {
if (!JNIWinamp.increaseVolume())
throw new InvalidHandle();
}
/**
* Decrease Volume a little bit.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void decreaseVolume() throws InvalidHandle {
if (!JNIWinamp.decreaseVolume())
throw new InvalidHandle();
}
/**
* Increase Volume.
*
* @param percent Percent to Increase Volume.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If percent not between 0 and 100
*/
public static void increaseVolumePercent (int percent) throws InvalidHandle, InvalidParameter {
if ( (percent < 0) || (percent > 100) )
throw new InvalidParameter("percent<EFBFBD>s value must be between 0 and 100");
if (!JNIWinamp.increaseVolumePercent(percent))
throw new InvalidHandle();
}
/**
* Decrease Volume.
*
* @param percent Percent to Decrease Volume.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If percent not between 0 and 100
*/
public static void decreaseVolumePercent(int percent) throws InvalidHandle, InvalidParameter {
if ( (percent < 0) || (percent > 100) )
throw new InvalidParameter("percent<EFBFBD>s value must be between 0 and 100");
if (!JNIWinamp.decreaseVolumePercent(percent))
throw new InvalidHandle();
}
/**
* Adjust Volume.
* Note that the pos must be between 0(0%) and 255 (100%).
*
* @param pos Position to Set Volume.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If pos not between 0 and 255
*/
public static void setVolume(int pos) throws InvalidHandle, InvalidParameter {
if ( (pos < 0) || (pos > 255) )
throw new InvalidParameter("pos value must be between 0 and 255");
if (!JNIWinamp.setVolume(pos))
throw new InvalidHandle();
}
/**
* Get Volume.
* @return The volume which is a number between 0 (0%) and 255(100%)
* @throws com.qotsa.exception.InvalidHandle
*/
public static int getVolume() throws InvalidHandle {
int volume = JNIWinamp.getVolume();
if (volume == -1)
throw new InvalidHandle();
return volume;
}
/**
* Get Volume Percent.
* @return Volume percent.
* @throws com.qotsa.exception.InvalidHandle
*/
public static int getVolumePercent() throws InvalidHandle {
int volume = getVolume();
int percent = (volume * 100) / 255;
return percent;
}
/**
* Restarts Winamp.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws java.lang.Exception When failed to restart Winamp.
*/
public static void restart() throws InvalidHandle, Exception {
exit();
run();
}
/**
* Go to a Specified Position in the List. This method doesn<73>t play.
* Just set list position. If you wanna play call play() after set position.
* Parameter pos is Zero-based index.
* @param pos Position.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If pos is negative or greater than List Length.
*/
public static void setPlaylistPosition(int pos) throws InvalidHandle, InvalidParameter {
int listLength = getPlayListLength();
if ( (pos < 0) || ( (pos + 1) > listLength) )
throw new InvalidParameter("Position is invalid in the list.");
if (!JNIWinamp.setPlaylistPosition(pos))
throw new InvalidHandle();
}
/**
* Clear Winamp's internal playlist.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void clearPlayList() throws InvalidHandle {
if (!JNIWinamp.clearPlayList())
throw new InvalidHandle();
}
/**
* Flush the playlist cache buffer.
* Call this if you want it to go refetch titles for tracks in the list.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void refreshPlayListCache() throws InvalidHandle{
if (!JNIWinamp.refreshPlayListCache())
throw new InvalidHandle();
}
/**
* Return the PlayListLength.
*
* @return List Length.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static int getPlayListLength() throws InvalidHandle {
int length = JNIWinamp.getPlayListLength();
if (length == -1)
throw new InvalidHandle();
return length;
}
/**
* Write a Playlist in winampDirInstallation\\Winamp.m3u.
* This is default Winamp IPC Default. If you wanna change this,
* just rename the file you<6F>ve created.
*
* @return Current List Position.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static int writePlayListToFile() throws InvalidHandle {
int playListPos = JNIWinamp.writePlayListToFile();
if (playListPos == -1)
throw new InvalidHandle();
return playListPos;
}
/**
* Verify if Shuffle is On.
*
* @return True - On ; False - Off.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static boolean isShuffleStatusOn() throws InvalidHandle {
int status = JNIWinamp.isShuffleStatusOn();
if (status == -1)
throw new InvalidHandle();
return (status == 1 ? true : false);
}
/**
* Verify if Repeat is On.
*
* @return True - On ; False - Off.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static boolean isRepeatStatusOn() throws InvalidHandle {
int status = JNIWinamp.isRepeatStatusOn();
if (status == -1)
throw new InvalidHandle();
return (status == 1 ? true : false);
}
/**
* Turn on Repeat.
*
* @param mode True - Turn on Repeat ; False - Turn off Repeat.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void setRepeatStatusOn(boolean mode) throws InvalidHandle {
if (!JNIWinamp.setRepeatStatusOn(mode))
throw new InvalidHandle();
}
/**
* Turn on Shuffle.
*
* @param mode True - Turn on Shuffle ; False - Turn off Shuffle.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static void setShuffleStatusOn(boolean mode) throws InvalidHandle {
if (!JNIWinamp.setShuffleStatusOn(mode))
throw new InvalidHandle();
}
/**
* Append a File into the List.
*
* @param filename FileName to Append in the list.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If the filename is an invalid path.
*/
public static void appendToPlayList(String filename) throws InvalidHandle, InvalidParameter {
File file = new File(filename);
if (!file.exists())
throw new InvalidParameter("File doesn<73>t exists.");
if (!JNIWinamp.appendToPlayList(filename))
throw new InvalidHandle();
}
/**
* Get Winamp Status.
*
* @return STOPPED - Stop
* PLAYING - play
* PAUSED - Paused
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static int getStatus() throws InvalidHandle {
int status = JNIWinamp.getStatus();
if (status == -1)
throw new InvalidHandle();
return status;
}
/**
* Get Current List Pos.
*
* @return Current List Position.
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static int getListPos() throws InvalidHandle {
int pos = JNIWinamp.getListPos();
if (pos == -1)
throw new InvalidHandle();
return pos;
}
/**
* Get Current Track Title.
*
* @return Current Track Title
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
*/
public static String getTitle() throws InvalidHandle {
String title = JNIWinamp.getTitle();
if (title == null)
throw new InvalidHandle();
return title;
}
/**
* Get Current Track FileName.
* Parameter pos is Zero-based index.
*
* @return Current Track FileName
* @param pos Track Position in the Current PlayList
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter If pos is negative or greater than List Length
*/
public static String getFileNameInList(int pos) throws InvalidHandle, InvalidParameter {
int listLength = getPlayListLength();
if ( (pos < 0) || (pos > listLength) )
throw new InvalidParameter("Position is invalid in the list.");
String filename = JNIWinamp.getFileNameInList(pos);
if (filename == null)
throw new InvalidHandle();
return filename;
}
/**
* Get Song Time.
*
* @return Time Song (depends on Param mode) or
* ISNOTPLAYING if there is no info about time because it not starts to play.
* @param mode CURRENTTIME - Currently Time in Milliseconds
* TIMELENGHT - Song Time Length in seconds
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter if parameter is not CURRENTTIME or TIMELENGTH.
*/
public static int getTime(int mode) throws InvalidHandle, InvalidParameter {
if (mode != CURRENTTIME && mode != TIMELENGTH)
throw new InvalidParameter();
int time = JNIWinamp.getTime(mode);
if (time == -2)
throw new InvalidHandle();
return time;
}
/**
* Fowards n Tracks in Play List.
*
* @param n Number of Tracks to Foward
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter if n is negative or Zero.
*/
public static void fwdTracks(int n) throws InvalidParameter, InvalidHandle {
if (n <= 0)
throw new InvalidParameter("Value must be Positive");
int pos = getListPos();
int lengthList = getPlayListLength();
int newPos = pos + n;
if (newPos > lengthList ) {
setPlaylistPosition(lengthList);
play();
}
else {
setPlaylistPosition(newPos);
play();
}
}
/**
* Rewinds n Tracks in Play List.
*
* @param n Number of Tracks to Rewind
* @throws com.qotsa.exception.InvalidHandle When the Winamp Windows is not handle(in most case, it means that winamp is not running)
* @throws com.qotsa.exception.InvalidParameter if n is negative or Zero.
*/
public static void rewTracks(int n) throws InvalidParameter, InvalidHandle {
if (n <= 0)
throw new InvalidParameter("Value must be Positive");
int pos = getListPos();
int lengthList = getPlayListLength();
int newPos = pos - n;
if (newPos < 0 ) {
setPlaylistPosition(0);
play();
}
else {
setPlaylistPosition(newPos);
play();
}
}
/**
* Get File Name Playing In Winamp.
*
* @return Current File Name.
*/
public static String getFileNamePlaying() throws InvalidHandle {
String fileName = JNIWinamp.getFileNamePlaying();
if (fileName == null)
throw new InvalidHandle();
return fileName;
}
}

View File

@@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!--
@(#)package.html 1.60 98/01/27
-->
</head>
<body bgcolor="white">
Package containing the Controller Class to communicate with Winamp.
<h2>Package Specification</h2>
<!-- Put @see and @since tags down here. -->
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,246 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
/**
* <p>A simple logging interface abstracting logging APIs. In order to be
* instantiated successfully by {@link LogFactory}, classes that implement
* this interface must have a constructor that takes a single String
* parameter representing the "name" of this Log.</p>
*
* <p> The six logging levels used by <code>Log</code> are (in order):
* <ol>
* <li>trace (the least serious)</li>
* <li>debug</li>
* <li>info</li>
* <li>warn</li>
* <li>error</li>
* <li>fatal (the most serious)</li>
* </ol>
* The mapping of these log levels to the concepts used by the underlying
* logging system is implementation dependent.
* The implemention should ensure, though, that this ordering behaves
* as expected.</p>
*
* <p>Performance is often a logging concern.
* By examining the appropriate property,
* a component can avoid expensive operations (producing information
* to be logged).</p>
*
* <p> For example,
* <code><pre>
* if (log.isDebugEnabled()) {
* ... do something expensive ...
* log.debug(theResult);
* }
* </pre></code>
* </p>
*
* <p>Configuration of the underlying logging system will generally be done
* external to the Logging APIs, through whatever mechanism is supported by
* that system.</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
* @version $Id: Log.java 424107 2006-07-20 23:15:42Z skitching $
*/
public interface Log {
// ----------------------------------------------------- Logging Properties
/**
* <p> Is debug logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than debug. </p>
*
* @return true if debug is enabled in the underlying logger.
*/
public boolean isDebugEnabled();
/**
* <p> Is error logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than error. </p>
*
* @return true if error is enabled in the underlying logger.
*/
public boolean isErrorEnabled();
/**
* <p> Is fatal logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than fatal. </p>
*
* @return true if fatal is enabled in the underlying logger.
*/
public boolean isFatalEnabled();
/**
* <p> Is info logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than info. </p>
*
* @return true if info is enabled in the underlying logger.
*/
public boolean isInfoEnabled();
/**
* <p> Is trace logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than trace. </p>
*
* @return true if trace is enabled in the underlying logger.
*/
public boolean isTraceEnabled();
/**
* <p> Is warn logging currently enabled? </p>
*
* <p> Call this method to prevent having to perform expensive operations
* (for example, <code>String</code> concatenation)
* when the log level is more than warn. </p>
*
* @return true if warn is enabled in the underlying logger.
*/
public boolean isWarnEnabled();
// -------------------------------------------------------- Logging Methods
/**
* <p> Log a message with trace log level. </p>
*
* @param message log this message
*/
public void trace(Object message);
/**
* <p> Log an error with trace log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void trace(Object message, Throwable t);
/**
* <p> Log a message with debug log level. </p>
*
* @param message log this message
*/
public void debug(Object message);
/**
* <p> Log an error with debug log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void debug(Object message, Throwable t);
/**
* <p> Log a message with info log level. </p>
*
* @param message log this message
*/
public void info(Object message);
/**
* <p> Log an error with info log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void info(Object message, Throwable t);
/**
* <p> Log a message with warn log level. </p>
*
* @param message log this message
*/
public void warn(Object message);
/**
* <p> Log an error with warn log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void warn(Object message, Throwable t);
/**
* <p> Log a message with error log level. </p>
*
* @param message log this message
*/
public void error(Object message);
/**
* <p> Log an error with error log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void error(Object message, Throwable t);
/**
* <p> Log a message with fatal log level. </p>
*
* @param message log this message
*/
public void fatal(Object message);
/**
* <p> Log an error with fatal log level. </p>
*
* @param message log this message
* @param t log this cause
*/
public void fatal(Object message, Throwable t);
}

View File

@@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
/**
* <p>An exception that is thrown only if a suitable <code>LogFactory</code>
* or <code>Log</code> instance cannot be created by the corresponding
* factory methods.</p>
*
* @author Craig R. McClanahan
* @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $
*/
public class LogConfigurationException extends RuntimeException {
/**
* Construct a new exception with <code>null</code> as its detail message.
*/
public LogConfigurationException() {
super();
}
/**
* Construct a new exception with the specified detail message.
*
* @param message The detail message
*/
public LogConfigurationException(String message) {
super(message);
}
/**
* Construct a new exception with the specified cause and a derived
* detail message.
*
* @param cause The underlying cause
*/
public LogConfigurationException(Throwable cause) {
this((cause == null) ? null : cause.toString(), cause);
}
/**
* Construct a new exception with the specified detail message and cause.
*
* @param message The detail message
* @param cause The underlying cause
*/
public LogConfigurationException(String message, Throwable cause) {
super(message + " (Caused by " + cause + ")");
this.cause = cause; // Two-argument version requires JDK 1.4 or later
}
/**
* The underlying cause of this exception.
*/
protected Throwable cause = null;
/**
* Return the underlying cause of this exception (if any).
*/
public Throwable getCause() {
return (this.cause);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging;
import java.lang.reflect.Constructor;
import java.util.Hashtable;
import org.apache.commons.logging.impl.NoOpLog;
/**
* <p>Factory for creating {@link Log} instances. Applications should call
* the <code>makeNewLogInstance()</code> method to instantiate new instances
* of the configured {@link Log} implementation class.</p>
*
* <p>By default, calling <code>getInstance()</code> will use the following
* algorithm:</p>
* <ul>
* <li>If Log4J is available, return an instance of
* <code>org.apache.commons.logging.impl.Log4JLogger</code>.</li>
* <li>If JDK 1.4 or later is available, return an instance of
* <code>org.apache.commons.logging.impl.Jdk14Logger</code>.</li>
* <li>Otherwise, return an instance of
* <code>org.apache.commons.logging.impl.NoOpLog</code>.</li>
* </ul>
*
* <p>You can change the default behavior in one of two ways:</p>
* <ul>
* <li>On the startup command line, set the system property
* <code>org.apache.commons.logging.log</code> to the name of the
* <code>org.apache.commons.logging.Log</code> implementation class
* you want to use.</li>
* <li>At runtime, call <code>LogSource.setLogImplementation()</code>.</li>
* </ul>
*
* @deprecated Use {@link LogFactory} instead - The default factory
* implementation performs exactly the same algorithm as this class did
*
* @author Rod Waldhoff
* @version $Id: LogSource.java 424107 2006-07-20 23:15:42Z skitching $
*/
public class LogSource {
// ------------------------------------------------------- Class Attributes
static protected Hashtable logs = new Hashtable();
/** Is log4j available (in the current classpath) */
static protected boolean log4jIsAvailable = false;
/** Is JDK 1.4 logging available */
static protected boolean jdk14IsAvailable = false;
/** Constructor for current log class */
static protected Constructor logImplctor = null;
// ----------------------------------------------------- Class Initializers
static {
// Is Log4J Available?
try {
if (null != Class.forName("org.apache.log4j.Logger")) {
log4jIsAvailable = true;
} else {
log4jIsAvailable = false;
}
} catch (Throwable t) {
log4jIsAvailable = false;
}
// Is JDK 1.4 Logging Available?
try {
if ((null != Class.forName("java.util.logging.Logger")) &&
(null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"))) {
jdk14IsAvailable = true;
} else {
jdk14IsAvailable = false;
}
} catch (Throwable t) {
jdk14IsAvailable = false;
}
// Set the default Log implementation
String name = null;
try {
name = System.getProperty("org.apache.commons.logging.log");
if (name == null) {
name = System.getProperty("org.apache.commons.logging.Log");
}
} catch (Throwable t) {
}
if (name != null) {
try {
setLogImplementation(name);
} catch (Throwable t) {
try {
setLogImplementation
("org.apache.commons.logging.impl.NoOpLog");
} catch (Throwable u) {
;
}
}
} else {
try {
if (log4jIsAvailable) {
setLogImplementation
("org.apache.commons.logging.impl.Log4JLogger");
} else if (jdk14IsAvailable) {
setLogImplementation
("org.apache.commons.logging.impl.Jdk14Logger");
} else {
setLogImplementation
("org.apache.commons.logging.impl.NoOpLog");
}
} catch (Throwable t) {
try {
setLogImplementation
("org.apache.commons.logging.impl.NoOpLog");
} catch (Throwable u) {
;
}
}
}
}
// ------------------------------------------------------------ Constructor
/** Don't allow others to create instances */
private LogSource() {
}
// ---------------------------------------------------------- Class Methods
/**
* Set the log implementation/log implementation factory
* by the name of the class. The given class
* must implement {@link Log}, and provide a constructor that
* takes a single {@link String} argument (containing the name
* of the log).
*/
static public void setLogImplementation(String classname) throws
LinkageError, ExceptionInInitializerError,
NoSuchMethodException, SecurityException,
ClassNotFoundException {
try {
Class logclass = Class.forName(classname);
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
logImplctor = logclass.getConstructor(argtypes);
} catch (Throwable t) {
logImplctor = null;
}
}
/**
* Set the log implementation/log implementation factory
* by class. The given class must implement {@link Log},
* and provide a constructor that takes a single {@link String}
* argument (containing the name of the log).
*/
static public void setLogImplementation(Class logclass) throws
LinkageError, ExceptionInInitializerError,
NoSuchMethodException, SecurityException {
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
logImplctor = logclass.getConstructor(argtypes);
}
/** Get a <code>Log</code> instance by class name */
static public Log getInstance(String name) {
Log log = (Log) (logs.get(name));
if (null == log) {
log = makeNewLogInstance(name);
logs.put(name, log);
}
return log;
}
/** Get a <code>Log</code> instance by class */
static public Log getInstance(Class clazz) {
return getInstance(clazz.getName());
}
/**
* Create a new {@link Log} implementation, based
* on the given <i>name</i>.
* <p>
* The specific {@link Log} implementation returned
* is determined by the value of the
* <tt>org.apache.commons.logging.log</tt> property.
* The value of <tt>org.apache.commons.logging.log</tt> may be set to
* the fully specified name of a class that implements
* the {@link Log} interface. This class must also
* have a public constructor that takes a single
* {@link String} argument (containing the <i>name</i>
* of the {@link Log} to be constructed.
* <p>
* When <tt>org.apache.commons.logging.log</tt> is not set,
* or when no corresponding class can be found,
* this method will return a Log4JLogger
* if the log4j Logger class is
* available in the {@link LogSource}'s classpath, or a
* Jdk14Logger if we are on a JDK 1.4 or later system, or
* NoOpLog if neither of the above conditions is true.
*
* @param name the log name (or category)
*/
static public Log makeNewLogInstance(String name) {
Log log = null;
try {
Object[] args = new Object[1];
args[0] = name;
log = (Log) (logImplctor.newInstance(args));
} catch (Throwable t) {
log = null;
}
if (null == log) {
log = new NoOpLog(name);
}
return log;
}
/**
* Returns a {@link String} array containing the names of
* all logs known to me.
*/
static public String[] getLogNames() {
return (String[]) (logs.keySet().toArray(new String[logs.size()]));
}
}

View File

@@ -0,0 +1,292 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import org.apache.avalon.framework.logger.Logger;
import org.apache.commons.logging.Log;
/**
* <p>Implementation of commons-logging Log interface that delegates all
* logging calls to the Avalon logging abstraction: the Logger interface.
* </p>
* <p>
* There are two ways in which this class can be used:
* </p>
* <ul>
* <li>the instance can be constructed with an Avalon logger
* (by calling {@link #AvalonLogger(Logger)}). In this case, it acts
* as a simple thin wrapping implementation over the logger. This is
* particularly useful when using a property setter.
* </li>
* <li>the {@link #setDefaultLogger} class property can be called which
* sets the ancesteral Avalon logger for this class. Any <code>AvalonLogger</code>
* instances created through the <code>LogFactory</code> mechanisms will output
* to child loggers of this <code>Logger</code>.
* </li>
* </ul>
* <p>
* <strong>Note:</strong> <code>AvalonLogger</code> does not implement Serializable
* because the constructors available for it make this impossible to achieve in all
* circumstances; there is no way to "reconnect" to an underlying Logger object on
* deserialization if one was just passed in to the constructor of the original
* object. This class <i>was</i> marked Serializable in the 1.0.4 release of
* commons-logging, but this never actually worked (a NullPointerException would
* be thrown as soon as the deserialized object was used), so removing this marker
* is not considered to be an incompatible change.
* </p>
* @author <a href="mailto:neeme@apache.org">Neeme Praks</a>
* @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $
*/
public class AvalonLogger implements Log {
/** Ancesteral avalon logger */
private static Logger defaultLogger = null;
/** Avalon logger used to perform log */
private transient Logger logger = null;
/**
* Constructs an <code>AvalonLogger</code> that outputs to the given
* <code>Logger</code> instance.
* @param logger the avalon logger implementation to delegate to
*/
public AvalonLogger(Logger logger) {
this.logger = logger;
}
/**
* Constructs an <code>AvalonLogger</code> that will log to a child
* of the <code>Logger</code> set by calling {@link #setDefaultLogger}.
* @param name the name of the avalon logger implementation to delegate to
*/
public AvalonLogger(String name) {
if (defaultLogger == null)
throw new NullPointerException("default logger has to be specified if this constructor is used!");
this.logger = defaultLogger.getChildLogger(name);
}
/**
* Gets the Avalon logger implementation used to perform logging.
* @return avalon logger implementation
*/
public Logger getLogger() {
return logger;
}
/**
* Sets the ancesteral Avalon logger from which the delegating loggers
* will descend.
* @param logger the default avalon logger,
* in case there is no logger instance supplied in constructor
*/
public static void setDefaultLogger(Logger logger) {
defaultLogger = logger;
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log.
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message));
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.error</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
if (getLogger().isErrorEnabled()) getLogger().error(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.error</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
if (getLogger().isErrorEnabled()) getLogger().error(String.valueOf(message));
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.fatalError</code>.
*
* @param message to log.
* @param t log this cause.
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
if (getLogger().isFatalErrorEnabled()) getLogger().fatalError(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.fatalError</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
if (getLogger().isFatalErrorEnabled()) getLogger().fatalError(String.valueOf(message));
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.info</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
if (getLogger().isInfoEnabled()) getLogger().info(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.info</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
if (getLogger().isInfoEnabled()) getLogger().info(String.valueOf(message));
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.debug</code> enabled?
* @see org.apache.commons.logging.Log#isDebugEnabled()
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.error</code> enabled?
* @see org.apache.commons.logging.Log#isErrorEnabled()
*/
public boolean isErrorEnabled() {
return getLogger().isErrorEnabled();
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.fatalError</code> enabled?
* @see org.apache.commons.logging.Log#isFatalEnabled()
*/
public boolean isFatalEnabled() {
return getLogger().isFatalErrorEnabled();
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.info</code> enabled?
* @see org.apache.commons.logging.Log#isInfoEnabled()
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.debug</code> enabled?
* @see org.apache.commons.logging.Log#isTraceEnabled()
*/
public boolean isTraceEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Is logging to
* <code>org.apache.avalon.framework.logger.Logger.warn</code> enabled?
* @see org.apache.commons.logging.Log#isWarnEnabled()
*/
public boolean isWarnEnabled() {
return getLogger().isWarnEnabled();
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log.
* @param t log this cause.
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.debug</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message));
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.warn</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
if (getLogger().isWarnEnabled()) getLogger().warn(String.valueOf(message), t);
}
/**
* Logs a message with
* <code>org.apache.avalon.framework.logger.Logger.warn</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
if (getLogger().isWarnEnabled()) getLogger().warn(String.valueOf(message));
}
}

View File

@@ -0,0 +1,335 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.LogRecord;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.commons.logging.Log;
/**
* <p>Implementation of the <code>org.apache.commons.logging.Log</code>
* interface that wraps the standard JDK logging mechanisms that are
* available in SourceForge's Lumberjack for JDKs prior to 1.4.</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:vince256@comcast.net">Vince Eagen</a>
* @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $
* @since 1.1
*/
public class Jdk13LumberjackLogger implements Log, Serializable {
// ----------------------------------------------------- Instance Variables
/**
* The underlying Logger implementation we are using.
*/
protected transient Logger logger = null;
protected String name = null;
private String sourceClassName = "unknown";
private String sourceMethodName = "unknown";
private boolean classAndMethodFound = false;
/**
* This member variable simply ensures that any attempt to initialise
* this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
* It must not be private, as an optimising compiler could detect that it
* is not used and optimise it away.
*/
protected static final Level dummyLevel = Level.FINE;
// ----------------------------------------------------------- Constructors
/**
* Construct a named instance of this Logger.
*
* @param name Name of the logger to be constructed
*/
public Jdk13LumberjackLogger(String name) {
this.name = name;
logger = getLogger();
}
// --------------------------------------------------------- Public Methods
private void log( Level level, String msg, Throwable ex ) {
if( getLogger().isLoggable(level) ) {
LogRecord record = new LogRecord(level, msg);
if( !classAndMethodFound ) {
getClassAndMethod();
}
record.setSourceClassName(sourceClassName);
record.setSourceMethodName(sourceMethodName);
if( ex != null ) {
record.setThrown(ex);
}
getLogger().log(record);
}
}
/**
* <p>Gets the class and method by looking at the stack trace for the
* first entry that is not this class.</p>
*/
private void getClassAndMethod() {
try {
Throwable throwable = new Throwable();
throwable.fillInStackTrace();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter( stringWriter );
throwable.printStackTrace( printWriter );
String traceString = stringWriter.getBuffer().toString();
StringTokenizer tokenizer =
new StringTokenizer( traceString, "\n" );
tokenizer.nextToken();
String line = tokenizer.nextToken();
while ( line.indexOf( this.getClass().getName() ) == -1 ) {
line = tokenizer.nextToken();
}
while ( line.indexOf( this.getClass().getName() ) >= 0 ) {
line = tokenizer.nextToken();
}
int start = line.indexOf( "at " ) + 3;
int end = line.indexOf( '(' );
String temp = line.substring( start, end );
int lastPeriod = temp.lastIndexOf( '.' );
sourceClassName = temp.substring( 0, lastPeriod );
sourceMethodName = temp.substring( lastPeriod + 1 );
} catch ( Exception ex ) {
// ignore - leave class and methodname unknown
}
classAndMethodFound = true;
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
log(Level.FINE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable exception) {
log(Level.FINE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return (logger);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
log(Level.INFO, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable exception) {
log(Level.INFO, String.valueOf(message), exception);
}
/**
* Is debug logging currently enabled?
*/
public boolean isDebugEnabled() {
return (getLogger().isLoggable(Level.FINE));
}
/**
* Is error logging currently enabled?
*/
public boolean isErrorEnabled() {
return (getLogger().isLoggable(Level.SEVERE));
}
/**
* Is fatal logging currently enabled?
*/
public boolean isFatalEnabled() {
return (getLogger().isLoggable(Level.SEVERE));
}
/**
* Is info logging currently enabled?
*/
public boolean isInfoEnabled() {
return (getLogger().isLoggable(Level.INFO));
}
/**
* Is trace logging currently enabled?
*/
public boolean isTraceEnabled() {
return (getLogger().isLoggable(Level.FINEST));
}
/**
* Is warn logging currently enabled?
*/
public boolean isWarnEnabled() {
return (getLogger().isLoggable(Level.WARNING));
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
log(Level.FINEST, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable exception) {
log(Level.FINEST, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
log(Level.WARNING, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable exception) {
log(Level.WARNING, String.valueOf(message), exception);
}
}

View File

@@ -0,0 +1,304 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.logging.Log;
/**
* <p>Implementation of the <code>org.apache.commons.logging.Log</code>
* interface that wraps the standard JDK logging mechanisms that were
* introduced in the Merlin release (JDK 1.4).</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $
*/
public class Jdk14Logger implements Log, Serializable {
/**
* This member variable simply ensures that any attempt to initialise
* this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
* It must not be private, as an optimising compiler could detect that it
* is not used and optimise it away.
*/
protected static final Level dummyLevel = Level.FINE;
// ----------------------------------------------------------- Constructors
/**
* Construct a named instance of this Logger.
*
* @param name Name of the logger to be constructed
*/
public Jdk14Logger(String name) {
this.name = name;
logger = getLogger();
}
// ----------------------------------------------------- Instance Variables
/**
* The underlying Logger implementation we are using.
*/
protected transient Logger logger = null;
/**
* The name of the logger we are wrapping.
*/
protected String name = null;
// --------------------------------------------------------- Public Methods
private void log( Level level, String msg, Throwable ex ) {
Logger logger = getLogger();
if (logger.isLoggable(level)) {
// Hack (?) to get the stack trace.
Throwable dummyException=new Throwable();
StackTraceElement locations[]=dummyException.getStackTrace();
// Caller will be the third element
String cname="unknown";
String method="unknown";
if( locations!=null && locations.length >2 ) {
StackTraceElement caller=locations[2];
cname=caller.getClassName();
method=caller.getMethodName();
}
if( ex==null ) {
logger.logp( level, cname, method, msg );
} else {
logger.logp( level, cname, method, msg, ex );
}
}
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
log(Level.FINE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable exception) {
log(Level.FINE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.SEVERE</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable exception) {
log(Level.SEVERE, String.valueOf(message), exception);
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return (logger);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
log(Level.INFO, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.INFO</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable exception) {
log(Level.INFO, String.valueOf(message), exception);
}
/**
* Is debug logging currently enabled?
*/
public boolean isDebugEnabled() {
return (getLogger().isLoggable(Level.FINE));
}
/**
* Is error logging currently enabled?
*/
public boolean isErrorEnabled() {
return (getLogger().isLoggable(Level.SEVERE));
}
/**
* Is fatal logging currently enabled?
*/
public boolean isFatalEnabled() {
return (getLogger().isLoggable(Level.SEVERE));
}
/**
* Is info logging currently enabled?
*/
public boolean isInfoEnabled() {
return (getLogger().isLoggable(Level.INFO));
}
/**
* Is trace logging currently enabled?
*/
public boolean isTraceEnabled() {
return (getLogger().isLoggable(Level.FINEST));
}
/**
* Is warn logging currently enabled?
*/
public boolean isWarnEnabled() {
return (getLogger().isLoggable(Level.WARNING));
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
log(Level.FINEST, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.FINEST</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable exception) {
log(Level.FINEST, String.valueOf(message), exception);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
log(Level.WARNING, String.valueOf(message), null);
}
/**
* Logs a message with <code>java.util.logging.Level.WARNING</code>.
*
* @param message to log
* @param exception log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable exception) {
log(Level.WARNING, String.valueOf(message), exception);
}
}

View File

@@ -0,0 +1,342 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
import org.apache.log4j.Level;
/**
* Implementation of {@link Log} that maps directly to a
* <strong>Logger</strong> for log4J version 1.2.
* <p>
* Initial configuration of the corresponding Logger instances should be done
* in the usual manner, as outlined in the Log4J documentation.
* <p>
* The reason this logger is distinct from the 1.3 logger is that in version 1.2
* of Log4J:
* <ul>
* <li>class Logger takes Priority parameters not Level parameters.
* <li>class Level extends Priority
* </ul>
* Log4J1.3 is expected to change Level so it no longer extends Priority, which is
* a non-binary-compatible change. The class generated by compiling this code against
* log4j 1.2 will therefore not run against log4j 1.3.
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
* @author Robert Burrell Donkin
* @version $Id: Log4JLogger.java 479747 2006-11-27 20:15:01Z dennisl $
*/
public class Log4JLogger implements Log, Serializable {
// ------------------------------------------------------------- Attributes
/** The fully qualified name of the Log4JLogger class. */
private static final String FQCN = Log4JLogger.class.getName();
/** Log to this logger */
private transient Logger logger = null;
/** Logger name */
private String name = null;
private static Priority traceLevel;
// ------------------------------------------------------------
// Static Initializer.
//
// Note that this must come after the static variable declarations
// otherwise initialiser expressions associated with those variables
// will override any settings done here.
//
// Verify that log4j is available, and that it is version 1.2.
// If an ExceptionInInitializerError is generated, then LogFactoryImpl
// will treat that as meaning that the appropriate underlying logging
// library is just not present - if discovery is in progress then
// discovery will continue.
// ------------------------------------------------------------
static {
if (!Priority.class.isAssignableFrom(Level.class)) {
// nope, this is log4j 1.3, so force an ExceptionInInitializerError
throw new InstantiationError("Log4J 1.2 not available");
}
// Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier
// versions do not. If TRACE is not available, then we have to map
// calls to Log.trace(...) onto the DEBUG level.
try {
traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null);
} catch(Exception ex) {
// ok, trace not available
traceLevel = Priority.DEBUG;
}
}
// ------------------------------------------------------------ Constructor
public Log4JLogger() {
}
/**
* Base constructor.
*/
public Log4JLogger(String name) {
this.name = name;
this.logger = getLogger();
}
/**
* For use with a log4j factory.
*/
public Log4JLogger(Logger logger ) {
if (logger == null) {
throw new IllegalArgumentException(
"Warning - null logger in constructor; possible log4j misconfiguration.");
}
this.name = logger.getName();
this.logger=logger;
}
// ---------------------------------------------------------
// Implementation
//
// Note that in the methods below the Priority class is used to define
// levels even though the Level class is supported in 1.2. This is done
// so that at compile time the call definitely resolves to a call to
// a method that takes a Priority rather than one that takes a Level.
//
// The Category class (and hence its subclass Logger) in version 1.2 only
// has methods that take Priority objects. The Category class (and hence
// Logger class) in version 1.3 has methods that take both Priority and
// Level objects. This means that if we use Level here, and compile
// against log4j 1.3 then calls would be bound to the versions of
// methods taking Level objects and then would fail to run against
// version 1.2 of log4j.
// ---------------------------------------------------------
/**
* Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
* When using a log4j version that does not support the <code>TRACE</code>
* level, the message will be logged at the <code>DEBUG</code> level.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
getLogger().log(FQCN, traceLevel, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.TRACE</code>.
* When using a log4j version that does not support the <code>TRACE</code>
* level, the message will be logged at the <code>DEBUG</code> level.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
getLogger().log(FQCN, traceLevel, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
getLogger().log(FQCN, Priority.DEBUG, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
getLogger().log(FQCN, Priority.DEBUG, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
getLogger().log(FQCN, Priority.INFO, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
getLogger().log(FQCN, Priority.INFO, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
getLogger().log(FQCN, Priority.WARN, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
getLogger().log(FQCN, Priority.WARN, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
getLogger().log(FQCN, Priority.ERROR, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
getLogger().log(FQCN, Priority.ERROR, message, t );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
getLogger().log(FQCN, Priority.FATAL, message, null );
}
/**
* Logs a message with <code>org.apache.log4j.Priority.FATAL</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
getLogger().log(FQCN, Priority.FATAL, message, t );
}
/**
* Return the native Logger instance we are using.
*/
public Logger getLogger() {
if (logger == null) {
logger = Logger.getLogger(name);
}
return (this.logger);
}
/**
* Check whether the Log4j Logger used is enabled for <code>DEBUG</code> priority.
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Check whether the Log4j Logger used is enabled for <code>ERROR</code> priority.
*/
public boolean isErrorEnabled() {
return getLogger().isEnabledFor(Priority.ERROR);
}
/**
* Check whether the Log4j Logger used is enabled for <code>FATAL</code> priority.
*/
public boolean isFatalEnabled() {
return getLogger().isEnabledFor(Priority.FATAL);
}
/**
* Check whether the Log4j Logger used is enabled for <code>INFO</code> priority.
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Check whether the Log4j Logger used is enabled for <code>TRACE</code> priority.
* When using a log4j version that does not support the TRACE level, this call
* will report whether <code>DEBUG</code> is enabled or not.
*/
public boolean isTraceEnabled() {
return getLogger().isEnabledFor(traceLevel);
}
/**
* Check whether the Log4j Logger used is enabled for <code>WARN</code> priority.
*/
public boolean isWarnEnabled() {
return getLogger().isEnabledFor(Priority.WARN);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,294 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.log.Logger;
import org.apache.log.Hierarchy;
import org.apache.commons.logging.Log;
/**
* <p>Implementation of <code>org.apache.commons.logging.Log</code>
* that wraps the <a href="http://avalon.apache.org/logkit/">avalon-logkit</a>
* logging system. Configuration of <code>LogKit</code> is left to the user.
* </p>
*
* <p><code>LogKit</code> accepts only <code>String</code> messages.
* Therefore, this implementation converts object messages into strings
* by called their <code>toString()</code> method before logging them.</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Robert Burrell Donkin
* @version $Id: LogKitLogger.java 424107 2006-07-20 23:15:42Z skitching $
*/
public class LogKitLogger implements Log, Serializable {
// ------------------------------------------------------------- Attributes
/** Logging goes to this <code>LogKit</code> logger */
protected transient Logger logger = null;
/** Name of this logger */
protected String name = null;
// ------------------------------------------------------------ Constructor
/**
* Construct <code>LogKitLogger</code> which wraps the <code>LogKit</code>
* logger with given name.
*
* @param name log name
*/
public LogKitLogger(String name) {
this.name = name;
this.logger = getLogger();
}
// --------------------------------------------------------- Public Methods
/**
* <p>Return the underlying Logger we are using.</p>
*/
public Logger getLogger() {
if (logger == null) {
logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name);
}
return (logger);
}
// ----------------------------------------------------- Log Implementation
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public void trace(Object message) {
debug(message);
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public void trace(Object message, Throwable t) {
debug(message, t);
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public void debug(Object message) {
if (message != null) {
getLogger().debug(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public void debug(Object message, Throwable t) {
if (message != null) {
getLogger().debug(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public void info(Object message) {
if (message != null) {
getLogger().info(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public void info(Object message, Throwable t) {
if (message != null) {
getLogger().info(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public void warn(Object message) {
if (message != null) {
getLogger().warn(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public void warn(Object message, Throwable t) {
if (message != null) {
getLogger().warn(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public void error(Object message) {
if (message != null) {
getLogger().error(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public void error(Object message, Throwable t) {
if (message != null) {
getLogger().error(String.valueOf(message), t);
}
}
/**
* Logs a message with <code>org.apache.log.Priority.FATAL_ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public void fatal(Object message) {
if (message != null) {
getLogger().fatalError(String.valueOf(message));
}
}
/**
* Logs a message with <code>org.apache.log.Priority.FATAL_ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public void fatal(Object message, Throwable t) {
if (message != null) {
getLogger().fatalError(String.valueOf(message), t);
}
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>DEBUG</code>.
*/
public boolean isDebugEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>ERROR</code>.
*/
public boolean isErrorEnabled() {
return getLogger().isErrorEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>FATAL_ERROR</code>.
*/
public boolean isFatalEnabled() {
return getLogger().isFatalErrorEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>INFO</code>.
*/
public boolean isInfoEnabled() {
return getLogger().isInfoEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>DEBUG</code>.
*/
public boolean isTraceEnabled() {
return getLogger().isDebugEnabled();
}
/**
* Checks whether the <code>LogKit</code> logger will log messages of priority <code>WARN</code>.
*/
public boolean isWarnEnabled() {
return getLogger().isWarnEnabled();
}
}

View File

@@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.Serializable;
import org.apache.commons.logging.Log;
/**
* <p>Trivial implementation of Log that throws away all messages. No
* configurable system properties are supported.</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
* @version $Id: NoOpLog.java 424107 2006-07-20 23:15:42Z skitching $
*/
public class NoOpLog implements Log, Serializable {
/** Convenience constructor */
public NoOpLog() { }
/** Base constructor */
public NoOpLog(String name) { }
/** Do nothing */
public void trace(Object message) { }
/** Do nothing */
public void trace(Object message, Throwable t) { }
/** Do nothing */
public void debug(Object message) { }
/** Do nothing */
public void debug(Object message, Throwable t) { }
/** Do nothing */
public void info(Object message) { }
/** Do nothing */
public void info(Object message, Throwable t) { }
/** Do nothing */
public void warn(Object message) { }
/** Do nothing */
public void warn(Object message, Throwable t) { }
/** Do nothing */
public void error(Object message) { }
/** Do nothing */
public void error(Object message, Throwable t) { }
/** Do nothing */
public void fatal(Object message) { }
/** Do nothing */
public void fatal(Object message, Throwable t) { }
/**
* Debug is never enabled.
*
* @return false
*/
public final boolean isDebugEnabled() { return false; }
/**
* Error is never enabled.
*
* @return false
*/
public final boolean isErrorEnabled() { return false; }
/**
* Fatal is never enabled.
*
* @return false
*/
public final boolean isFatalEnabled() { return false; }
/**
* Info is never enabled.
*
* @return false
*/
public final boolean isInfoEnabled() { return false; }
/**
* Trace is never enabled.
*
* @return false
*/
public final boolean isTraceEnabled() { return false; }
/**
* Warn is never enabled.
*
* @return false
*/
public final boolean isWarnEnabled() { return false; }
}

View File

@@ -0,0 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.LogFactory;
/**
* This class is capable of receiving notifications about the undeployment of
* a webapp, and responds by ensuring that commons-logging releases all
* memory associated with the undeployed webapp.
* <p>
* In general, the WeakHashtable support added in commons-logging release 1.1
* ensures that logging classes do not hold references that prevent an
* undeployed webapp's memory from being garbage-collected even when multiple
* copies of commons-logging are deployed via multiple classloaders (a
* situation that earlier versions had problems with). However there are
* some rare cases where the WeakHashtable approach does not work; in these
* situations specifying this class as a listener for the web application will
* ensure that all references held by commons-logging are fully released.
* <p>
* To use this class, configure the webapp deployment descriptor to call
* this class on webapp undeploy; the contextDestroyed method will tell
* every accessable LogFactory class that the entry in its map for the
* current webapp's context classloader should be cleared.
*
* @since 1.1
*/
public class ServletContextCleaner implements ServletContextListener {
private Class[] RELEASE_SIGNATURE = {ClassLoader.class};
/**
* Invoked when a webapp is undeployed, this tells the LogFactory
* class to release any logging information related to the current
* contextClassloader.
*/
public void contextDestroyed(ServletContextEvent sce) {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
Object[] params = new Object[1];
params[0] = tccl;
// Walk up the tree of classloaders, finding all the available
// LogFactory classes and releasing any objects associated with
// the tccl (ie the webapp).
//
// When there is only one LogFactory in the classpath, and it
// is within the webapp being undeployed then there is no problem;
// garbage collection works fine.
//
// When there are multiple LogFactory classes in the classpath but
// parent-first classloading is used everywhere, this loop is really
// short. The first instance of LogFactory found will
// be the highest in the classpath, and then no more will be found.
// This is ok, as with this setup this will be the only LogFactory
// holding any data associated with the tccl being released.
//
// When there are multiple LogFactory classes in the classpath and
// child-first classloading is used in any classloader, then multiple
// LogFactory instances may hold info about this TCCL; whenever the
// webapp makes a call into a class loaded via an ancestor classloader
// and that class calls LogFactory the tccl gets registered in
// the LogFactory instance that is visible from the ancestor
// classloader. However the concrete logging library it points
// to is expected to have been loaded via the TCCL, so the
// underlying logging lib is only initialised/configured once.
// These references from ancestor LogFactory classes down to
// TCCL classloaders are held via weak references and so should
// be released but there are circumstances where they may not.
// Walking up the classloader ancestry ladder releasing
// the current tccl at each level tree, though, will definitely
// clear any problem references.
ClassLoader loader = tccl;
while (loader != null) {
// Load via the current loader. Note that if the class is not accessable
// via this loader, but is accessable via some ancestor then that class
// will be returned.
try {
Class logFactoryClass = loader.loadClass("org.apache.commons.logging.LogFactory");
Method releaseMethod = logFactoryClass.getMethod("release", RELEASE_SIGNATURE);
releaseMethod.invoke(null, params);
loader = logFactoryClass.getClassLoader().getParent();
} catch(ClassNotFoundException ex) {
// Neither the current classloader nor any of its ancestors could find
// the LogFactory class, so we can stop now.
loader = null;
} catch(NoSuchMethodException ex) {
// This is not expected; every version of JCL has this method
System.err.println("LogFactory instance found which does not support release method!");
loader = null;
} catch(IllegalAccessException ex) {
// This is not expected; every ancestor class should be accessable
System.err.println("LogFactory instance found which is not accessable!");
loader = null;
} catch(InvocationTargetException ex) {
// This is not expected
System.err.println("LogFactory instance release method failed!");
loader = null;
}
}
// Just to be sure, invoke release on the LogFactory that is visible from
// this ServletContextCleaner class too. This should already have been caught
// by the above loop but just in case...
LogFactory.release(tccl);
}
/**
* Invoked when a webapp is deployed. Nothing needs to be done here.
*/
public void contextInitialized(ServletContextEvent sce) {
// do nothing
}
}

View File

@@ -0,0 +1,721 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;
/**
* <p>Simple implementation of Log that sends all enabled log messages,
* for all defined loggers, to System.err. The following system properties
* are supported to configure the behavior of this logger:</p>
* <ul>
* <li><code>org.apache.commons.logging.simplelog.defaultlog</code> -
* Default logging detail level for all instances of SimpleLog.
* Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
* If not specified, defaults to "info". </li>
* <li><code>org.apache.commons.logging.simplelog.log.xxxxx</code> -
* Logging detail level for a SimpleLog instance named "xxxxx".
* Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
* If not specified, the default logging detail level is used.</li>
* <li><code>org.apache.commons.logging.simplelog.showlogname</code> -
* Set to <code>true</code> if you want the Log instance name to be
* included in output messages. Defaults to <code>false</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.showShortLogname</code> -
* Set to <code>true</code> if you want the last component of the name to be
* included in output messages. Defaults to <code>true</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.showdatetime</code> -
* Set to <code>true</code> if you want the current date and time
* to be included in output messages. Default is <code>false</code>.</li>
* <li><code>org.apache.commons.logging.simplelog.dateTimeFormat</code> -
* The date and time format to be used in the output messages.
* The pattern describing the date and time format is the same that is
* used in <code>java.text.SimpleDateFormat</code>. If the format is not
* specified or is invalid, the default format is used.
* The default format is <code>yyyy/MM/dd HH:mm:ss:SSS zzz</code>.</li>
* </ul>
*
* <p>In addition to looking for system properties with the names specified
* above, this implementation also checks for a class loader resource named
* <code>"simplelog.properties"</code>, and includes any matching definitions
* from this resource (if it exists).</p>
*
* @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
* @author Rod Waldhoff
* @author Robert Burrell Donkin
*
* @version $Id: SimpleLog.java 581090 2007-10-01 22:01:06Z dennisl $
*/
public class SimpleLog implements Log, Serializable {
// ------------------------------------------------------- Class Attributes
/** All system properties used by <code>SimpleLog</code> start with this */
static protected final String systemPrefix =
"org.apache.commons.logging.simplelog.";
/** Properties loaded from simplelog.properties */
static protected final Properties simpleLogProps = new Properties();
/** The default format to use when formating dates */
static protected final String DEFAULT_DATE_TIME_FORMAT =
"yyyy/MM/dd HH:mm:ss:SSS zzz";
/** Include the instance name in the log message? */
static protected boolean showLogName = false;
/** Include the short name ( last component ) of the logger in the log
* message. Defaults to true - otherwise we'll be lost in a flood of
* messages without knowing who sends them.
*/
static protected boolean showShortName = true;
/** Include the current time in the log message */
static protected boolean showDateTime = false;
/** The date and time format to use in the log message */
static protected String dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;
/**
* Used to format times.
* <p>
* Any code that accesses this object should first obtain a lock on it,
* ie use synchronized(dateFormatter); this requirement was introduced
* in 1.1.1 to fix an existing thread safety bug (SimpleDateFormat.format
* is not thread-safe).
*/
static protected DateFormat dateFormatter = null;
// ---------------------------------------------------- Log Level Constants
/** "Trace" level logging. */
public static final int LOG_LEVEL_TRACE = 1;
/** "Debug" level logging. */
public static final int LOG_LEVEL_DEBUG = 2;
/** "Info" level logging. */
public static final int LOG_LEVEL_INFO = 3;
/** "Warn" level logging. */
public static final int LOG_LEVEL_WARN = 4;
/** "Error" level logging. */
public static final int LOG_LEVEL_ERROR = 5;
/** "Fatal" level logging. */
public static final int LOG_LEVEL_FATAL = 6;
/** Enable all logging levels */
public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1);
/** Enable no logging levels */
public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1);
// ------------------------------------------------------------ Initializer
private static String getStringProperty(String name) {
String prop = null;
try {
prop = System.getProperty(name);
} catch (SecurityException e) {
; // Ignore
}
return (prop == null) ? simpleLogProps.getProperty(name) : prop;
}
private static String getStringProperty(String name, String dephault) {
String prop = getStringProperty(name);
return (prop == null) ? dephault : prop;
}
private static boolean getBooleanProperty(String name, boolean dephault) {
String prop = getStringProperty(name);
return (prop == null) ? dephault : "true".equalsIgnoreCase(prop);
}
// Initialize class attributes.
// Load properties file, if found.
// Override with system properties.
static {
// Add props from the resource simplelog.properties
InputStream in = getResourceAsStream("simplelog.properties");
if(null != in) {
try {
simpleLogProps.load(in);
in.close();
} catch(java.io.IOException e) {
// ignored
}
}
showLogName = getBooleanProperty( systemPrefix + "showlogname", showLogName);
showShortName = getBooleanProperty( systemPrefix + "showShortLogname", showShortName);
showDateTime = getBooleanProperty( systemPrefix + "showdatetime", showDateTime);
if(showDateTime) {
dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat",
dateTimeFormat);
try {
dateFormatter = new SimpleDateFormat(dateTimeFormat);
} catch(IllegalArgumentException e) {
// If the format pattern is invalid - use the default format
dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;
dateFormatter = new SimpleDateFormat(dateTimeFormat);
}
}
}
// ------------------------------------------------------------- Attributes
/** The name of this simple log instance */
protected String logName = null;
/** The current log level */
protected int currentLogLevel;
/** The short name of this simple log instance */
private String shortLogName = null;
// ------------------------------------------------------------ Constructor
/**
* Construct a simple log with given name.
*
* @param name log name
*/
public SimpleLog(String name) {
logName = name;
// Set initial log level
// Used to be: set default log level to ERROR
// IMHO it should be lower, but at least info ( costin ).
setLevel(SimpleLog.LOG_LEVEL_INFO);
// Set log level from properties
String lvl = getStringProperty(systemPrefix + "log." + logName);
int i = String.valueOf(name).lastIndexOf(".");
while(null == lvl && i > -1) {
name = name.substring(0,i);
lvl = getStringProperty(systemPrefix + "log." + name);
i = String.valueOf(name).lastIndexOf(".");
}
if(null == lvl) {
lvl = getStringProperty(systemPrefix + "defaultlog");
}
if("all".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_ALL);
} else if("trace".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_TRACE);
} else if("debug".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_DEBUG);
} else if("info".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_INFO);
} else if("warn".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_WARN);
} else if("error".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_ERROR);
} else if("fatal".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_FATAL);
} else if("off".equalsIgnoreCase(lvl)) {
setLevel(SimpleLog.LOG_LEVEL_OFF);
}
}
// -------------------------------------------------------- Properties
/**
* <p> Set logging level. </p>
*
* @param currentLogLevel new logging level
*/
public void setLevel(int currentLogLevel) {
this.currentLogLevel = currentLogLevel;
}
/**
* <p> Get logging level. </p>
*/
public int getLevel() {
return currentLogLevel;
}
// -------------------------------------------------------- Logging Methods
/**
* <p> Do the actual logging.
* This method assembles the message
* and then calls <code>write()</code> to cause it to be written.</p>
*
* @param type One of the LOG_LEVEL_XXX constants defining the log level
* @param message The message itself (typically a String)
* @param t The exception whose stack trace should be logged
*/
protected void log(int type, Object message, Throwable t) {
// Use a string buffer for better performance
StringBuffer buf = new StringBuffer();
// Append date-time if so configured
if(showDateTime) {
Date now = new Date();
String dateText;
synchronized(dateFormatter) {
dateText = dateFormatter.format(now);
}
buf.append(dateText);
buf.append(" ");
}
// Append a readable representation of the log level
switch(type) {
case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO] "); break;
case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN] "); break;
case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
}
// Append the name of the log instance if so configured
if( showShortName) {
if( shortLogName==null ) {
// Cut all but the last component of the name for both styles
shortLogName = logName.substring(logName.lastIndexOf(".") + 1);
shortLogName =
shortLogName.substring(shortLogName.lastIndexOf("/") + 1);
}
buf.append(String.valueOf(shortLogName)).append(" - ");
} else if(showLogName) {
buf.append(String.valueOf(logName)).append(" - ");
}
// Append the message
buf.append(String.valueOf(message));
// Append stack trace if not null
if(t != null) {
buf.append(" <");
buf.append(t.toString());
buf.append(">");
java.io.StringWriter sw= new java.io.StringWriter(1024);
java.io.PrintWriter pw= new java.io.PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
buf.append(sw.toString());
}
// Print to the appropriate destination
write(buf);
}
/**
* <p>Write the content of the message accumulated in the specified
* <code>StringBuffer</code> to the appropriate output destination. The
* default implementation writes to <code>System.err</code>.</p>
*
* @param buffer A <code>StringBuffer</code> containing the accumulated
* text to be logged
*/
protected void write(StringBuffer buffer) {
System.err.println(buffer.toString());
}
/**
* Is the given log level currently enabled?
*
* @param logLevel is this level enabled?
*/
protected boolean isLevelEnabled(int logLevel) {
// log level are numerically ordered so can use simple numeric
// comparison
return (logLevel >= currentLogLevel);
}
// -------------------------------------------------------- Log Implementation
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#debug(Object)
*/
public final void debug(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#debug(Object, Throwable)
*/
public final void debug(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#trace(Object)
*/
public final void trace(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
log(SimpleLog.LOG_LEVEL_TRACE, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#trace(Object, Throwable)
*/
public final void trace(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
log(SimpleLog.LOG_LEVEL_TRACE, message, t);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#info(Object)
*/
public final void info(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
log(SimpleLog.LOG_LEVEL_INFO,message,null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#info(Object, Throwable)
*/
public final void info(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
log(SimpleLog.LOG_LEVEL_INFO, message, t);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#warn(Object)
*/
public final void warn(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
log(SimpleLog.LOG_LEVEL_WARN, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#warn(Object, Throwable)
*/
public final void warn(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
log(SimpleLog.LOG_LEVEL_WARN, message, t);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#error(Object)
*/
public final void error(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
log(SimpleLog.LOG_LEVEL_ERROR, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#error(Object, Throwable)
*/
public final void error(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
log(SimpleLog.LOG_LEVEL_ERROR, message, t);
}
}
/**
* Log a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.
*
* @param message to log
* @see org.apache.commons.logging.Log#fatal(Object)
*/
public final void fatal(Object message) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
log(SimpleLog.LOG_LEVEL_FATAL, message, null);
}
}
/**
* Logs a message with
* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.
*
* @param message to log
* @param t log this cause
* @see org.apache.commons.logging.Log#fatal(Object, Throwable)
*/
public final void fatal(Object message, Throwable t) {
if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
log(SimpleLog.LOG_LEVEL_FATAL, message, t);
}
}
/**
* <p> Are debug messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isDebugEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
}
/**
* <p> Are error messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isErrorEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
}
/**
* <p> Are fatal messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isFatalEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
}
/**
* <p> Are info messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isInfoEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
}
/**
* <p> Are trace messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isTraceEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
}
/**
* <p> Are warn messages currently enabled? </p>
*
* <p> This allows expensive operations such as <code>String</code>
* concatenation to be avoided when the message will be ignored by the
* logger. </p>
*/
public final boolean isWarnEnabled() {
return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
}
/**
* Return the thread context class loader if available.
* Otherwise return null.
*
* The thread context class loader is available for JDK 1.2
* or later, if certain security conditions are met.
*
* @exception LogConfigurationException if a suitable class loader
* cannot be identified.
*/
private static ClassLoader getContextClassLoader()
{
ClassLoader classLoader = null;
if (classLoader == null) {
try {
// Are we running on a JDK 1.2 or later system?
Method method = Thread.class.getMethod("getContextClassLoader",
(Class[]) null);
// Get the thread context class loader (if there is one)
try {
classLoader = (ClassLoader)method.invoke(Thread.currentThread(),
(Class[]) null);
} catch (IllegalAccessException e) {
; // ignore
} catch (InvocationTargetException e) {
/**
* InvocationTargetException is thrown by 'invoke' when
* the method being invoked (getContextClassLoader) throws
* an exception.
*
* getContextClassLoader() throws SecurityException when
* the context class loader isn't an ancestor of the
* calling class's class loader, or if security
* permissions are restricted.
*
* In the first case (not related), we want to ignore and
* keep going. We cannot help but also ignore the second
* with the logic below, but other calls elsewhere (to
* obtain a class loader) will trigger this exception where
* we can make a distinction.
*/
if (e.getTargetException() instanceof SecurityException) {
; // ignore
} else {
// Capture 'e.getTargetException()' exception for details
// alternate: log 'e.getTargetException()', and pass back 'e'.
throw new LogConfigurationException
("Unexpected InvocationTargetException", e.getTargetException());
}
}
} catch (NoSuchMethodException e) {
// Assume we are running on JDK 1.1
; // ignore
}
}
if (classLoader == null) {
classLoader = SimpleLog.class.getClassLoader();
}
// Return the selected class loader
return classLoader;
}
private static InputStream getResourceAsStream(final String name)
{
return (InputStream)AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
ClassLoader threadCL = getContextClassLoader();
if (threadCL != null) {
return threadCL.getResourceAsStream(name);
} else {
return ClassLoader.getSystemResourceAsStream(name);
}
}
});
}
}

View File

@@ -0,0 +1,478 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.logging.impl;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
/**
* <p>Implementation of <code>Hashtable</code> that uses <code>WeakReference</code>'s
* to hold its keys thus allowing them to be reclaimed by the garbage collector.
* The associated values are retained using strong references.</p>
*
* <p>This class follows the symantics of <code>Hashtable</code> as closely as
* possible. It therefore does not accept null values or keys.</p>
*
* <p><strong>Note:</strong>
* This is <em>not</em> intended to be a general purpose hash table replacement.
* This implementation is also tuned towards a particular purpose: for use as a replacement
* for <code>Hashtable</code> in <code>LogFactory</code>. This application requires
* good liveliness for <code>get</code> and <code>put</code>. Various tradeoffs
* have been made with this in mind.
* </p>
* <p>
* <strong>Usage:</strong> typical use case is as a drop-in replacement
* for the <code>Hashtable</code> used in <code>LogFactory</code> for J2EE enviroments
* running 1.3+ JVMs. Use of this class <i>in most cases</i> (see below) will
* allow classloaders to be collected by the garbage collector without the need
* to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}.
* </p>
*
* <p><code>org.apache.commons.logging.LogFactory</code> checks whether this class
* can be supported by the current JVM, and if so then uses it to store
* references to the <code>LogFactory</code> implementationd it loads
* (rather than using a standard Hashtable instance).
* Having this class used instead of <code>Hashtable</code> solves
* certain issues related to dynamic reloading of applications in J2EE-style
* environments. However this class requires java 1.3 or later (due to its use
* of <code>java.lang.ref.WeakReference</code> and associates).
* And by the way, this extends <code>Hashtable</code> rather than <code>HashMap</code>
* for backwards compatibility reasons. See the documentation
* for method <code>LogFactory.createFactoryStore</code> for more details.</p>
*
* <p>The reason all this is necessary is due to a issue which
* arises during hot deploy in a J2EE-like containers.
* Each component running in the container owns one or more classloaders; when
* the component loads a LogFactory instance via the component classloader
* a reference to it gets stored in the static LogFactory.factories member,
* keyed by the component's classloader so different components don't
* stomp on each other. When the component is later unloaded, the container
* sets the component's classloader to null with the intent that all the
* component's classes get garbage-collected. However there's still a
* reference to the component's classloader from a key in the "global"
* <code>LogFactory</code>'s factories member! If <code>LogFactory.release()</code>
* is called whenever component is unloaded, the classloaders will be correctly
* garbage collected; this <i>should</i> be done by any container that
* bundles commons-logging by default. However, holding the classloader
* references weakly ensures that the classloader will be garbage collected
* without the container performing this step. </p>
*
* <p>
* <strong>Limitations:</strong>
* There is still one (unusual) scenario in which a component will not
* be correctly unloaded without an explicit release. Though weak references
* are used for its keys, it is necessary to use strong references for its values.
* </p>
*
* <p> If the abstract class <code>LogFactory</code> is
* loaded by the container classloader but a subclass of
* <code>LogFactory</code> [LogFactory1] is loaded by the component's
* classloader and an instance stored in the static map associated with the
* base LogFactory class, then there is a strong reference from the LogFactory
* class to the LogFactory1 instance (as normal) and a strong reference from
* the LogFactory1 instance to the component classloader via
* <code>getClass().getClassLoader()</code>. This chain of references will prevent
* collection of the child classloader.</p>
*
* <p>
* Such a situation occurs when the commons-logging.jar is
* loaded by a parent classloader (e.g. a server level classloader in a
* servlet container) and a custom <code>LogFactory</code> implementation is
* loaded by a child classloader (e.g. a web app classloader).</p>
*
* <p>To avoid this scenario, ensure
* that any custom LogFactory subclass is loaded by the same classloader as
* the base <code>LogFactory</code>. Creating custom LogFactory subclasses is,
* however, rare. The standard LogFactoryImpl class should be sufficient
* for most or all users.</p>
*
*
* @author Brian Stansberry
*
* @since 1.1
*/
public final class WeakHashtable extends Hashtable {
/**
* The maximum number of times put() or remove() can be called before
* the map will be purged of all cleared entries.
*/
private static final int MAX_CHANGES_BEFORE_PURGE = 100;
/**
* The maximum number of times put() or remove() can be called before
* the map will be purged of one cleared entry.
*/
private static final int PARTIAL_PURGE_COUNT = 10;
/* ReferenceQueue we check for gc'd keys */
private ReferenceQueue queue = new ReferenceQueue();
/* Counter used to control how often we purge gc'd entries */
private int changeCount = 0;
/**
* Constructs a WeakHashtable with the Hashtable default
* capacity and load factor.
*/
public WeakHashtable() {}
/**
*@see Hashtable
*/
public boolean containsKey(Object key) {
// purge should not be required
Referenced referenced = new Referenced(key);
return super.containsKey(referenced);
}
/**
*@see Hashtable
*/
public Enumeration elements() {
purge();
return super.elements();
}
/**
*@see Hashtable
*/
public Set entrySet() {
purge();
Set referencedEntries = super.entrySet();
Set unreferencedEntries = new HashSet();
for (Iterator it=referencedEntries.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Referenced referencedKey = (Referenced) entry.getKey();
Object key = referencedKey.getValue();
Object value = entry.getValue();
if (key != null) {
Entry dereferencedEntry = new Entry(key, value);
unreferencedEntries.add(dereferencedEntry);
}
}
return unreferencedEntries;
}
/**
*@see Hashtable
*/
public Object get(Object key) {
// for performance reasons, no purge
Referenced referenceKey = new Referenced(key);
return super.get(referenceKey);
}
/**
*@see Hashtable
*/
public Enumeration keys() {
purge();
final Enumeration enumer = super.keys();
return new Enumeration() {
public boolean hasMoreElements() {
return enumer.hasMoreElements();
}
public Object nextElement() {
Referenced nextReference = (Referenced) enumer.nextElement();
return nextReference.getValue();
}
};
}
/**
*@see Hashtable
*/
public Set keySet() {
purge();
Set referencedKeys = super.keySet();
Set unreferencedKeys = new HashSet();
for (Iterator it=referencedKeys.iterator(); it.hasNext();) {
Referenced referenceKey = (Referenced) it.next();
Object keyValue = referenceKey.getValue();
if (keyValue != null) {
unreferencedKeys.add(keyValue);
}
}
return unreferencedKeys;
}
/**
*@see Hashtable
*/
public Object put(Object key, Object value) {
// check for nulls, ensuring symantics match superclass
if (key == null) {
throw new NullPointerException("Null keys are not allowed");
}
if (value == null) {
throw new NullPointerException("Null values are not allowed");
}
// for performance reasons, only purge every
// MAX_CHANGES_BEFORE_PURGE times
if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) {
purge();
changeCount = 0;
}
// do a partial purge more often
else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) {
purgeOne();
}
Referenced keyRef = new Referenced(key, queue);
return super.put(keyRef, value);
}
/**
*@see Hashtable
*/
public void putAll(Map t) {
if (t != null) {
Set entrySet = t.entrySet();
for (Iterator it=entrySet.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
}
/**
*@see Hashtable
*/
public Collection values() {
purge();
return super.values();
}
/**
*@see Hashtable
*/
public Object remove(Object key) {
// for performance reasons, only purge every
// MAX_CHANGES_BEFORE_PURGE times
if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) {
purge();
changeCount = 0;
}
// do a partial purge more often
else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) {
purgeOne();
}
return super.remove(new Referenced(key));
}
/**
*@see Hashtable
*/
public boolean isEmpty() {
purge();
return super.isEmpty();
}
/**
*@see Hashtable
*/
public int size() {
purge();
return super.size();
}
/**
*@see Hashtable
*/
public String toString() {
purge();
return super.toString();
}
/**
* @see Hashtable
*/
protected void rehash() {
// purge here to save the effort of rehashing dead entries
purge();
super.rehash();
}
/**
* Purges all entries whose wrapped keys
* have been garbage collected.
*/
private void purge() {
synchronized (queue) {
WeakKey key;
while ((key = (WeakKey) queue.poll()) != null) {
super.remove(key.getReferenced());
}
}
}
/**
* Purges one entry whose wrapped key
* has been garbage collected.
*/
private void purgeOne() {
synchronized (queue) {
WeakKey key = (WeakKey) queue.poll();
if (key != null) {
super.remove(key.getReferenced());
}
}
}
/** Entry implementation */
private final static class Entry implements Map.Entry {
private final Object key;
private final Object value;
private Entry(Object key, Object value) {
this.key = key;
this.value = value;
}
public boolean equals(Object o) {
boolean result = false;
if (o != null && o instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) o;
result = (getKey()==null ?
entry.getKey() == null :
getKey().equals(entry.getKey()))
&&
(getValue()==null ?
entry.getValue() == null :
getValue().equals(entry.getValue()));
}
return result;
}
public int hashCode() {
return (getKey()==null ? 0 : getKey().hashCode()) ^
(getValue()==null ? 0 : getValue().hashCode());
}
public Object setValue(Object value) {
throw new UnsupportedOperationException("Entry.setValue is not supported.");
}
public Object getValue() {
return value;
}
public Object getKey() {
return key;
}
}
/** Wrapper giving correct symantics for equals and hashcode */
private final static class Referenced {
private final WeakReference reference;
private final int hashCode;
/**
*
* @throws NullPointerException if referant is <code>null</code>
*/
private Referenced(Object referant) {
reference = new WeakReference(referant);
// Calc a permanent hashCode so calls to Hashtable.remove()
// work if the WeakReference has been cleared
hashCode = referant.hashCode();
}
/**
*
* @throws NullPointerException if key is <code>null</code>
*/
private Referenced(Object key, ReferenceQueue queue) {
reference = new WeakKey(key, queue, this);
// Calc a permanent hashCode so calls to Hashtable.remove()
// work if the WeakReference has been cleared
hashCode = key.hashCode();
}
public int hashCode() {
return hashCode;
}
private Object getValue() {
return reference.get();
}
public boolean equals(Object o) {
boolean result = false;
if (o instanceof Referenced) {
Referenced otherKey = (Referenced) o;
Object thisKeyValue = getValue();
Object otherKeyValue = otherKey.getValue();
if (thisKeyValue == null) {
result = (otherKeyValue == null);
// Since our hashcode was calculated from the original
// non-null referant, the above check breaks the
// hashcode/equals contract, as two cleared Referenced
// objects could test equal but have different hashcodes.
// We can reduce (not eliminate) the chance of this
// happening by comparing hashcodes.
if (result == true) {
result = (this.hashCode() == otherKey.hashCode());
}
// In any case, as our c'tor does not allow null referants
// and Hashtable does not do equality checks between
// existing keys, normal hashtable operations should never
// result in an equals comparison between null referants
}
else
{
result = thisKeyValue.equals(otherKeyValue);
}
}
return result;
}
}
/**
* WeakReference subclass that holds a hard reference to an
* associated <code>value</code> and also makes accessible
* the Referenced object holding it.
*/
private final static class WeakKey extends WeakReference {
private final Referenced referenced;
private WeakKey(Object key,
ReferenceQueue queue,
Referenced referenced) {
super(key, queue);
this.referenced = referenced;
}
private Referenced getReferenced() {
return referenced;
}
}
}

View File

@@ -0,0 +1,22 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<p>Concrete implementations of commons-logging wrapper APIs.</p>
</body>

View File

@@ -0,0 +1,255 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<p>Simple wrapper API around multiple logging APIs.</p>
<h3>Overview</h3>
<p>This package provides an API for logging in server-based applications that
can be used around a variety of different logging implementations, including
prebuilt support for the following:</p>
<ul>
<li><a href="http://logging.apache.org/log4j/">Log4J</a> (version 1.2 or later)
from Apache's Logging project. Each named <a href="Log.html">Log</a>
instance is connected to a corresponding Log4J Logger.</li>
<li><a href="http://java.sun.com/j2se/1.4/docs/guide/util/logging/index.html">
JDK Logging API</a>, included in JDK 1.4 or later systems. Each named
<a href="Log.html">Log</a> instance is connected to a corresponding
<code>java.util.logging.Logger</code> instance.</li>
<li><a href="http://avalon.apache.org/logkit/">LogKit</a> from Apache's
Avalon project. Each named <a href="Log.html">Log</a> instance is
connected to a corresponding LogKit <code>Logger</code>.</li>
<li><a href="impl/NoOpLog.html">NoOpLog</a> implementation that simply swallows
all log output, for all named <a href="Log.html">Log</a> instances.</li>
<li><a href="impl/SimpleLog.html">SimpleLog</a> implementation that writes all
log output, for all named <a href="Log.html">Log</a> instances, to
System.err.</li>
</ul>
<h3>Quick Start Guide</h3>
<p>For those impatient to just get on with it, the following example
illustrates the typical declaration and use of a logger that is named (by
convention) after the calling class:
<pre>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Foo {
private Log log = LogFactory.getLog(Foo.class);
public void foo() {
...
try {
if (log.isDebugEnabled()) {
log.debug("About to do something to object " + name);
}
name.bar();
} catch (IllegalStateException e) {
log.error("Something bad happened to " + name, e);
}
...
}
</pre>
<p>Unless you configure things differently, all log output will be written
to System.err. Therefore, you really will want to review the remainder of
this page in order to understand how to configure logging for your
application.</p>
<h3>Configuring the Commons Logging Package</h3>
<h4>Choosing a <code>LogFactory</code> Implementation</h4>
<p>From an application perspective, the first requirement is to retrieve an
object reference to the <code>LogFactory</code> instance that will be used
to create <code><a href="Log.html">Log</a></code> instances for this
application. This is normally accomplished by calling the static
<code>getFactory()</code> method. This method implements the following
discovery algorithm to select the name of the <code>LogFactory</code>
implementation class this application wants to use:</p>
<ul>
<li>Check for a system property named
<code>org.apache.commons.logging.LogFactory</code>.</li>
<li>Use the JDK 1.3 JAR Services Discovery mechanism (see
<a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html">
http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html</a> for
more information) to look for a resource named
<code>META-INF/services/org.apache.commons.logging.LogFactory</code>
whose first line is assumed to contain the desired class name.</li>
<li>Look for a properties file named <code>commons-logging.properties</code>
visible in the application class path, with a property named
<code>org.apache.commons.logging.LogFactory</code> defining the
desired implementation class name.</li>
<li>Fall back to a default implementation, which is described
further below.</li>
</ul>
<p>If a <code>commons-logging.properties</code> file is found, all of the
properties defined there are also used to set configuration attributes on
the instantiated <code>LogFactory</code> instance.</p>
<p>Once an implementation class name is selected, the corresponding class is
loaded from the current Thread context class loader (if there is one), or
from the class loader that loaded the <code>LogFactory</code> class itself
otherwise. This allows a copy of <code>commons-logging.jar</code> to be
shared in a multiple class loader environment (such as a servlet container),
but still allow each web application to provide its own <code>LogFactory</code>
implementation, if it so desires. An instance of this class will then be
created, and cached per class loader.
<h4>The Default <code>LogFactory</code> Implementation</h4>
<p>The Logging Package APIs include a default <code>LogFactory</code>
implementation class (<a href="impl/LogFactoryImpl.html">
org.apache.commons.logging.impl.LogFactoryImpl</a>) that is selected if no
other implementation class name can be discovered. Its primary purpose is
to create (as necessary) and return <a href="Log.html">Log</a> instances
in response to calls to the <code>getInstance()</code> method. The default
implementation uses the following rules:</p>
<ul>
<li>At most one <code>Log</code> instance of the same name will be created.
Subsequent <code>getInstance()</code> calls to the same
<code>LogFactory</code> instance, with the same name or <code>Class</code>
parameter, will return the same <code>Log</code> instance.</li>
<li>When a new <code>Log</code> instance must be created, the default
<code>LogFactory</code> implementation uses the following discovery
process:
<ul>
<li>Look for a configuration attribute of this factory named
<code>org.apache.commons.logging.Log</code> (for backwards
compatibility to pre-1.0 versions of this API, an attribute
<code>org.apache.commons.logging.log</code> is also consulted).</li>
<li>Look for a system property named
<code>org.apache.commons.logging.Log</code> (for backwards
compatibility to pre-1.0 versions of this API, a system property
<code>org.apache.commons.logging.log</code> is also consulted).</li>
<li>If the Log4J logging system is available in the application
class path, use the corresponding wrapper class
(<a href="impl/Log4JLogger.html">Log4JLogger</a>).</li>
<li>If the application is executing on a JDK 1.4 system, use
the corresponding wrapper class
(<a href="impl/Jdk14Logger.html">Jdk14Logger</a>).</li>
<li>Fall back to the default simple logging implementation
(<a href="impl/SimpleLog.html">SimpleLog</a>).</li>
</ul></li>
<li>Load the class of the specified name from the thread context class
loader (if any), or from the class loader that loaded the
<code>LogFactory</code> class otherwise.</li>
<li>Instantiate an instance of the selected <code>Log</code>
implementation class, passing the specified name as the single
argument to its constructor.</li>
</ul>
<p>See the <a href="impl/SimpleLog.html">SimpleLog</a> JavaDocs for detailed
configuration information for this default implementation.</p>
<h4>Configuring the Underlying Logging System</h4>
<p>The basic principle is that the user is totally responsible for the
configuration of the underlying logging system.
Commons-logging should not change the existing configuration.</p>
<p>Each individual <a href="Log.html">Log</a> implementation may
support its own configuration properties. These will be documented in the
class descriptions for the corresponding implementation class.</p>
<p>Finally, some <code>Log</code> implementations (such as the one for Log4J)
require an external configuration file for the entire logging environment.
This file should be prepared in a manner that is specific to the actual logging
technology being used.</p>
<h3>Using the Logging Package APIs</h3>
<p>Use of the Logging Package APIs, from the perspective of an application
component, consists of the following steps:</p>
<ol>
<li>Acquire a reference to an instance of
<a href="Log.html">org.apache.commons.logging.Log</a>, by calling the
factory method
<a href="LogFactory.html#getInstance(java.lang.String)">
LogFactory.getInstance(String name)</a>. Your application can contain
references to multiple loggers that are used for different
purposes. A typical scenario for a server application is to have each
major component of the server use its own Log instance.</li>
<li>Cause messages to be logged (if the corresponding detail level is enabled)
by calling appropriate methods (<code>trace()</code>, <code>debug()</code>,
<code>info()</code>, <code>warn()</code>, <code>error</code>, and
<code>fatal()</code>).</li>
</ol>
<p>For convenience, <code>LogFactory</code> also offers a static method
<code>getLog()</code> that combines the typical two-step pattern:</p>
<pre>
Log log = LogFactory.getFactory().getInstance(Foo.class);
</pre>
<p>into a single method call:</p>
<pre>
Log log = LogFactory.getLog(Foo.class);
</pre>
<p>For example, you might use the following technique to initialize and
use a <a href="Log.html">Log</a> instance in an application component:</p>
<pre>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyComponent {
protected Log log =
LogFactory.getLog(MyComponent.class);
// Called once at startup time
public void start() {
...
log.info("MyComponent started");
...
}
// Called once at shutdown time
public void stop() {
...
log.info("MyComponent stopped");
...
}
// Called repeatedly to process a particular argument value
// which you want logged if debugging is enabled
public void process(String value) {
...
// Do the string concatenation only if logging is enabled
if (log.isDebugEnabled())
log.debug("MyComponent processing " + value);
...
}
}
</pre>
</body>

View File

@@ -0,0 +1,55 @@
package com.dt.iTunesController;
import com.jacob.com.Dispatch;
/**
* Represents a artwork.
*
* Defines a single piece of artwork.
*
* Artwork is always associated with an individual track.
* To add a piece of artwork to a track, use IITTrack::AddArtworkFromFile().
* The IITTrack::Artwork property
*
* To get a collection of artwork associated with a track call
* <code>ITTrack.getArtwork()</code>.
*
* @author <a href="mailto:steve@dot-totally.co.uk">Steve Eyre</a>
* @version 0.2
*/
public class ITArtwork extends ITObject {
public ITArtwork (Dispatch d) {
super(d);
}
/**
* Delete this object.
*/
public void delete() {
Dispatch.call(object, "Delete");
}
/**
* Returns the kind of the object.
* @return Returns the kind of the object.
*/
public ITArtworkFormat getFormat() {
return ITArtworkFormat.values()[Dispatch.get(object, "Format").getInt()];
}
// TODO: Comments
public boolean getIsDownloadedArtwork() {
return Dispatch.get(object, "IsDownloadedArtwork").getBoolean();
}
public String getDescription() {
return Dispatch.get(object, "Description").getString();
}
public void SaveArtworkToFile(String filePath) {
Dispatch.call(object, "SaveArtworkToFile",filePath);
}
}

View File

@@ -0,0 +1,55 @@
package com.dt.iTunesController;
import com.jacob.com.Dispatch;
/**
* Represents a collection of Artwork objects.
*
* Note that collection indices are always 1-based.
*
* You can retrieve all the Artworks defined for a source using
* <code>ITSource.getArtwork()</code>.
*
* @author <a href="mailto:steve@dot-totally.co.uk">Steve Eyre</a>
* @version 0.2
*/
public class ITArtworkCollection {
protected Dispatch object;
public ITArtworkCollection(Dispatch d) {
object = d;
}
/**
* Returns the number of playlists in the collection.
* @return Returns the number of playlists in the collection.
*/
public int getCount() {
return Dispatch.get(object, "Count").getInt();
}
/**
* Returns an ITArtwork object corresponding to the given index (1-based).
* @param index Index of the playlist to retrieve, must be less than or
* equal to <code>ITArtworkCollection.getCount()</code>.
* @return Returns an ITArtwork object corresponding to the given index.
* Will be set to NULL if no playlist could be retrieved.
*/
public ITArtwork getItem (int index) {
Dispatch item = Dispatch.call(object, "Item", index).toDispatch();
return new ITArtwork(item);
}
/**
* Returns an ITArtwork object with the specified persistent ID. See the
* documentation on ITObject for more information on persistent IDs.
* @param highID The high 32 bits of the 64-bit persistent ID.
* @param lowID The low 32 bits of the 64-bit persistent ID.
* @return Returns an ITArtwork object with the specified persistent ID.
* Will be set to NULL if no playlist could be retrieved.
*/
public ITArtwork getItemByPersistentID (int highID, int lowID) {
Dispatch item = Dispatch.call(object, "ItemByPersistentID", highID, lowID).toDispatch();
return new ITArtwork(item);
}
}

View File

@@ -0,0 +1,13 @@
package com.dt.iTunesController;
/**
* Specifies the Artwork kind.
* @author <a href="mailto:steve@dot-totally.co.uk">Steve Eyre</a>
* @version 0.2
*/
public enum ITArtworkFormat {
ITArtworkFormatUnknown,
ITArtworkFormatJPEG,
ITArtworkFormatPNG,
ITArtworkFormatBMP;
}

View File

@@ -0,0 +1,76 @@
package com.dt.iTunesController;
import com.jacob.com.Dispatch;
/**
* Represents an audio CD playlist.
*
* An audio CD playlist is always associated with an IITSource of kind
* ITSourceKindAudioCD.
*
* You can retrieve all the playlists defined for a source using
* <code>ITSource.getPlaylists()</code>.
* @author <a href="mailto:steve@dot-totally.co.uk">Steve Eyre</a>
* @version 0.2
*/
public class ITAudioCDPlaylist extends ITPlaylist {
public ITAudioCDPlaylist(Dispatch d) {
super(d);
}
/**
* Returns the audio CD's artist.
* @return Returns the audio CD's artist.
*/
public String getArtist() {
return Dispatch.get(object, "Artist").getString();
}
/**
* Returns true if this audio CD is a compilation album.
* @return Returns true if this audio CD is a compilation album.
*/
public boolean isCompilation() {
return Dispatch.get(object, "Compilation").getBoolean();
}
/**
* Returns the audio CD's composer.
* @return Returns the audio CD's composer.
*/
public String getComposer() {
return Dispatch.get(object, "Composer").getString();
}
/**
* Returns the total number of discs in this CD's album.
* @return Returns the total number of discs in this CD's album.
*/
public long getDiscCount() {
return Dispatch.get(object, "DiscCount").getLong();
}
/**
* Returns the index of the CD disc in the source album.
* @return Returns the index of the CD disc in the source album.
*/
public long getDiscNumber() {
return Dispatch.get(object, "DiscNumber").getLong();
}
/**
* Returns the audio CD's genre.
* @return Returns the audio CD's genre.
*/
public String getGenre() {
return Dispatch.get(object, "Genre").getString();
}
/**
* Reveals the CD playlist in the main browser window.
*/
public void reveal() {
Dispatch.call(object, "Reveal");
}
}

View File

@@ -0,0 +1,45 @@
package com.dt.iTunesController;
import com.jacob.com.Dispatch;
/**
* Represents the main browser window.
*
* You can retrieve the main browser window using
* <code>iTunes.BrowserWindow()</code>.
*
* @author <a href="mailto:steve@dot-totally.co.uk">Steve Eyre</a>
* @version 0.2
*/
public class ITBrowserWindow extends ITWindow {
public ITBrowserWindow (Dispatch d) {
super(d);
}
/**
* Returns the kind of the object.
* @return Returns the kind of the object.
*/
public boolean getMiniPlayer() {
return Dispatch.get(object, "MiniPlayer").getBoolean();
}
// TODO: Comments
public ITTrackCollection getSelectedTracks() {
Dispatch collection = Dispatch.call(object, "SelectedTracks").getDispatch();
return new ITTrackCollection(collection);
}
public ITPlaylist getSelectedPlaylist() {
Dispatch playlist = Dispatch.get(object, "SelectedPlaylist").toDispatch();
return new ITPlaylist(playlist);
}
public void setSelectedPlaylist(ITPlaylist playlist) {
Dispatch dispatchRef = playlist.fetchDispatch();
Dispatch.put(object, "SelectedPlaylist", dispatchRef);
}
}

Some files were not shown because too many files have changed in this diff Show More