1
2
3
4
5
6
7 import Queue
8 from ctypes import *
9 from ctypes.wintypes import *
10 import queueHandler
11 import speech
12 import globalVars
13 from logHandler import log
14 import winUser
15 import api
16 import eventHandler
17 import controlTypes
18 import NVDAObjects.JAB
23 if not res:
24 raise RuntimeError("Result %s" % res)
25 return res
26
28 try:
29 func=getattr(bridgeDll,name)
30 except AttributeError:
31 log.warning("%s not found in Java Access Bridge dll"%name)
32 return
33 func.restype=restype
34 func.argtypes=argtypes
35 if kwargs.get('errcheck'):
36 func.errcheck=_errcheck
37
38
39 legacyAccessBridge=True
40 try:
41 bridgeDll=getattr(cdll,'windowsAccessBridge-32')
42 legacyAccessBridge=False
43 except WindowsError:
44 try:
45 bridgeDll=cdll.windowsAccessBridge
46 except WindowsError:
47 bridgeDll=None
48
49
50
51 jint=c_int
52 jfloat=c_float
53 -class JOBJECT64(c_int if legacyAccessBridge else c_int64):
55
56 MAX_STRING_SIZE=1024
57 SHORT_STRING_SIZE=256
66
68 _fields_=[
69 ('name',WCHAR*MAX_STRING_SIZE),
70 ('description',WCHAR*MAX_STRING_SIZE),
71 ('role',WCHAR*SHORT_STRING_SIZE),
72 ('role_en_US',WCHAR*SHORT_STRING_SIZE),
73 ('states',WCHAR*SHORT_STRING_SIZE),
74 ('states_en_US',WCHAR*SHORT_STRING_SIZE),
75 ('indexInParent',jint),
76 ('childrenCount',jint),
77 ('x',jint),
78 ('y',jint),
79 ('width',jint),
80 ('height',jint),
81 ('accessibleComponent',BOOL),
82 ('accessibleAction',BOOL),
83 ('accessibleSelection',BOOL),
84 ('accessibleText',BOOL),
85 ('accessibleValue',BOOL),
86 ]
87
88 -class AccessibleTextInfo(Structure):
89 _fields_=[
90 ('charCount',jint),
91 ('caretIndex',jint),
92 ('indexAtPoint',jint),
93 ]
94
96 _fields_=[
97 ('letter',WCHAR),
98 ('word',WCHAR*SHORT_STRING_SIZE),
99 ('sentence',WCHAR*MAX_STRING_SIZE),
100 ]
101
103 _fields_=[
104 ('selectionStartIndex',jint),
105 ('selectionEndIndex',jint),
106 ('selectedText',WCHAR*MAX_STRING_SIZE),
107 ]
108
110 _fields_=[
111 ('x',jint),
112 ('y',jint),
113 ('width',jint),
114 ('height',jint),
115 ]
116
118 _fields_=[
119 ('bold',BOOL),
120 ('italic',BOOL),
121 ('underline',BOOL),
122 ('strikethrough',BOOL),
123 ('superscript',BOOL),
124 ('subscript',BOOL),
125 ('backgroundColor',WCHAR*SHORT_STRING_SIZE),
126 ('foregroundColor',WCHAR*SHORT_STRING_SIZE),
127 ('fontFamily',WCHAR*SHORT_STRING_SIZE),
128 ('fontSize',jint),
129 ('alignment',jint),
130 ('bidiLevel',jint),
131 ('firstLineIndent',jfloat),
132 ('LeftIndent',jfloat),
133 ('rightIndent',jfloat),
134 ('lineSpacing',jfloat),
135 ('spaceAbove',jfloat),
136 ('spaceBelow',jfloat),
137 ('fullAttributesString',WCHAR*MAX_STRING_SIZE),
138 ]
139
140 MAX_RELATION_TARGETS = 25
141 MAX_RELATIONS = 5
149
155
156 MAX_ACTION_INFO = 256
157 MAX_ACTIONS_TO_DO = 32
163
169
175
176 AccessBridge_FocusGainedFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64)
177 AccessBridge_PropertyStateChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,c_wchar_p,c_wchar_p)
178 AccessBridge_PropertyCaretChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,c_int,c_int)
179 AccessBridge_PropertyActiveDescendentChangeFP=CFUNCTYPE(None,c_long,JOBJECT64,JOBJECT64,JOBJECT64,JOBJECT64)
180
181
182 if bridgeDll:
183 _fixBridgeFunc(None,'Windows_run')
184 _fixBridgeFunc(None,'setFocusGainedFP',c_void_p)
185 _fixBridgeFunc(None,'setPropertyStateChangeFP',c_void_p)
186 _fixBridgeFunc(None,'setPropertyCaretChangeFP',c_void_p)
187 _fixBridgeFunc(None,'setPropertyActiveDescendentChangeFP',c_void_p)
188 _fixBridgeFunc(None,'releaseJavaObject',c_long,JOBJECT64)
189 _fixBridgeFunc(BOOL,'getVersionInfo',POINTER(AccessBridgeVersionInfo),errcheck=True)
190 _fixBridgeFunc(BOOL,'isJavaWindow',HWND)
191 _fixBridgeFunc(BOOL,'isSameObject',c_long,JOBJECT64,JOBJECT64)
192 _fixBridgeFunc(BOOL,'getAccessibleContextFromHWND',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True)
193 _fixBridgeFunc(HWND,'getHWNDFromAccessibleContext',c_long,JOBJECT64,errcheck=True)
194 _fixBridgeFunc(BOOL,'getAccessibleContextAt',c_long,JOBJECT64,jint,jint,POINTER(JOBJECT64),errcheck=True)
195 _fixBridgeFunc(BOOL,'getAccessibleContextWithFocus',HWND,POINTER(c_long),POINTER(JOBJECT64),errcheck=True)
196 _fixBridgeFunc(BOOL,'getAccessibleContextInfo',c_long,JOBJECT64,POINTER(AccessibleContextInfo),errcheck=True)
197 _fixBridgeFunc(JOBJECT64,'getAccessibleChildFromContext',c_long,JOBJECT64,jint,errcheck=True)
198 _fixBridgeFunc(JOBJECT64,'getAccessibleParentFromContext',c_long,JOBJECT64)
199 _fixBridgeFunc(BOOL,'getAccessibleRelationSet',c_long,JOBJECT64,POINTER(AccessibleRelationSetInfo),errcheck=True)
200 _fixBridgeFunc(BOOL,'getAccessibleTextInfo',c_long,JOBJECT64,POINTER(AccessibleTextInfo),jint,jint,errcheck=True)
201 _fixBridgeFunc(BOOL,'getAccessibleTextItems',c_long,JOBJECT64,POINTER(AccessibleTextItemsInfo),jint,errcheck=True)
202 _fixBridgeFunc(BOOL,'getAccessibleTextSelectionInfo',c_long,JOBJECT64,POINTER(AccessibleTextSelectionInfo),errcheck=True)
203 _fixBridgeFunc(BOOL,'getAccessibleTextAttributes',c_long,JOBJECT64,jint,POINTER(AccessibleTextAttributesInfo),errcheck=True)
204 _fixBridgeFunc(BOOL,'getAccessibleTextLineBounds',c_long,JOBJECT64,jint,POINTER(jint),POINTER(jint),errcheck=True)
205 _fixBridgeFunc(BOOL,'getAccessibleTextRange',c_long,JOBJECT64,jint,jint,POINTER(c_wchar),c_short,errcheck=True)
206 _fixBridgeFunc(BOOL,'getCurrentAccessibleValueFromContext',c_long,JOBJECT64,POINTER(c_wchar),c_short,errcheck=True)
207 _fixBridgeFunc(BOOL,'selectTextRange',c_long,JOBJECT64,c_int,c_int,errcheck=True)
208 _fixBridgeFunc(BOOL,'getTextAttributesInRange',c_long,JOBJECT64,c_int,c_int,POINTER(AccessibleTextAttributesInfo),POINTER(c_short),errcheck=True)
209 _fixBridgeFunc(JOBJECT64,'getTopLevelObject',c_long,JOBJECT64,errcheck=True)
210 _fixBridgeFunc(c_int,'getObjectDepth',c_long,JOBJECT64)
211 _fixBridgeFunc(JOBJECT64,'getActiveDescendent',c_long,JOBJECT64)
212 _fixBridgeFunc(BOOL,'requestFocus',c_long,JOBJECT64,errcheck=True)
213 _fixBridgeFunc(BOOL,'setCaretPosition',c_long,JOBJECT64,c_int,errcheck=True)
214 _fixBridgeFunc(BOOL,'getCaretLocation',c_long,JOBJECT64,POINTER(AccessibleTextRectInfo),jint,errcheck=True)
215 _fixBridgeFunc(BOOL,'getAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActions),errcheck=True)
216 _fixBridgeFunc(BOOL,'doAccessibleActions',c_long,JOBJECT64,POINTER(AccessibleActionsToDo),POINTER(jint),errcheck=True)
217
218
219
220 isRunning=False
221 vmIDsToWindowHandles={}
222 internalFunctionQueue=Queue.Queue(1000)
223 internalFunctionQueue.__name__="JABHandler.internalFunctionQueue"
227
228 -class JABContext(object):
229
230 - def __init__(self,hwnd=None,vmID=None,accContext=None):
231 if hwnd and not vmID:
232 vmID=c_int()
233 accContext=JOBJECT64()
234 bridgeDll.getAccessibleContextFromHWND(hwnd,byref(vmID),byref(accContext))
235 vmID=vmID.value
236
237 vmIDsToWindowHandles[vmID]=hwnd
238 elif vmID and not hwnd:
239 hwnd=vmIDsToWindowHandles.get(vmID)
240 if not hwnd:
241 topAC=bridgeDll.getTopLevelObject(vmID,accContext)
242 hwnd=bridgeDll.getHWNDFromAccessibleContext(vmID,topAC)
243 bridgeDll.releaseJavaObject(vmID,topAC)
244
245 vmIDsToWindowHandles[vmID]=hwnd
246 self.hwnd=hwnd
247 self.vmID=vmID
248 self.accContext=accContext
249
251 if isRunning:
252 try:
253 bridgeDll.releaseJavaObject(self.vmID,self.accContext)
254 except:
255 log.debugWarning("Error releasing java object",exc_info=True)
256
257
258 - def __eq__(self,jabContext):
259 if self.vmID==jabContext.vmID and bridgeDll.isSameObject(self.vmID,self.accContext,jabContext.accContext):
260 return True
261 else:
262 return False
263
264 - def __ne__(self,jabContext):
265 if self.vmID!=jabContext.vmID or not bridgeDll.isSameObject(self.vmID,self.accContext,jabContext.accContext):
266 return True
267 else:
268 return False
269
270 - def getVersionInfo(self):
274
279
281 textInfo=AccessibleTextInfo()
282 bridgeDll.getAccessibleTextInfo(self.vmID,self.accContext,byref(textInfo),x,y)
283 return textInfo
284
286 textItemsInfo=AccessibleTextItemsInfo()
287 bridgeDll.getAccessibleTextItems(self.vmID,self.accContext,byref(textItemsInfo),index)
288 return textItemsInfo
289
291 textSelectionInfo=AccessibleTextSelectionInfo()
292 bridgeDll.getAccessibleTextSelectionInfo(self.vmID,self.accContext,byref(textSelectionInfo))
293 return textSelectionInfo
294
296 length=((end+1)-start)
297 if length<=0:
298 return "\n"
299 text=create_unicode_buffer(length+1)
300 bridgeDll.getAccessibleTextRange(self.vmID,self.accContext,start,end,text,length)
301 return text.value
302
304 index=max(index,0)
305 log.debug("lineBounds: index %s"%index)
306
307 startIndex=c_int()
308 endIndex=c_int()
309 bridgeDll.getAccessibleTextLineBounds(self.vmID,self.accContext,index,byref(startIndex),byref(endIndex))
310 start=startIndex.value
311 end=endIndex.value
312 log.debug("line bounds: start %s, end %s"%(start,end))
313 if end<start:
314
315 return (0,-1)
316 ok=False
317
318
319 while not ok:
320 bridgeDll.getAccessibleTextLineBounds(self.vmID,self.accContext,end,byref(startIndex),byref(endIndex))
321 tempStart=max(startIndex.value,0)
322 tempEnd=max(endIndex.value,0)
323 log.debug("line bounds: tempStart %s, tempEnd %s"%(tempStart,tempEnd))
324 if tempStart>(index+1):
325
326 end=tempStart-1
327 else:
328 ok=True
329 ok=False
330
331 while not ok:
332 bridgeDll.getAccessibleTextLineBounds(self.vmID,self.accContext,start,byref(startIndex),byref(endIndex))
333 tempStart=max(startIndex.value,0)
334 tempEnd=max(endIndex.value,0)
335 log.debug("line bounds: tempStart %s, tempEnd %s"%(tempStart,tempEnd))
336 if tempEnd<(index-1):
337
338 start=tempEnd+1
339 else:
340 ok=True
341 log.debug("line bounds: returning %s, %s"%(start,end))
342 return (start,end)
343
344
346 accContext=bridgeDll.getAccessibleParentFromContext(self.vmID,self.accContext)
347 if accContext:
348 return self.__class__(self.hwnd,self.vmID,accContext)
349 else:
350 return None
351
353 accContext=bridgeDll.getAccessibleChildFromContext(self.vmID,self.accContext,index)
354 if accContext:
355 return self.__class__(self.hwnd,self.vmID,accContext)
356 else:
357 return None
358
360 accContext=bridgeDll.getActiveDescendent(self.vmID,self.accContext)
361 if accContext:
362 return self.__class__(self.hwnd,self.vmID,accContext)
363 else:
364 return None
365
367 newAccContext=JOBJECT64()
368 res=bridgeDll.getAccessibleContextAt(self.vmID,self.accContext,x,y,byref(newAccContext))
369 if not res or not newAccContext:
370 return None
371 if not bridgeDll.isSameObject(self.vmID,newAccContext,self.accContext):
372 return self.__class__(self.hwnd,self.vmID,newAccContext)
373 elif newAccContext!=self.accContext:
374 bridgeDll.releaseJavaObject(self.vmID,newAccContext)
375 return None
376
378 buf=create_unicode_buffer(SHORT_STRING_SIZE+1)
379 bridgeDll.getCurrentAccessibleValueFromContext(self.vmID,self.accContext,buf,SHORT_STRING_SIZE)
380 return buf.value
381
384
385 - def setCaretPosition(self,offset):
386 bridgeDll.setCaretPosition(self.vmID,self.accContext,offset)
387
388 - def getTextAttributesInRange(self, startIndex, endIndex):
389 attributes = AccessibleTextAttributesInfo()
390 length = c_short()
391 bridgeDll.getTextAttributesInRange(self.vmID, self.accContext, startIndex, endIndex, byref(attributes), byref(length))
392 return attributes, length.value
393
395 relations = AccessibleRelationSetInfo()
396 bridgeDll.getAccessibleRelationSet(self.vmID, self.accContext, byref(relations))
397 return relations
398
403
430
436
441
461
467
481
486
506
510
527