blob: e16192a8cb0c5cfaee760ba38439c27389600ce3 [file] [log] [blame]
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* A class to manage firing Accessibility events to Windows AT
*/
#include "AccessBridgeDebug.h"
#include "AccessBridgeEventHandler.h"
#include "AccessBridgePackages.h"
#include "WinAccessBridge.h"
DEBUG_CODE(extern HWND theDialogWindow);
extern "C" {
DEBUG_CODE(void AppendToCallInfo(char *s));
}
// -----------------------------
/**
* Initialization. Set all callbacks to null
*/
AccessBridgeEventHandler::AccessBridgeEventHandler() {
javaEventMask = 0;
accessibilityEventMask = 0;
propertyChangeFP = (AccessBridge_PropertyChangeFP) NULL;
javaShutdownFP = (AccessBridge_JavaShutdownFP) NULL;
focusGainedFP = (AccessBridge_FocusGainedFP) NULL;
focusLostFP = (AccessBridge_FocusLostFP) NULL;
caretUpdateFP = (AccessBridge_CaretUpdateFP) NULL;
mouseClickedFP = (AccessBridge_MouseClickedFP) NULL;
mouseEnteredFP = (AccessBridge_MouseEnteredFP) NULL;
mouseExitedFP = (AccessBridge_MouseExitedFP) NULL;
mousePressedFP = (AccessBridge_MousePressedFP) NULL;
mouseReleasedFP = (AccessBridge_MouseReleasedFP) NULL;
menuCanceledFP = (AccessBridge_MenuCanceledFP) NULL;
menuDeselectedFP = (AccessBridge_MenuDeselectedFP) NULL;
menuSelectedFP = (AccessBridge_MenuSelectedFP) NULL;
popupMenuCanceledFP = (AccessBridge_PopupMenuCanceledFP) NULL;
popupMenuWillBecomeInvisibleFP = (AccessBridge_PopupMenuWillBecomeInvisibleFP) NULL;
popupMenuWillBecomeVisibleFP = (AccessBridge_PopupMenuWillBecomeVisibleFP) NULL;
propertyNameChangeFP = (AccessBridge_PropertyNameChangeFP) NULL;
propertyDescriptionChangeFP = (AccessBridge_PropertyDescriptionChangeFP) NULL;
propertyStateChangeFP = (AccessBridge_PropertyStateChangeFP) NULL;
propertyValueChangeFP = (AccessBridge_PropertyValueChangeFP) NULL;
propertySelectionChangeFP = (AccessBridge_PropertySelectionChangeFP) NULL;
propertyTextChangeFP = (AccessBridge_PropertyTextChangeFP) NULL;
propertyCaretChangeFP = (AccessBridge_PropertyCaretChangeFP) NULL;
propertyVisibleDataChangeFP = (AccessBridge_PropertyVisibleDataChangeFP) NULL;
propertyChildChangeFP = (AccessBridge_PropertyChildChangeFP) NULL;
propertyActiveDescendentChangeFP = (AccessBridge_PropertyActiveDescendentChangeFP) NULL;
propertyTableModelChangeFP = (AccessBridge_PropertyTableModelChangeFP) NULL;
}
/**
* Destruction.
*/
AccessBridgeEventHandler::~AccessBridgeEventHandler() {
}
// ------------ Event handling methods
#define SET_JAVA_EVENT_FP(function, eventFP, callbackFP, eventConstant) \
void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \
callbackFP = fp; \
if (fp != (eventFP) 0) { \
javaEventMask |= eventConstant; \
wab->addJavaEventNotification(eventConstant); \
} else { \
javaEventMask &= (0xFFFFFFFF - eventConstant); \
wab->removeJavaEventNotification(eventConstant); \
} \
}
SET_JAVA_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP, propertyChangeFP, cPropertyChangeEvent)
SET_JAVA_EVENT_FP(setJavaShutdownFP, AccessBridge_JavaShutdownFP, javaShutdownFP, cJavaShutdownEvent)
SET_JAVA_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP, focusGainedFP, cFocusGainedEvent)
SET_JAVA_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP, focusLostFP, cFocusLostEvent)
SET_JAVA_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP, caretUpdateFP, cCaretUpdateEvent)
SET_JAVA_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP, mouseClickedFP, cMouseClickedEvent)
SET_JAVA_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP, mouseEnteredFP, cMouseEnteredEvent)
SET_JAVA_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP, mouseExitedFP, cMouseExitedEvent)
SET_JAVA_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP, mousePressedFP, cMousePressedEvent)
SET_JAVA_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP, mouseReleasedFP, cMouseReleasedEvent)
SET_JAVA_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP, menuCanceledFP, cMenuCanceledEvent)
SET_JAVA_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP, menuDeselectedFP, cMenuDeselectedEvent)
SET_JAVA_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP, menuSelectedFP, cMenuSelectedEvent)
SET_JAVA_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP, cPopupMenuCanceledEvent)
SET_JAVA_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP, cPopupMenuWillBecomeInvisibleEvent)
SET_JAVA_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP, cPopupMenuWillBecomeVisibleEvent)
#define SET_ACCESSIBILITY_EVENT_FP(function, eventFP, callbackFP, eventConstant) \
void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \
callbackFP = fp; \
if (fp != (eventFP) 0) { \
accessibilityEventMask |= eventConstant; \
wab->addAccessibilityEventNotification(eventConstant); \
} else { \
accessibilityEventMask &= (0xFFFFFFFF - eventConstant); \
wab->removeAccessibilityEventNotification(eventConstant); \
} \
}
SET_ACCESSIBILITY_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP, propertyNameChangeFP, cPropertyNameChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP, propertyDescriptionChangeFP, cPropertyDescriptionChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP, propertyStateChangeFP, cPropertyStateChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP, propertyValueChangeFP, cPropertyValueChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP, propertySelectionChangeFP, cPropertySelectionChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP, propertyTextChangeFP, cPropertyTextChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP, propertyCaretChangeFP, cPropertyCaretChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP, propertyVisibleDataChangeFP, cPropertyVisibleDataChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP, propertyChildChangeFP, cPropertyChildChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP, propertyActiveDescendentChangeFP, cPropertyActiveDescendentChangeEvent)
SET_ACCESSIBILITY_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP, propertyTableModelChangeFP, cPropertyTableModelChangeEvent)
/**
* propertyChange - extends the Java method call to Windows:
* propertyChange(PropertyChangeEvent e, )
*
* Note: PropertyChangeEvent object passed in is a globalReference;
* It is critical that releaseJavaObject() be called
* on the PropertyChangeEvent once it is no longer needed,
* otherwise the JavaVM/JNI will suffer memory leaks
*
*/
void
AccessBridgeEventHandler::firePropertyChange(long vmID,
JOBJECT64 event, JOBJECT64 source,
wchar_t *property, wchar_t *oldName,
wchar_t *newName) {
DEBUG_CODE(char debugBuf[255]);
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%p, %p):\r\n", event, source));
#else // JOBJECT64 is jlong (64 bit)
DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%016I64X, %016I64X):\r\n", event, source));
#endif
DEBUG_CODE(AppendToCallInfo(debugBuf));
if (propertyChangeFP != (AccessBridge_PropertyChangeFP) 0) {
propertyChangeFP(vmID, event, source, property, oldName, newName);
} else {
DEBUG_CODE(AppendToCallInfo("[ERROR]: propertyChangeFP == 0"));
}
}
/**
* FIRE_EVENT - macro for all fireXXX methods (which
* all are basically identical to one another...)
*
* Note: the event and source objects passed in are globalReferences;
* It is critical that releaseJavaObject() be called
* on them once they are no longer needed, otherwise
* the JavaVM/JNI will suffer memory leaks
*
*/
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n";
#else // JOBJECT64 is jlong (64 bit)
const char fireEventDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n";
#endif
#define FIRE_EVENT(method, FPprototype, eventFP) \
void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \
DEBUG_CODE(char debugBuf[255]); \
DEBUG_CODE(sprintf(debugBuf, fireEventDebugString, #method, event, source, vmID)); \
DEBUG_CODE(AppendToCallInfo(debugBuf)); \
if (eventFP != (FPprototype) 0) { \
eventFP(vmID, event, source); \
} else { \
DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0")); \
} \
}
void AccessBridgeEventHandler::fireJavaShutdown(long vmID) {
DEBUG_CODE(char debugBuf[255]);
DEBUG_CODE(sprintf(debugBuf, "[INFO]: Calling fireJavaShutdown; vmID = %X\r\n", vmID));
DEBUG_CODE(AppendToCallInfo(debugBuf));
if (javaShutdownFP != (AccessBridge_JavaShutdownFP) 0) {
javaShutdownFP(vmID);
} else {
DEBUG_CODE(AppendToCallInfo("[ERROR]: javaShutdownFP == 0"));
}
}
FIRE_EVENT(fireFocusGained, AccessBridge_FocusGainedFP, focusGainedFP)
FIRE_EVENT(fireFocusLost, AccessBridge_FocusLostFP, focusLostFP)
FIRE_EVENT(fireCaretUpdate, AccessBridge_CaretUpdateFP, caretUpdateFP)
FIRE_EVENT(fireMouseClicked, AccessBridge_MouseClickedFP, mouseClickedFP)
FIRE_EVENT(fireMouseEntered, AccessBridge_MouseEnteredFP, mouseEnteredFP)
FIRE_EVENT(fireMouseExited, AccessBridge_MouseExitedFP, mouseExitedFP)
FIRE_EVENT(fireMousePressed, AccessBridge_MousePressedFP, mousePressedFP)
FIRE_EVENT(fireMouseReleased, AccessBridge_MouseReleasedFP, mouseReleasedFP)
FIRE_EVENT(fireMenuCanceled, AccessBridge_MenuCanceledFP, menuCanceledFP)
FIRE_EVENT(fireMenuDeselected, AccessBridge_MenuDeselectedFP, menuDeselectedFP)
FIRE_EVENT(fireMenuSelected, AccessBridge_MenuSelectedFP, menuSelectedFP)
FIRE_EVENT(firePopupMenuCanceled, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP)
FIRE_EVENT(firePopupMenuWillBecomeInvisible, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP)
FIRE_EVENT(firePopupMenuWillBecomeVisible, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP)
/**
* FIRE_PROPERTY_CHANGE - macro for all fireXXX methods (which
* all are basically identical to one another...
*
* Note: the event and source objects passed in are globalReferences;
* It is critical that releaseJavaObject() be called
* on them once they are no longer needed, otherwise
* the JavaVM/JNI will suffer memory leaks
*
*/
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n";
#else // JOBJECT64 is jlong (64 bit)
const char firePropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n";
#endif
#define FIRE_PROPERTY_CHANGE(method, FPprototype, eventFP) \
void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \
DEBUG_CODE(char debugBuf[255]); \
DEBUG_CODE(sprintf(debugBuf, firePropertyChangeDebugString, #method, event, source)); \
DEBUG_CODE(AppendToCallInfo(debugBuf)); \
if (eventFP != (FPprototype) 0) { \
eventFP(vmID, event, source); \
} else { \
DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0")); \
} \
}
/**
* FIRE_STRING_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods
* that have strings as the old/new values
* Note: the event and source objects passed in are globalReferences;
* It is critical that releaseJavaObject() be called
* on them once they are no longer needed, otherwise
* the JavaVM/JNI will suffer memory leaks
*
*/
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n";
#else // JOBJECT64 is jlong (64 bit)
const char fireStringPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n";
#endif
#define FIRE_STRING_PROPERTY_CHANGE(method, FPprototype, eventFP, oldValue, newValue) \
void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \
wchar_t *oldValue, wchar_t *newValue) { \
DEBUG_CODE(char debugBuf[255]); \
DEBUG_CODE(sprintf(debugBuf, fireStringPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \
DEBUG_CODE(AppendToCallInfo(debugBuf)); \
if (eventFP != (FPprototype) 0) { \
eventFP(vmID, event, source, oldValue, newValue); \
} else { \
DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \
} \
}
/**
* FIRE_INT_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods
* that have ints as the old/new values
*
* Note: the event and source objects passed in are globalReferences;
* It is critical that releaseJavaObject() be called
* on them once they are no longer needed, otherwise
* the JavaVM/JNI will suffer memory leaks
*
*/
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n";
#else // JOBJECT64 is jlong (64 bit)
const char fireIntPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n";
#endif
#define FIRE_INT_PROPERTY_CHANGE(method, FPprototype, eventFP) \
void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \
int oldValue, int newValue) { \
DEBUG_CODE(char debugBuf[255]); \
DEBUG_CODE(sprintf(debugBuf, fireIntPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \
DEBUG_CODE(AppendToCallInfo(debugBuf)); \
if (eventFP != (FPprototype) 0) { \
eventFP(vmID, event, source, oldValue, newValue); \
} else { \
DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \
} \
}
/**
* FIRE_AC_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods
* that have jobjects (AccessibleContexts) as the old/new values
*
* Note: the event and source objects passed in are globalReferences;
* It is critical that releaseJavaObject() be called
* on them once they are no longer needed, otherwise
* the JavaVM/JNI will suffer memory leaks
*
*/
#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer)
const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n";
#else // JOBJECT64 is jlong (64 bit)
const char fireACPropertyChangeDebugString[] = "[INFO]: In AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n";
#endif
#define FIRE_AC_PROPERTY_CHANGE(method, FPprototype, eventFP) \
void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \
JOBJECT64 oldValue, JOBJECT64 newValue) { \
DEBUG_CODE(char debugBuf[255]); \
DEBUG_CODE(sprintf(debugBuf, fireACPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \
DEBUG_CODE(AppendToCallInfo(debugBuf)); \
if (eventFP != (FPprototype) 0) { \
eventFP(vmID, event, source, oldValue, newValue); \
} else { \
DEBUG_CODE(AppendToCallInfo("[ERROR]: eventFP == 0\r\n")); \
} \
}
FIRE_STRING_PROPERTY_CHANGE(firePropertyNameChange,
AccessBridge_PropertyNameChangeFP,
propertyNameChangeFP, oldName, newName)
FIRE_STRING_PROPERTY_CHANGE(firePropertyDescriptionChange,
AccessBridge_PropertyDescriptionChangeFP,
propertyDescriptionChangeFP,
oldDescription, newDescription)
FIRE_STRING_PROPERTY_CHANGE(firePropertyStateChange,
AccessBridge_PropertyStateChangeFP,
propertyStateChangeFP, oldState, newState)
FIRE_STRING_PROPERTY_CHANGE(firePropertyValueChange,
AccessBridge_PropertyValueChangeFP,
propertyValueChangeFP, oldValue, newValue)
FIRE_PROPERTY_CHANGE(firePropertySelectionChange,
AccessBridge_PropertySelectionChangeFP,
propertySelectionChangeFP)
FIRE_PROPERTY_CHANGE(firePropertyTextChange,
AccessBridge_PropertyTextChangeFP,
propertyTextChangeFP);
FIRE_INT_PROPERTY_CHANGE(firePropertyCaretChange,
AccessBridge_PropertyCaretChangeFP,
propertyCaretChangeFP)
FIRE_PROPERTY_CHANGE(firePropertyVisibleDataChange,
AccessBridge_PropertyVisibleDataChangeFP,
propertyVisibleDataChangeFP)
FIRE_AC_PROPERTY_CHANGE(firePropertyChildChange,
AccessBridge_PropertyChildChangeFP,
propertyChildChangeFP)
FIRE_AC_PROPERTY_CHANGE(firePropertyActiveDescendentChange,
AccessBridge_PropertyActiveDescendentChangeFP,
propertyActiveDescendentChangeFP)
FIRE_STRING_PROPERTY_CHANGE(firePropertyTableModelChange,
AccessBridge_PropertyTableModelChangeFP,
propertyTableModelChangeFP, oldValue, newValue)