def _getControlVersion(self):
     res = watchdog.cancellableSendMessage(self.windowHandle,
                                           AEM_CONTROLVERSION, None, None)
     major = winUser.LOBYTE(winUser.LOWORD(res))
     minor = winUser.HIBYTE(winUser.LOWORD(res))
     version = major + (0.1 * minor)
     return version
Exemple #2
0
 def inputTouchWndProc(self, hwnd, msg, wParam, lParam):
     if msg >= _WM_POINTER_FIRST and msg <= _WM_POINTER_LAST:
         flags = winUser.HIWORD(wParam)
         touching = (flags & POINTER_MESSAGE_FLAG_INRANGE) and (
             flags & POINTER_MESSAGE_FLAG_FIRSTBUTTON)
         x = winUser.LOWORD(lParam)
         y = winUser.HIWORD(lParam)
         ID = winUser.LOWORD(wParam)
         if touching:
             self.trackerManager.update(ID, x, y, False)
         elif not flags & POINTER_MESSAGE_FLAG_FIRSTBUTTON:
             self.trackerManager.update(ID, x, y, True)
         return 0
     return windll.user32.DefWindowProcW(hwnd, msg, wParam, lParam)
Exemple #3
0
def consoleWinEventHook(handle,eventID,window,objectID,childID,threadID,timestamp):
	#We don't want to do anything with the event if the event is not for the window this console is in
	if window!=consoleObject.windowHandle:
		return
	if eventID==winUser.EVENT_CONSOLE_CARET and not eventHandler.isPendingEvents("caret",consoleObject):
		eventHandler.queueEvent("caret",consoleObject)
	# It is safe to call this event from this callback.
	# This avoids an extra core cycle.
	consoleObject.event_textChange()
	if eventID==winUser.EVENT_CONSOLE_UPDATE_SIMPLE:
		x=winUser.LOWORD(objectID)
		y=winUser.HIWORD(objectID)
		consoleScreenBufferInfo=wincon.GetConsoleScreenBufferInfo(consoleOutputHandle)
		if x<consoleScreenBufferInfo.dwCursorPosition.x and (y==consoleScreenBufferInfo.dwCursorPosition.y or y==consoleScreenBufferInfo.dwCursorPosition.y+1):  
			eventHandler.queueEvent("typedCharacter",consoleObject,ch=unichr(winUser.LOWORD(childID)))
Exemple #4
0
 def _getPointFromOffset(self, offset):
     if self.obj.editAPIVersion == 1 or self.obj.editAPIVersion >= 3:
         processHandle = self.obj.processHandle
         internalP = winKernel.virtualAllocEx(processHandle, None,
                                              ctypes.sizeof(PointLStruct),
                                              winKernel.MEM_COMMIT,
                                              winKernel.PAGE_READWRITE)
         try:
             p = PointLStruct(0, 0)
             winKernel.writeProcessMemory(processHandle, internalP,
                                          ctypes.byref(p), ctypes.sizeof(p),
                                          None)
             watchdog.cancellableSendMessage(self.obj.windowHandle,
                                             EM_POSFROMCHAR, internalP,
                                             offset)
             winKernel.readProcessMemory(processHandle, internalP,
                                         ctypes.byref(p), ctypes.sizeof(p),
                                         None)
         finally:
             winKernel.virtualFreeEx(processHandle, internalP, 0,
                                     winKernel.MEM_RELEASE)
         point = textInfos.Point(p.x, p.y)
     else:
         res = watchdog.cancellableSendMessage(self.obj.windowHandle,
                                               EM_POSFROMCHAR, offset, None)
         point = textInfos.Point(winUser.LOWORD(res), winUser.HIWORD(res))
     (left, top, width, height) = self.obj.location
     point.x = point.x + left
     point.y = point.y + top
     return point
Exemple #5
0
	def _getOffsetFromPoint(self,x,y):
		x, y = winUser.ScreenToClient(self.obj.windowHandle, x, y)
		if self.obj.editAPIVersion>=1:
			processHandle=self.obj.processHandle
			internalP=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(PointLStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
			try:
				p=PointLStruct(x,y)
				winKernel.writeProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
				offset=watchdog.cancellableSendMessage(self.obj.windowHandle,winUser.EM_CHARFROMPOS,0,internalP)
			finally:
				winKernel.virtualFreeEx(processHandle,internalP,0,winKernel.MEM_RELEASE)
		else:
			p=x+(y<<16)
			res=watchdog.cancellableSendMessage(self.obj.windowHandle,winUser.EM_CHARFROMPOS,0,p)
			offset=winUser.LOWORD(res)
			lineNum=winUser.HIWORD(res)
			if offset==0xFFFF and lineNum==0xFFFF:
				raise LookupError("Point outside client area")
			if self._getStoryLength() > 0xFFFF:
				# Returned offsets are 16 bits, therefore for large documents, we need to make sure that the correct offset is returned.
				# We can calculate this by using the start offset of the line with the retrieved line number.
				lineStart=watchdog.cancellableSendMessage(self.obj.windowHandle,winUser.EM_LINEINDEX,lineNum,0)
				# Get the last 16 bits of the line number
				lineStart16=lineStart&0xFFFF
				if lineStart16 > offset:
					# There are cases where the last 16 bits of the line start are greater than the
					# 16 bits offset. For example, this happens when the line start offset is 65534 (0xFFFE)
					# and the offset we need ought to be 65537 (0x10001), which is a 17 bits number
					# In that case, add 0x10000 to the offset, which will make the eventual formula return the correct offset,
					# unless a line has more than 65535 characters, in which case we can't get a reliable offset.
					offset+=0x10000
				offset = (offset - lineStart16) + lineStart
		return offset
def initialize():
	global _remoteLib, _remoteLoader64, localLib, generateBeep, VBuf_getTextInRange, lastLanguageID, lastLayoutString
	hkl=c_ulong(windll.User32.GetKeyboardLayout(0)).value
	lastLanguageID=winUser.LOWORD(hkl)
	KL_NAMELENGTH=9
	buf=create_unicode_buffer(KL_NAMELENGTH)
	res=windll.User32.GetKeyboardLayoutNameW(buf)
	if res:
		lastLayoutString=buf.value
	localLib=cdll.LoadLibrary(os.path.join(versionedLibPath,'nvdaHelperLocal.dll'))
	for name,func in [
		("nvdaController_speakText",nvdaController_speakText),
		("nvdaController_cancelSpeech",nvdaController_cancelSpeech),
		("nvdaController_brailleMessage",nvdaController_brailleMessage),
		("nvdaControllerInternal_requestRegistration",nvdaControllerInternal_requestRegistration),
		("nvdaControllerInternal_inputLangChangeNotify",nvdaControllerInternal_inputLangChangeNotify),
		("nvdaControllerInternal_typedCharacterNotify",nvdaControllerInternal_typedCharacterNotify),
		("nvdaControllerInternal_displayModelTextChangeNotify",nvdaControllerInternal_displayModelTextChangeNotify),
		("nvdaControllerInternal_logMessage",nvdaControllerInternal_logMessage),
		("nvdaControllerInternal_inputCompositionUpdate",nvdaControllerInternal_inputCompositionUpdate),
		("nvdaControllerInternal_inputCandidateListUpdate",nvdaControllerInternal_inputCandidateListUpdate),
		("nvdaControllerInternal_IMEOpenStatusUpdate",nvdaControllerInternal_IMEOpenStatusUpdate),
		("nvdaControllerInternal_inputConversionModeUpdate",nvdaControllerInternal_inputConversionModeUpdate),
		("nvdaControllerInternal_vbufChangeNotify",nvdaControllerInternal_vbufChangeNotify),
		("nvdaControllerInternal_installAddonPackageFromPath",nvdaControllerInternal_installAddonPackageFromPath),
		("nvdaControllerInternal_drawFocusRectNotify",nvdaControllerInternal_drawFocusRectNotify),
	]:
		try:
			_setDllFuncPointer(localLib,"_%s"%name,func)
		except AttributeError as e:
			log.error("nvdaHelperLocal function pointer for %s could not be found, possibly old nvdaHelperLocal dll"%name,exc_info=True)
			raise e
	localLib.nvdaHelperLocal_initialize()
	generateBeep=localLib.generateBeep
	generateBeep.argtypes=[c_char_p,c_float,c_int,c_int,c_int]
	generateBeep.restype=c_int
	# The rest of this function (to do with injection) only applies if NVDA is not running as a Windows store application
	# Handle VBuf_getTextInRange's BSTR out parameter so that the BSTR will be freed automatically.
	VBuf_getTextInRange = CFUNCTYPE(c_int, c_int, c_int, c_int, POINTER(BSTR), c_int)(
		("VBuf_getTextInRange", localLib),
		((1,), (1,), (1,), (2,), (1,)))
	if config.isAppX:
		log.info("Remote injection disabled due to running as a Windows Store Application")
		return
	#Load nvdaHelperRemote.dll but with an altered search path so it can pick up other dlls in lib
	h=windll.kernel32.LoadLibraryExW(os.path.abspath(os.path.join(versionedLibPath,u"nvdaHelperRemote.dll")),0,0x8)
	if not h:
		log.critical("Error loading nvdaHelperRemote.dll: %s" % WinError())
		return
	_remoteLib=CDLL("nvdaHelperRemote",handle=h)
	if _remoteLib.injection_initialize(globalVars.appArgs.secure) == 0:
		raise RuntimeError("Error initializing NVDAHelperRemote")
	if not _remoteLib.installIA2Support():
		log.error("Error installing IA2 support")
	#Manually start the in-process manager thread for this NVDA main thread now, as a slow system can cause this action to confuse WX
	_remoteLib.initInprocManagerThreadIfNeeded()
	if os.environ.get('PROCESSOR_ARCHITEW6432') in ('AMD64', 'ARM64'):
		_remoteLoader64=RemoteLoader64()
Exemple #7
0
		def handleScreenOrientationChange(self, lParam):
			import ui
			import winUser
			# Resolution detection comes from an article found at https://msdn.microsoft.com/en-us/library/ms812142.aspx.
			#The low word is the width and hiword is height.
			width = winUser.LOWORD(lParam)
			height = winUser.HIWORD(lParam)
			self.orientationCoordsCache = (width,height)
			if width > height:
				# If the height and width are the same, it's actually a screen flip, and we do want to alert of those!
				if self.orientationStateCache == self.ORIENTATION_LANDSCAPE and self.orientationCoordsCache != (width,height):
					return
				#Translators: The screen is oriented so that it is wider than it is tall.
				ui.message(_("Landscape" ))
				self.orientationStateCache = self.ORIENTATION_LANDSCAPE
			else:
				if self.orientationStateCache == self.ORIENTATION_PORTRAIT and self.orientationCoordsCache != (width,height):
					return
				#Translators: The screen is oriented in such a way that the height is taller than it is wide.
				ui.message(_("Portrait"))
				self.orientationStateCache = self.ORIENTATION_PORTRAIT
def nvdaControllerInternal_inputLangChangeNotify(threadID, hkl, layoutString):
    global lastLanguageID, lastLayoutString
    languageID = winUser.LOWORD(hkl)
    #Simple case where there is no change
    if languageID == lastLanguageID and layoutString == lastLayoutString:
        return 0
    focus = api.getFocusObject()
    #This callback can be called before NVDa is fully initialized
    #So also handle focus object being None as well as checking for sleepMode
    if not focus or focus.sleepMode:
        return 0
    import NVDAObjects.window
    #Generally we should not allow input lang changes from threads that are not focused.
    #But threadIDs for console windows are always wrong so don't ignore for those.
    if not isinstance(focus, NVDAObjects.window.Window) or (
            threadID != focus.windowThreadID
            and focus.windowClassName != "ConsoleWindowClass"):
        return 0
    import sayAllHandler
    #Never announce changes while in sayAll (#1676)
    if sayAllHandler.isRunning():
        return 0
    import queueHandler
    import ui
    buf = create_unicode_buffer(1024)
    res = windll.kernel32.GetLocaleInfoW(languageID, 2, buf, 1024)
    # Translators: the label for an unknown language when switching input methods.
    inputLanguageName = buf.value if res else _("unknown language")
    layoutStringCodes = []
    inputMethodName = None
    #layoutString can either be a real input method name, a hex string for an input method name in the registry, or an empty string.
    #If it is a real input method name, then it is used as is.
    #If it is a hex string or it is empty, then the method name is looked up by trying:
    #The full hex string, the hkl as a hex string, the low word of the hex string or hkl, the high word of the hex string or hkl.
    if layoutString:
        try:
            int(layoutString, 16)
            layoutStringCodes.append(layoutString)
        except ValueError:
            inputMethodName = layoutString
    if not inputMethodName:
        layoutStringCodes.insert(
            0,
            hex(hkl)[2:].rstrip('L').upper().rjust(8, '0'))
        for stringCode in list(layoutStringCodes):
            layoutStringCodes.append(stringCode[4:].rjust(8, '0'))
            if stringCode[0] < 'D':
                layoutStringCodes.append(stringCode[0:4].rjust(8, '0'))
        for stringCode in layoutStringCodes:
            inputMethodName = _lookupKeyboardLayoutNameWithHexString(
                stringCode)
            if inputMethodName: break
    if not inputMethodName:
        log.debugWarning(
            "Could not find layout name for keyboard layout, reporting as unknown"
        )
        # Translators: The label for an unknown input method when switching input methods.
        inputMethodName = _("unknown input method")
    #Remove the language name if it is in the input method name.
    if ' - ' in inputMethodName:
        inputMethodName = "".join(inputMethodName.split(' - ')[1:])
    #Include the language only if it changed.
    if languageID != lastLanguageID:
        msg = u"{language} - {layout}".format(language=inputLanguageName,
                                              layout=inputMethodName)
    else:
        msg = inputMethodName
    lastLanguageID = languageID
    lastLayoutString = layoutString
    queueHandler.queueFunction(queueHandler.eventQueue, ui.message, msg)
    return 0