import controlTypes\r
import NVDAObjects.JAB\r
\r
-bridgeDll=None\r
+#Some utility functions to help with function defines\r
+\r
+def _errcheck(res, func, args):\r
+ if not res:\r
+ raise RuntimeError("Result %s" % res)\r
+ return res\r
+\r
+def _fixBridgeFunc(restype,name,*argtypes,**kwargs):\r
+ func=getattr(bridgeDll,name)\r
+ func.restype=restype\r
+ func.argtypes=argtypes\r
+ if kwargs.get('errcheck'):\r
+ func.errcheck=_errcheck\r
+\r
+#Load the first available access bridge dll\r
+legacyAccessBridge=True\r
+try:\r
+ bridgeDll=getattr(cdll,'windowsAccessBridge-32')\r
+ legacyAccessBridge=False\r
+except WindowsError:\r
+ try:\r
+ bridgeDll=cdll.windowsAccessBridge\r
+ except WindowsError:\r
+ bridgeDll=None\r
+\r
+#Definitions of access bridge types, structs and prototypes\r
+\r
+jint=c_int\r
+jfloat=c_float\r
+class JOBJECT64(c_int if legacyAccessBridge else c_int64):\r
+ pass\r
+\r
+MAX_STRING_SIZE=1024\r
+SHORT_STRING_SIZE=256\r
+\r
+class AccessBridgeVersionInfo(Structure):\r
+ _fields_=[\r
+ ('VMVersion',WCHAR*SHORT_STRING_SIZE),\r
+ ('bridgeJavaClassVersion',WCHAR*SHORT_STRING_SIZE),\r
+ ('bridgeJavaDLLVersion',WCHAR*SHORT_STRING_SIZE),\r
+ ('bridgeWinDLLVersion',WCHAR*SHORT_STRING_SIZE),\r
+ ]\r
+\r
+class AccessibleContextInfo(Structure):\r
+ _fields_=[\r
+ ('name',WCHAR*MAX_STRING_SIZE),\r
+ ('description',WCHAR*MAX_STRING_SIZE),\r
+ ('role',WCHAR*SHORT_STRING_SIZE),\r
+ ('role_en_US',WCHAR*SHORT_STRING_SIZE),\r
+ ('states',WCHAR*SHORT_STRING_SIZE),\r
+ ('states_en_US',WCHAR*SHORT_STRING_SIZE),\r
+ ('indexInParent',jint),\r
+ ('childrenCount',jint),\r
+ ('x',jint),\r
+ ('y',jint),\r
+ ('width',jint),\r
+ ('height',jint),\r
+ ('accessibleComponent',BOOL),\r
+ ('accessibleAction',BOOL),\r
+ ('accessibleSelection',BOOL),\r
+ ('accessibleText',BOOL),\r
+ ('accessibleValue',BOOL),\r
+ ]\r
+\r
+class AccessibleTextInfo(Structure):\r
+ _fields_=[\r
+ ('charCount',jint),\r
+ ('caretIndex',jint),\r
+ ('indexAtPoint',jint),\r
+ ]\r
+\r
+class AccessibleTextItemsInfo(Structure):\r
+ _fields_=[\r
+ ('letter',WCHAR),\r
+ ('word',WCHAR*SHORT_STRING_SIZE),\r
+ ('sentence',WCHAR*MAX_STRING_SIZE),\r
+ ]\r
+\r
+class AccessibleTextSelectionInfo(Structure):\r
+ _fields_=[\r
+ ('selectionStartIndex',jint),\r
+ ('selectionEndIndex',jint),\r
+ ('selectedText',WCHAR*MAX_STRING_SIZE),\r
+ ]\r
+\r
+class AccessibleTextRectInfo(Structure):\r
+ _fields_=[\r
+ ('x',jint),\r
+ ('y',jint),\r
+ ('width',jint),\r
+ ('height',jint),\r
+ ]\r
+\r
+class AccessibleTextAttributesInfo(Structure):\r
+ _fields_=[\r
+ ('bold',BOOL),\r
+ ('italic',BOOL),\r
+ ('underline',BOOL),\r
+ ('strikethrough',BOOL),\r
+ ('superscript',BOOL),\r
+ ('subscript',BOOL),\r
+ ('backgroundColor',WCHAR*SHORT_STRING_SIZE),\r
+ ('foregroundColor',WCHAR*SHORT_STRING_SIZE),\r
+ ('fontFamily',WCHAR*SHORT_STRING_SIZE),\r
+ ('fontSize',jint),\r
+ ('alignment',jint),\r
+ ('bidiLevel',jint),\r
+ ('firstLineIndent',jfloat),\r
+ ('LeftIndent',jfloat),\r
+ ('rightIndent',jfloat),\r
+ ('lineSpacing',jfloat),\r
+ ('spaceAbove',jfloat),\r
+ ('spaceBelow',jfloat),\r
+ ('fullAttributesString',WCHAR*MAX_STRING_SIZE),\r
+ ]\r
+\r
+MAX_RELATION_TARGETS = 25\r
+MAX_RELATIONS = 5\r
+\r
+class AccessibleRelationInfo(Structure):\r
+ _fields_ = [\r
+ ("key", WCHAR * SHORT_STRING_SIZE),\r
+ ("targetCount", jint),\r
+ ("targets", JOBJECT64 * MAX_RELATION_TARGETS),\r
+ ]\r
+\r
+class AccessibleRelationSetInfo(Structure):\r
+ _fields_ = [\r
+ ("relationCount", jint),\r
+ ("relations", AccessibleRelationInfo * MAX_RELATIONS),\r
+ ]\r
+\r
+AccessBridge_FocusGainedFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64)\r
+AccessBridge_PropertyStateChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,c_wchar_p,c_wchar_p)\r
+AccessBridge_PropertyCaretChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,c_int,c_int)\r
+AccessBridge_PropertyActiveDescendentChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,JOBJECT64,JOBJECT64)\r
+\r
+#Appropriately set the return and argument types of all the access bridge dll functions\r
+if bridgeDll:\r
+ _fixBridgeFunc(None,'Windows_run')\r
+ _fixBridgeFunc(None,'setFocusGainedFP',c_void_p)\r
+ _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p)\r
+ _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p)\r
+ _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p)\r
+ _fixBridgeFunc(None,'releaseJavaObject',c_long,JOBJECT64)\r
+ _fixBridgeFunc(BOOL,'getVersionInfo',POINTER(AccessBridgeVersionInfo),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'isJavaWindow',HWND)\r
+ _fixBridgeFunc(BOOL,'isSameObject',c_long,JOBJECT64,JOBJECT64)\r
+ _fixBridgeFunc(BOOL,'getAccessibleContextFromHWND',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True)\r
+ _fixBridgeFunc(HWND,'getHWNDFromAccessibleContext',c_long,JOBJECT64,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleContextAt',c_long,JOBJECT64,jint,jint,POINTER(JOBJECT64),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleContextWithFocus',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True)\r
+ _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True)\r
+ _fixBridgeFunc(JOBJECT64,'getAccessibleParentFromContext',c_long,JOBJECT64)\r
+ _fixBridgeFunc(BOOL,'getAccessibleRelationSet',c_long,JOBJECT64,POINTER(AccessibleRelationSetInfo),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextInfo',c_long,JOBJECT64,POINTER(AccessibleTextInfo),jint,jint,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextItems',c_long,JOBJECT64,POINTER(AccessibleTextItemsInfo),jint,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextSelectionInfo',c_long,JOBJECT64,POINTER(AccessibleTextSelectionInfo),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextAttributes',c_long,JOBJECT64,jint,POINTER(AccessibleTextAttributesInfo),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextLineBounds',c_long,JOBJECT64,jint,POINTER(jint),POINTER(jint),errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getAccessibleTextRange',c_long,JOBJECT64,jint,jint,POINTER(c_wchar),c_short,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getCurrentAccessibleValueFromContext',c_long,JOBJECT64,POINTER(c_wchar),c_short,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True)\r
+ _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True)\r
+ _fixBridgeFunc(c_int,'getObjectDepth',c_long,JOBJECT64)\r
+ _fixBridgeFunc(JOBJECT64,'getActiveDescendent',c_long,JOBJECT64)\r
+ _fixBridgeFunc(BOOL,'requestFocus',c_long,JOBJECT64,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True)\r
+ _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True)\r
+\r
+#NVDA specific code\r
+\r
isRunning=False\r
vmIDsToWindowHandles={}\r
internalFunctionQueue=Queue.Queue(1000)\r
def internalQueueFunction(func,*args,**kwargs):\r
internalFunctionQueue.put_nowait((func,args,kwargs))\r
\r
-MAX_STRING_SIZE=1024\r
-SHORT_STRING_SIZE=256\r
-\r
class JABContext(object):\r
\r
def __init__(self,hwnd=None,vmID=None,accContext=None):\r
if hwnd and not vmID:\r
vmID=c_int()\r
- accContext=c_int()\r
+ accContext=JOBJECT64()\r
bridgeDll.getAccessibleContextFromHWND(hwnd,byref(vmID),byref(accContext))\r
vmID=vmID.value\r
- accContext=accContext.value\r
#Record this vm ID and window handle for later use with other objects\r
vmIDsToWindowHandles[vmID]=hwnd\r
elif vmID and not hwnd:\r
return None\r
\r
def getAccessibleContextAt(self,x,y):\r
- newAccContext=c_int()\r
+ newAccContext=JOBJECT64()\r
res=bridgeDll.getAccessibleContextAt(self.vmID,self.accContext,x,y,byref(newAccContext))\r
- newAccContext=newAccContext.value\r
if not res or not newAccContext:\r
return None\r
if not bridgeDll.isSameObject(self.vmID,newAccContext,self.accContext):\r
bridgeDll.getAccessibleRelationSet(self.vmID, self.accContext, byref(relations))\r
return relations\r
\r
-class AccessBridgeVersionInfo(Structure):\r
- _fields_=[\r
- ('VMVersion',WCHAR*SHORT_STRING_SIZE),\r
- ('bridgeJavaClassVersion',WCHAR*SHORT_STRING_SIZE),\r
- ('bridgeJavaDLLVersion',WCHAR*SHORT_STRING_SIZE),\r
- ('bridgeWinDLLVersion',WCHAR*SHORT_STRING_SIZE),\r
- ]\r
-\r
-class AccessibleContextInfo(Structure):\r
- _fields_=[\r
- ('name',WCHAR*MAX_STRING_SIZE),\r
- ('description',WCHAR*MAX_STRING_SIZE),\r
- ('role',WCHAR*SHORT_STRING_SIZE),\r
- ('role_en_US',WCHAR*SHORT_STRING_SIZE),\r
- ('states',WCHAR*SHORT_STRING_SIZE),\r
- ('states_en_US',WCHAR*SHORT_STRING_SIZE),\r
- ('indexInParent',c_int),\r
- ('childrenCount',c_int),\r
- ('x',c_int),\r
- ('y',c_int),\r
- ('width',c_int),\r
- ('height',c_int),\r
- ('accessibleComponent',BOOL),\r
- ('accessibleAction',BOOL),\r
- ('accessibleSelection',BOOL),\r
- ('accessibleText',BOOL),\r
- ('accessibleValue',BOOL),\r
- ]\r
-\r
-class AccessibleTextInfo(Structure):\r
- _fields_=[\r
- ('charCount',c_int),\r
- ('caretIndex',c_int),\r
- ('indexAtPoint',c_int),\r
- ]\r
-\r
-class AccessibleTextItemsInfo(Structure):\r
- _fields_=[\r
- ('letter',WCHAR),\r
- ('word',WCHAR*SHORT_STRING_SIZE),\r
- ('sentence',WCHAR*MAX_STRING_SIZE),\r
- ]\r
-\r
-class AccessibleTextSelectionInfo(Structure):\r
- _fields_=[\r
- ('selectionStartIndex',c_int),\r
- ('selectionEndIndex',c_int),\r
- ('selectedText',WCHAR*MAX_STRING_SIZE),\r
- ]\r
-\r
-class AccessibleTextRectInfo(Structure):\r
- _fields_=[\r
- ('x',c_int),\r
- ('y',c_int),\r
- ('width',c_int),\r
- ('height',c_int),\r
- ]\r
-\r
-class AccessibleTextAttributesInfo(Structure):\r
- _fields_=[\r
- ('bold',BOOL),\r
- ('italic',BOOL),\r
- ('underline',BOOL),\r
- ('strikethrough',BOOL),\r
- ('superscript',BOOL),\r
- ('subscript',BOOL),\r
- ('backgroundColor',WCHAR*SHORT_STRING_SIZE),\r
- ('foregroundColor',WCHAR*SHORT_STRING_SIZE),\r
- ('fontFamily',WCHAR*SHORT_STRING_SIZE),\r
- ('fontSize',c_int),\r
- ('alignment',c_int),\r
- ('bidiLevel',c_int),\r
- ('firstLineIndent',c_float),\r
- ('LeftIndent',c_float),\r
- ('rightIndent',c_float),\r
- ('lineSpacing',c_float),\r
- ('spaceAbove',c_float),\r
- ('spaceBelow',c_float),\r
- ('fullAttributesString',WCHAR*MAX_STRING_SIZE),\r
- ]\r
-\r
-MAX_RELATION_TARGETS = 25\r
-MAX_RELATIONS = 5\r
-\r
-class AccessibleRelationInfo(Structure):\r
- _fields_ = [\r
- ("key", WCHAR * SHORT_STRING_SIZE),\r
- ("targetCount", c_int),\r
- ("targets", c_int * MAX_RELATION_TARGETS),\r
- ]\r
-\r
-class AccessibleRelationSetInfo(Structure):\r
- _fields_ = [\r
- ("relationCount", c_int),\r
- ("relations", AccessibleRelationInfo * MAX_RELATIONS),\r
- ]\r
-\r
-@CFUNCTYPE(None,c_int,c_int,c_int)\r
+@AccessBridge_FocusGainedFP\r
def internal_event_focusGained(vmID, event,source):\r
internalQueueFunction(event_gainFocus,vmID,source)\r
bridgeDll.releaseJavaObject(vmID,event)\r
return\r
eventHandler.queueEvent("gainFocus",obj)\r
\r
-@CFUNCTYPE(None,c_int,c_int,c_int,c_int,c_int)\r
+@AccessBridge_PropertyActiveDescendentChangeFP\r
def internal_event_activeDescendantChange(vmID, event,source,oldDescendant,newDescendant):\r
internalQueueFunction(event_gainFocus,vmID,newDescendant)\r
for accContext in [event,oldDescendant]:\r
bridgeDll.releaseJavaObject(vmID,accContext)\r
\r
-@CFUNCTYPE(None,c_int,c_int,c_int,c_wchar_p,c_wchar_p)\r
+@AccessBridge_PropertyStateChangeFP\r
def internal_event_stateChange(vmID,event,source,oldState,newState):\r
internalQueueFunction(event_stateChange,vmID,source,oldState,newState)\r
bridgeDll.releaseJavaObject(vmID,event)\r
return\r
eventHandler.queueEvent("stateChange",obj)\r
\r
-@CFUNCTYPE(None,c_int,c_int,c_int,c_int,c_int)\r
+@AccessBridge_PropertyCaretChangeFP\r
def internal_event_caretChange(vmID, event,source,oldPos,newPos):\r
if oldPos<0 and newPos>=0:\r
internalQueueFunction(event_gainFocus,vmID,source)\r
\r
def event_enterJavaWindow(hwnd):\r
vmID=c_int()\r
- accContext=c_int()\r
+ accContext=JOBJECT64()\r
try:\r
bridgeDll.getAccessibleContextFromHWND(hwnd,byref(vmID),byref(accContext))\r
except:\r
return\r
- vmIDsToWindowHandles[vmID.value]=hwnd\r
+ vmID=vmID.value\r
+ vmIDsToWindowHandles[vmID]=hwnd\r
lastFocus=eventHandler.lastQueuedFocusObject\r
if isinstance(lastFocus,NVDAObjects.JAB.JAB) and lastFocus.windowHandle==hwnd:\r
return\r
- internalQueueFunction(event_gainFocus,vmID.value,accContext.value)\r
+ internalQueueFunction(event_gainFocus,vmID,accContext)\r
\r
def isJavaWindow(hwnd):\r
- if not isRunning:\r
+ if not bridgeDll or not isRunning:\r
return False\r
return bridgeDll.isJavaWindow(hwnd)\r
\r
-def _errcheck(res, func, args):\r
- if not res:\r
- raise RuntimeError("Result %d" % res)\r
-\r
def initialize():\r
- global bridgeDll, isRunning\r
- try:\r
- bridgeDll=cdll.WINDOWSACCESSBRIDGE\r
- for func in (\r
- bridgeDll.Windows_run, bridgeDll.getAccessibleContextFromHWND, bridgeDll.getVersionInfo, \r
- bridgeDll.getAccessibleContextInfo, bridgeDll.getAccessibleTextInfo, bridgeDll.getAccessibleTextItems,\r
- bridgeDll.getAccessibleTextSelectionInfo, bridgeDll.getAccessibleTextRange, bridgeDll.getAccessibleTextLineBounds,\r
- bridgeDll.getCurrentAccessibleValueFromContext, bridgeDll.selectTextRange, bridgeDll.setCaretPosition,\r
- bridgeDll.getAccessibleContextWithFocus, \r
- ):\r
- func.errcheck = _errcheck\r
- bridgeDll.Windows_run()\r
- #Accept wm_copydata and any wm_user messages from other processes even if running with higher privilages\r
- ChangeWindowMessageFilter=getattr(windll.user32,'ChangeWindowMessageFilter',None)\r
- if ChangeWindowMessageFilter:\r
- if not ChangeWindowMessageFilter(winUser.WM_COPYDATA,1):\r
+ global isRunning\r
+ if not bridgeDll:\r
+ raise NotImplementedError("dll not available")\r
+ bridgeDll.Windows_run()\r
+ #Accept wm_copydata and any wm_user messages from other processes even if running with higher privilages\r
+ ChangeWindowMessageFilter=getattr(windll.user32,'ChangeWindowMessageFilter',None)\r
+ if ChangeWindowMessageFilter:\r
+ if not ChangeWindowMessageFilter(winUser.WM_COPYDATA,1):\r
+ raise WinError()\r
+ for msg in xrange(winUser.WM_USER+1,65535):\r
+ if not ChangeWindowMessageFilter(msg,1):\r
raise WinError()\r
- for msg in xrange(winUser.WM_USER+1,65535):\r
- if not ChangeWindowMessageFilter(msg,1):\r
- raise WinError()\r
- #Register java events\r
- bridgeDll.setFocusGainedFP(internal_event_focusGained)\r
- bridgeDll.setPropertyActiveDescendentChangeFP(internal_event_activeDescendantChange)\r
- bridgeDll.setPropertyStateChangeFP(internal_event_stateChange)\r
- bridgeDll.setPropertyCaretChangeFP(internal_event_caretChange)\r
- isRunning=True\r
- return True\r
- except:\r
- log.debugWarning("Error initializing java access bridge",exc_info=True)\r
- return False\r
+ #Register java events\r
+ bridgeDll.setFocusGainedFP(internal_event_focusGained)\r
+ bridgeDll.setPropertyActiveDescendentChangeFP(internal_event_activeDescendantChange)\r
+ bridgeDll.setPropertyStateChangeFP(internal_event_stateChange)\r
+ bridgeDll.setPropertyCaretChangeFP(internal_event_caretChange)\r
+ isRunning=True\r
\r
def pumpAll():\r
if isRunning: \r
\r
def terminate():\r
global isRunning, bridgeDll\r
- if not isRunning:\r
+ if not bridgeDll or not isRunning:\r
return\r
bridgeDll.setFocusGainedFP(None)\r
bridgeDll.setPropertyActiveDescendentChangeFP(None)\r
bridgeDll.setPropertyStateChangeFP(None)\r
bridgeDll.setPropertyCaretChangeFP(None)\r
- windll.kernel32.FreeLibrary(bridgeDll._handle)\r
- cdll.WINDOWSACCESSBRIDGE=bridgeDll=None\r
+ h=bridgeDll._handle\r
+ bridgeDll=None\r
+ if legacyAccessBridge:\r
+ del cdll.windowsAccessBridge \r
+ else:\r
+ delattr(cdll,'windowsAccessBridge-32')\r
+ windll.kernel32.FreeLibrary(h)\r
isRunning=False\r