Esempio n. 1
0
def _doConfigUpgrade(profile, fromVersion):
	toVersion = fromVersion+1
	upgradeStepName = "upgradeConfigFrom_{0}_to_{1}".format(fromVersion, toVersion)
	upgradeStepFunc = getattr(profileUpgradeSteps, upgradeStepName)
	log.debug("Upgrading from schema version {0} to {1}".format(fromVersion, toVersion))
	upgradeStepFunc(profile)
	profile[SCHEMA_VERSION_KEY] = toVersion
Esempio n. 2
0
def update(obj, force=False):
	# Don't create treeInterceptors for objects for which NVDA should sleep.
	if obj.sleepMode:
		return None
	#If this object already has a treeInterceptor, just return that and don't bother trying to create one
	ti=obj.treeInterceptor
	if not ti:
		if not obj.shouldCreateTreeInterceptor and not force:
			return None
		try:
			newClass=obj.treeInterceptorClass
		except NotImplementedError:
			return None
		if not force and (
			not config.conf['virtualBuffers']['enableOnPageLoad'] or
			getattr(obj.appModule, "disableBrowseModeByDefault", False)
		):
			# Import late to avoid circular import.
			from browseMode import BrowseModeTreeInterceptor
			# Disabling enableOnPageLoad should only affect browse mode tree interceptors.
			if issubclass(newClass, BrowseModeTreeInterceptor):
				return None
		ti=newClass(obj)
		if not ti.isAlive:
			return None
		runningTable.add(ti)
		log.debug("Adding new treeInterceptor to runningTable: %s"%ti)
	if ti.shouldPrepare:
		ti.prepare()
	return ti
Esempio n. 3
0
	def _onReceive(self, data):
		if self.isBulk:
			# data contains the entire packet.
			stream = StringIO(data)
			firstByte=data[0]
			stream.seek(1)
		else:
			firstByte = data
			# data only contained the first byte. Read the rest from the device.
			stream = self._dev
		if firstByte=="\x1c":
			# A device is identifying itself
			deviceId=stream.read(2)
			# When a device identifies itself, the packets ends with 0x1f
			assert stream.read(1) == "\x1f"
			self._handleIdentification(deviceId)
		elif firstByte=="\xfa":
			# Command packets are ten bytes long
			packet=firstByte+stream.read(9)
			assert packet[2] == "\x01" # Fixed value
			checksum=packet[8]
			assert packet[9] == "\xfb" # Command End
			assert(chr(sum(ord(c) for c in packet[0:8]+packet[9])&0xff)==checksum)
			self._handlePacket(packet)
		else:
			log.debug("Unknown first byte received: 0x%x"%ord(firstByte))
			return
Esempio n. 4
0
	def handleData(self, data):

		if data >= HEDO_CR_BEGIN and data <= HEDO_CR_END:
			# Routing key is pressed
			try:
				inputCore.manager.executeGesture(InputGestureRouting(data - HEDO_CR_BEGIN))
			except inputCore.NoInputGestureAction:
				log.debug("No Action for routing command")
				pass

		elif data >= (HEDO_CR_BEGIN + HEDO_RELEASE_OFFSET) and data <= (HEDO_CR_END + HEDO_RELEASE_OFFSET):
			# Routing key is released
			return

		elif data in HEDO_KEYMAP:
			# A key is pressed
			# log.debug("Key " + HEDO_KEYMAP[data] + " pressed")
			self._keysDown.add(HEDO_KEYMAP[data])
			self._ignoreKeyReleases = False

		elif data > HEDO_RELEASE_OFFSET and (data - HEDO_RELEASE_OFFSET) in HEDO_KEYMAP:
			# A key is released
			# log.debug("Key " + str(self._keysDown) + " released")
			if self._ignoreKeyReleases == False:
				keys = "+".join(self._keysDown)
				self._ignoreKeyReleases = True
				self._keysDown = set()
				try:
					inputCore.manager.executeGesture(InputGestureKeys(keys))
				except inputCore.NoInputGestureAction:
					log.debug("No Action for keys {keys}".format(keys=keys))
					pass
Esempio n. 5
0
	def _sendIdentificationRequests(self, match):
		log.debug("Considering sending identification requests for device %s"%str(match))
		if match.type==bdDetect.KEY_CUSTOM: # USB Bulk
			map=[modelTuple for modelTuple in modelMap if modelTuple[1].usbId==match.id]
		elif "bluetoothName" in match.deviceInfo: # Bluetooth
			map=[modelTuple for modelTuple in modelMap if modelTuple[1].bluetoothPrefix and match.id.startswith(modelTuple[1].bluetoothPrefix)]
		else: # The only serial device we support which is not bluetooth, is a Sync Braille
			self._model = SyncBraille()
			log.debug("Use %s as model without sending an additional identification request"%self._model.name)
			return
		if not map:
			log.debugWarning("The provided device match to send identification requests didn't yield any results")
			map = modelMap
		if len(map)==1:
			modelCls = map[0][1]
			numCells = self.numCells or modelCls.numCells
			if numCells:
				# There is only one model matching the criteria, and we have the proper number of cells.
				# There's no point in sending an identification request at all, just use this model
				log.debug("Use %s as model without sending an additional identification request"%modelCls.name)
				self._model = modelCls()
				self.numCells = numCells
				return
		self._model = None
		for id, cls in map:
			log.debug("Sending request for id %r"%id)
			self._dev.write("\x1c{id}\x1f".format(id=id))
			self._dev.waitForRead(self.timeout)
			if self._model:
				log.debug("%s model has been set"%self._model.name)
				break
Esempio n. 6
0
	def addToPackagePath(self, package):
		""" Adds this L{Addon} extensions to the specific package path if those exist.
		This allows the addon to "run" / be available because the package is able to search its path,
		looking for particular modules. This is used by the following:
		- `globalPlugins`
		- `appModules`
		- `synthDrivers`
		- `brailleDisplayDrivers`
		@param package: the python module representing the package.
		@type package: python module.
		"""
		# #3090: Ensure that we don't add disabled / blocked add-ons to package path.
		# By returning here the addon does not "run"/ become active / registered.
		if self.isDisabled or self.isBlocked:
			return

		extension_path = os.path.join(self.path, package.__name__)
		if not os.path.isdir(extension_path):
			# This addon does not have extension points for this package
			return
		# Python 2.x doesn't properly handle unicode import paths, so convert them before adding.
		converted_path = self._getPathForInclusionInPackage(package)
		package.__path__.insert(0, converted_path)
		self._extendedPackages.add(package)
		log.debug("Addon %s added to %s package path", self.manifest['name'], package.__name__)
Esempio n. 7
0
	def completeRemove(self,runUninstallTask=True):
		if runUninstallTask:
			try:
				# #2715: The add-on must be added to _availableAddons here so that
				# translations can be used in installTasks module.
				_availableAddons[self.path] = self
				self.runInstallTask("onUninstall")
			except:
				log.error("task 'onUninstall' on addon '%s' failed"%self.name,exc_info=True)
			finally:
				del _availableAddons[self.path]
		tempPath=tempfile.mktemp(suffix=DELETEDIR_SUFFIX,dir=os.path.dirname(self.path))
		try:
			os.rename(self.path,tempPath)
		except (WindowsError,IOError):
			raise RuntimeError("Cannot rename add-on path for deletion")
		shutil.rmtree(tempPath,ignore_errors=True)
		if os.path.exists(tempPath):
			log.error("Error removing addon directory %s, deferring until next NVDA restart"%self.path)
		# clean up the addons state. If an addon with the same name is installed, it should not be automatically
		# disabled / blocked.
		log.debug("removing addon {} from _disabledAddons/_blockedAddons".format(self.name))
		_disabledAddons.discard(self.name)
		_blockedAddons.discard(self.name)
		saveState()
Esempio n. 8
0
	def cancel(self):
		# Set a flag to tell the callback not to push more audio.
		self._wasCancelled = True
		log.debug("Cancelling")
		# There might be more text pending. Throw it away.
		self._queuedSpeech = []
		self._player.stop()
Esempio n. 9
0
def killTreeInterceptor(treeInterceptorObject):
	try:
		runningTable.remove(treeInterceptorObject)
	except KeyError:
		return
	treeInterceptorObject.terminate()
	log.debug("Killed treeInterceptor: %s" % treeInterceptorObject)
Esempio n. 10
0
	def loadSettings(self, onlyChanged=False):
		# Method override due to specific logic needed when changing a voice.
		c=config.conf[self._configSection][self.name]
		if self.isSupported("voice"):
			voice=c.get("voice",None)
			if not onlyChanged or self.voice!=voice:
				try:
					changeVoice(self,voice)
				except:
					log.warning("Invalid voice: %s" % voice)
					# Update the configuration with the correct voice.
					c["voice"]=self.voice
					# We need to call changeVoice here so that required initialisation can be performed.
					changeVoice(self,self.voice)
		elif not onlyChanged:
			changeVoice(self,None)
		for s in self.supportedSettings:
			if s.id == "voice" or c[s.id] is None:
				continue
			val=c[s.id]
			if onlyChanged and getattr(self,s.id)==val:
				continue
			setattr(self,s.id, val)
		log.debug(
			(
				"Loaded changed settings for SynthDriver {}"
				if onlyChanged else
				"Loaded settings for SynthDriver {}"
			).format(self.name))
Esempio n. 11
0
	def _onReceive(self, data):
		"""Event handler when data from the display is received

		Formats a packet of four bytes in a packet type and three arguments.
		If the packet is known to have a payload, this is also fetched and the checksum is verified.
		The constructed packet is handed off to L{_handlePacket}.
		"""
		if self.isUsb:
			data = BytesIO(data)
			packetType = data.read(1)
		else:
			packetType = data
			data = self._dev

		arg1 = data.read(1)
		arg2 = data.read(1)
		arg3 = data.read(1)
		log.debug("Got packet of type %r with args: %r %r %r", packetType, arg1, arg2, arg3)
		# Info and extended key responses are the only packets with payload and checksum
		if packetType in (FS_PKT_INFO, FS_PKT_EXT_KEY):
			length = ord(arg1)
			payload = data.read(length)
			checksum = ord(data.read(1))
			calculatedChecksum = BrailleDisplayDriver._calculateChecksum(packetType + arg1 + arg2 + arg3 + payload)
			assert calculatedChecksum == checksum, "Checksum mismatch, expected %s but got %s" % (checksum, payload[-1])
		else:
			payload = FS_DATA_EMPTY

		self._handlePacket(packetType, arg1, arg2, arg3, payload)
Esempio n. 12
0
	def getAudioSelectionParsed(self):
		# Get marker positions and selection duration.
		# Return the list of substrings to be handled by individual scripts.
		audioSelectionParsed = self.getAudioSelection().split()
		if globalVars.appArgs.debugLogging:
			log.debug("GWV: parsed status bar length: %s"%len(audioSelectionParsed))
		return audioSelectionParsed
Esempio n. 13
0
def getWindowScalingFactor(window):
	"""Gets the logical scaling factor used for the given window handle. This is based off the Dpi reported by windows
	for the given window handle / divided by the "base" DPI level of 96. Typically this is a result of using the scaling
	percentage in the windows display settings. 100% is typically 96 DPI, 150% is typically 144 DPI.
	@param window: a native Windows window handle (hWnd)
	@returns the logical scaling factor. EG. 1.0 if the window DPI level is 96, 1.5 if the window DPI level is 144"""
	user32 = ctypes.windll.user32
	try:
		winDpi = user32.GetDpiForWindow(window)
	except:
		log.debug("GetDpiForWindow failed, using GetDeviceCaps instead")
		dc = user32.GetDC(window)
		winDpi = ctypes.windll.gdi32.GetDeviceCaps(dc, LOGPIXELSX)
		ret = user32.ReleaseDC(window, dc)
		if ret != 1:
			log.error("Unable to release the device context.")

	# For GetDpiForWindow: an invalid hwnd value will result in a return value of 0.
	# There is little information about what GetDeviceCaps does in the case of a failure for LOGPIXELSX, however,
	# a value of zero is certainly an error.
	if winDpi <= 0:
		log.debugWarning("Failed to get the DPI for the window, assuming a "
		                 "DPI of {} and using a scaling of 1.0. The hWnd value "
		                 "used was: {}".format(DEFAULT_DPI_LEVEL, window))
		return 1.0

	return winDpi / DEFAULT_DPI_LEVEL
Esempio n. 14
0
	def _getColumnContent(self, column):
		children = UIA._get_children(self)
		try:
			return children[column - 1].firstChild.name
		except Exception as e:
			log.debug(e)
		return ""
Esempio n. 15
0
	def _handleResponse(self, command, arg):
		if command == BAUM_CELL_COUNT:
			self.numCells = ord(arg)
		elif command == BAUM_DEVICE_ID:
			self._deviceID = arg

		elif command in KEY_NAMES:
			arg = sum(ord(byte) << offset * 8 for offset, byte in enumerate(arg))
			if arg < self._keysDown.get(command, 0):
				# Release.
				if not self._ignoreKeyReleases:
					# The first key released executes the key combination.
					try:
						inputCore.manager.executeGesture(InputGesture(self._keysDown))
					except inputCore.NoInputGestureAction:
						pass
					# Any further releases are just the rest of the keys in the combination being released,
					# so they should be ignored.
					self._ignoreKeyReleases = True
			else:
				# Press.
				# This begins a new key combination.
				self._ignoreKeyReleases = False
			self._keysDown[command] = arg

		elif command == BAUM_POWERDOWN:
			log.debug("Power down")
		elif command in (BAUM_COMMUNICATION_CHANNEL, BAUM_SERIAL_NUMBER):
			pass

		else:
			log.debugWarning("Unknown command {command!r}, arg {arg!r}".format(command=command, arg=arg))
Esempio n. 16
0
	def __init__(self, port="auto"):
		super(BrailleDisplayDriver, self).__init__()
		self._serial = None
		self._buffer = ""
		if port == "auto":
			portsToTry = itertools.chain(self._getUSBPorts(), self._getBluetoothPorts())
		elif port == "usb":
			portsToTry = self._getUSBPorts()
		elif port == "bluetooth":
			portsToTry = self._getBluetoothPorts()
		else:
			portsToTry = (port,)
		found = False
		for port in portsToTry:
			log.debug("Checking port %s for a BrailleNote", port)
			try:
				self._serial = serial.Serial(port, baudrate=BAUD_RATE, timeout=TIMEOUT, writeTimeout=TIMEOUT, parity=serial.PARITY_NONE)
			except serial.SerialException:
				continue
			# Check for cell information
			if self._describe():
				log.debug("BrailleNote found on %s with %d cells", port, self.numCells)
				found = True
				break
			else:
				self._serial.close()
		if not found:
			raise RuntimeError("Can't find a braillenote device (port = %s)" % port)
		# start reading keys
		self._readTimer = wx.PyTimer(self._readKeys)
		self._readTimer.Start(READ_INTERVAL)
Esempio n. 17
0
def initialize():
	global state, _stateFilename, autoChecker
	_stateFilename = os.path.join(globalVars.appArgs.configPath, "updateCheckState.pickle")
	try:
		state = cPickle.load(file(_stateFilename, "r"))
	except:
		log.debugWarning("Couldn't retrieve update state", exc_info=True)
		# Defaults.
		state = {
			"lastCheck": 0,
			"dontRemindVersion": None,
		}
		_setStateToNone(state)

	# check the pending version against the current version
	# and make sure that pendingUpdateFile and pendingUpdateVersion are part of the state dictionary.
	if "pendingUpdateVersion" not in state or state["pendingUpdateVersion"] == versionInfo.version:
		_setStateToNone(state)
	# remove all update files except the one that is currently pending (if any)
	try:
		for fileName in os.listdir(storeUpdatesDir):
			f=os.path.join(storeUpdatesDir, fileName)
			if f != state["pendingUpdateFile"]:
				os.remove(f)
				log.debug("Update file %s removed"%f)
	except OSError:
		log.warning("Unable to remove old update file %s"%f, exc_info=True)

	if not globalVars.appArgs.launcher and (config.conf["update"]["autoCheck"] or (config.conf["update"]["startupNotification"] and isPendingUpdate())):
		autoChecker = AutoUpdateChecker()
Esempio n. 18
0
	def __init__(self, port="auto"):
		super(BrailleDisplayDriver, self).__init__()
		self._serial = None
		if port == "auto":
			portsToTry = itertools.chain(self._getUSBPorts(), self._getBluetoothPorts())
		elif port == "usb":
			portsToTry = self._getUSBPorts()
		elif port == "bluetooth":
			portsToTry = self._getBluetoothPorts()
		else:
			portsToTry = (port,)
		for port in portsToTry:
			log.debug("Checking port %s for a BrailleNote", port)
			try:
				self._serial = hwIo.Serial(port, baudrate=BAUD_RATE, timeout=TIMEOUT, writeTimeout=TIMEOUT, parity=serial.PARITY_NONE, onReceive=self._onReceive)
			except EnvironmentError:
				continue
			# Check for cell information
			if self._describe():
				log.debug("BrailleNote found on %s with %d cells", port, self.numCells)
				break
			else:
				self._serial.close()
		else:
			raise RuntimeError("Can't find a braillenote device (port = %s)" % port)
Esempio n. 19
0
	def script_showSelectionOptions(self, gesture):
		fakeSel = self.selection
		if fakeSel.isCollapsed:
			# Double click to access the toolbar; e.g. for annotations.
			try:
				p = fakeSel.pointAtStart
			except NotImplementedError:
				log.debugWarning("Couldn't get point to click")
				return
			log.debug("Double clicking")
			winUser.setCursorPos(p.x, p.y)
			winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN, 0, 0, None, None)
			winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP, 0, 0, None, None)
			winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN, 0, 0, None, None)
			winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP, 0, 0, None, None)
			return

		# The user makes a selection using browse mode virtual selection.
		# Update the selection in Kindle.
		# This will cause the options to appear.
		fakeSel.innerTextInfo.updateSelection()
		# The selection might have been adjusted to meet word boundaries,
		# so retrieve and report the selection from Kindle.
		# we can't just use self.makeTextInfo, as that will use our fake selection.
		realSel = self.rootNVDAObject.makeTextInfo(textInfos.POSITION_SELECTION)
		# Translators: Announces selected text. %s is replaced with the text.
		speech.speakSelectionMessage(_("selected %s"), realSel.text)
		# Remove our virtual selection and move the caret to the active end.
		fakeSel.innerTextInfo = realSel
		fakeSel.collapse(end=not self._lastSelectionMovedStart)
		self.selection = fakeSel
Esempio n. 20
0
	def onContinue(self, evt):
		try:
			self.saveState()
		except:
			log.debug("unable to save state", exc_info=True)
		finally:
			self.EndModal(wx.OK)
Esempio n. 21
0
def FaultTolerantFile(name):
	'''Used to write out files in a more fault tolerant way. A temporary file is used, and replaces the 
	file `name' when the context manager scope ends and the the context manager __exit__ is called. This
	means writing out the complete file can be performed with less concern of corrupting the original file
	if the process is interrupted by windows shutting down.
	`name` must be unicode.

	Usage:
		with FaultTolerantFile("myFile.txt") as f:
			f.write("This is a test")

	This creates a temporary file, and the writes actually happen on this temp file. At the end of the 
	`with` block, when `f` goes out of context the temporary file is closed and, this temporary file replaces "myFile.txt"
	'''
	if not isinstance(name, text_type):
		raise TypeError("name must be an unicode string")
	dirpath, filename = os.path.split(name)
	with NamedTemporaryFile(dir=dirpath, prefix=filename, suffix='.tmp', delete=False) as f:
		log.debug(f.name)
		yield f
		f.flush()
		os.fsync(f)
		f.close()
		moveFileResult = ctypes.windll.kernel32.MoveFileExW(f.name, name, MOVEFILE_REPLACE_EXISTING)
		if moveFileResult == 0:
			raise ctypes.WinError()
Esempio n. 22
0
	def loadSettings(self, onlyChanged=False):
		"""
		Loads settings for this driver from the configuration.
		This method assumes that the instance has attributes o/properties
		corresponding with the name of every setting in L{supportedSettings}.
		@param onlyChanged: When loading settings, only apply those for which
			the value in the configuration differs from the current value.
		@type onlyChanged: bool
		"""
		conf=config.conf[self._configSection][self.name]
		for setting in self.supportedSettings:
			if not setting.useConfig or conf.get(setting.id) is None:
				continue
			val=conf[setting.id]
			if onlyChanged and getattr(self,setting.id) == val:
				continue
			try:
				setattr(self,setting.id, val)
			except UnsupportedConfigParameterError:
				log.debugWarning("Unsupported setting %s; ignoring"%setting.name, exc_info=True)
				continue
		if self.supportedSettings:
			log.debug(
				(
					"Loaded changed settings for {} {}"
					if onlyChanged else
					"Loaded settings for {} {}"
				).format(self.__class__.__name__, self.name))
	def event_typedCharacter(self, obj, nextHandler, ch):
		if lastKeyDownTime is None or (time.time() - lastKeyDownTime) >= 0.5 and ch != "":
			if obj.windowClassName != "ConsoleWindowClass":
				log.debug("typedCharacter %r %r" % (obj.windowClassName, ch))
				textInserted(obj.windowHandle, -1, ch)
			return
		nextHandler()
Esempio n. 24
0
	def _get_placeholder(self):
		"""If it exists for this object get the value of the placeholder text.
		For example this might be the aria-placeholder text for a field in a web page.
		@return: the placeholder text else None
		@rtype: String or None
		"""
		log.debug("Potential unimplemented child class: %r" %self)
		return None
Esempio n. 25
0
def registerGeneratorObject(generatorObj):
    global generators, lastGeneratorObjID
    if not isinstance(generatorObj, types.GeneratorType):
        raise TypeError("Arg 2 must be a generator object, not %s" % type(generatorObj))
    lastGeneratorObjID += 1
    log.debug("Adding generator %d" % lastGeneratorObjID)
    generators[lastGeneratorObjID] = generatorObj
    return lastGeneratorObjID
Esempio n. 26
0
	def _closeComPort(self):
		if self._readTimer is not None:
			self._readTimer.Stop()
			self._readTimer = None
		if self._serial is not None:
			log.debug("Closing port %s", self._serial.port)
			self._serial.close()
			self._serial = None
Esempio n. 27
0
	def close(self):
		if _isDebug():
			log.debug("Closing")
		self._onReceive = None
		if hasattr(self, "_file") and self._file is not INVALID_HANDLE_VALUE:
			ctypes.windll.kernel32.CancelIoEx(self._file, byref(self._readOl))
		if hasattr(self, "_writeFile") and self._writeFile not in (self._file, INVALID_HANDLE_VALUE):
			ctypes.windll.kernel32.CancelIoEx(self._writeFile, byref(self._readOl))
Esempio n. 28
0
def _terminate(module, name=None):
	if name is None:
		name = module.__name__
	log.debug("Terminating %s" % name)
	try:
		module.terminate()
	except:
		log.exception("Error terminating %s" % name)
Esempio n. 29
0
	def evaluateUpdatePendingUpdateMenuItemCommand(self):
		try:
			self.sysTrayIcon.menu.Remove(self.sysTrayIcon.installPendingUpdateMenuItem)
		except:
			log.debug("Error while removing  pending update menu item", exc_info=True)
			pass
		if not globalVars.appArgs.secure and updateCheck and updateCheck.isPendingUpdate():
			self.sysTrayIcon.menu.Insert(self.sysTrayIcon.installPendingUpdateMenuItemPos,self.sysTrayIcon.installPendingUpdateMenuItem)
Esempio n. 30
0
	def getAudioSelection(self):
		# Call the info getter twice to obtain audio selection (relies on display text).
		global multiInstance
		audioSelection = self.getStatusInfo(0, 2)
		if multiInstance > 1: audioSelection = self.getStatusInfo(0, 2)
		if globalVars.appArgs.debugLogging:
			log.debug("GWV: status bar length: %s"%len(audioSelection))
		return audioSelection
 def __init__(self, *args, **kwargs):
     super(GlobalPlugin, self).__init__(*args, **kwargs)
     log.debug("constructor")
     self.injectProcessing()
Esempio n. 32
0
def processForegroundWinEvent(window, objectID, childID):
	"""checks to see if the foreground win event is not the same as the existing focus or any of its parents,
	then converts the win event to an NVDA event (instantiating an NVDA Object) and then checks the NVDAObject
	against the existing focus object.
	If all is ok it queues the foreground event to NVDA and returns True.
	@param window: a win event's window handle
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@returns: True if the foreground was processed, False otherwise.
	@rtype: boolean
	"""
	if isMSAADebugLoggingEnabled():
		log.debug(
			f"Processing foreground winEvent: {getWinEventLogInfo(window, objectID, childID)}"
		)
	# Ignore foreground events on windows that aren't the current foreground window
	if window != winUser.getForegroundWindow():
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Dropping foreground winEvent as it does not match GetForegroundWindow. "
				f"WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		return False
	# If there is a pending gainFocus, it will handle the foreground object.
	oldFocus = eventHandler.lastQueuedFocusObject
	# If this foreground win event's window is an ancestor of the existing focus's window, then ignore it
	if (
		isinstance(oldFocus, NVDAObjects.window.Window)
		and winUser.isDescendantWindow(window, oldFocus.windowHandle)
	):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Dropping foreground winEvent as focus is already on a descendant. "
				f"WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		return False
	# If the existing focus has the same win event params as these, then ignore this event
	if (
		isinstance(oldFocus, NVDAObjects.IAccessible.IAccessible)
		and window == oldFocus.event_windowHandle
		and objectID == oldFocus.event_objectID
		and childID == oldFocus.event_childID
	):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Dropping foreground winEvent as it is duplicate to existing focus. "
				f"WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		return False
	# Notify appModuleHandler of this new foreground window
	appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
	# If Java access bridge is running, and this is a java window, then pass it to java and forget about it
	if JABHandler.isRunning and JABHandler.isJavaWindow(window):
		JABHandler.event_enterJavaWindow(window)
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Redirecting foreground winEvent to Java window. "
				f"WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		return True
	# Convert the win event to an NVDA event
	NVDAEvent = winEventToNVDAEvent(winUser.EVENT_SYSTEM_FOREGROUND, window, objectID, childID, useCache=False)
	if not NVDAEvent:
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Could not convert foreground winEvent to an NVDA event. "
				f"WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		return False
	eventHandler.queueEvent(*NVDAEvent)
	return True
    def _onReceive(self, data: bytes):
        byte1, stream, data = self._prepFirstByteStreamAndData(data)

        if byte1 == ACK:
            frame = ord(stream.read(1))
            self._handleAck(frame)
        elif byte1 == STX:
            length = bytesToInt(
                stream.read(2)) - 2  # length includes the length itself
            packet: bytes = stream.read(length)
            if self.isHid and not stream.read(1) == ETX:
                # Incomplete packet
                self._hidInputbuffer = data
                return
            packetType: bytes = packet[0:1]
            packetSubType: bytes = packet[1:2]
            packetData: bytes = packet[2:] if length > 2 else b""
            if packetType == EB_SYSTEM:
                self._handleSystemPacket(packetSubType, packetData)
            elif packetType == EB_MODE:
                if packetSubType == EB_MODE_DRIVER:
                    log.debug(
                        "Braille display switched to driver mode, updating display..."
                    )
                    braille.handler.update()
                elif packetSubType == EB_MODE_INTERNAL:
                    log.debug("Braille display switched to internal mode")
            elif packetType == EB_KEY:
                self._handleKeyPacket(packetSubType, packetData)
            elif packetType == EB_IRIS_TEST and packetSubType == EB_IRIS_TEST_sub:
                # Ping command sent by Iris every two seconds, send it back on the main thread.
                # This means that, if the main thread is frozen, Iris will be notified of this.
                log.debug("Received ping from Iris braille display")
                wx.CallAfter(self._sendPacket, packetType, packetSubType,
                             packetData)
            elif packetType == EB_VISU:
                log.debug("Ignoring visualisation packet")
            elif packetType == EB_ENCRYPTION_KEY:
                log.debug("Ignoring encryption key packet")
            else:
                log.debug("Ignoring packet: type %r, subtype %r, data %r" %
                          (packetType, packetSubType, packetData))
Esempio n. 34
0
    def handleData(self, data):
        if data >= HEDO_MOBIL_CR_BEGIN and data <= HEDO_MOBIL_CR_END:
            # Routing key is pressed
            try:
                inputCore.manager.executeGesture(
                    InputGestureRouting(data - HEDO_MOBIL_CR_BEGIN))
            except inputCore.NoInputGestureAction:
                log.debug("No Action for routing index " + index)
                pass
            return

        # On every keypress or keyrelease information about all keys is sent
        # There are three groups of keys thus three bytes will be sent on
        # each keypress or release
        # The 4 MSB of each byte mark the group
        # Bytes of the form 0x0? include information for B1 to B3
        # Bytes of the form 0x1? include information for B4 to B6
        # Bytes of the form 0x2? include information for K1 to K3
        # The 4 LSB mark the pressed buttons in the group
        # Are all buttons of one group released, the 4 LSB are zero
        if data & 0xF0 == 0x00:
            # B1..B3
            if data & 0x01:
                self._keysDown.add("B1")
            if data & 0x02:
                self._keysDown.add("B2")
            if data & 0x04:
                self._keysDown.add("B3")
            if data == 0x00:
                self._released_keys.add("B1")

        elif data & 0xF0 == 0x10:
            # B4..B6
            if data & 0x01:
                self._keysDown.add("B4")
            if data & 0x02:
                self._keysDown.add("B5")
            if data & 0x04:
                self._keysDown.add("B6")
            if data == 0x10:
                self._released_keys.add("B4")

        elif data & 0xF0 == 0x20:
            # K1..K3
            if data & 0x01:
                self._keysDown.add("K1")
            if data & 0x02:
                self._keysDown.add("K2")
            if data & 0x04:
                self._keysDown.add("K3")
            if data == 0x20:
                self._released_keys.add("K1")

        if "B1" in self._released_keys and "B4" in self._released_keys and "K1" in self._released_keys:
            # all keys are released
            keys = "+".join(self._keysDown)
            self._keysDown = set()
            self._released_keys = set()
            try:
                inputCore.manager.executeGesture(InputGestureKeys(keys))
            except inputCore.NoInputGestureAction:
                log.debug("No Action for keys " + keys)
                pass
Esempio n. 35
0
    def __init__(self, locale):
        """
		@param locale: The characterDescriptions.dic file will be found by using this locale.
		@type locale: string
		"""
        self._entries = {}
        fileName = os.path.join('locale', locale, 'characterDescriptions.dic')
        if not os.path.isfile(fileName):
            raise LookupError(fileName)
        f = codecs.open(fileName, "r", "utf_8_sig", errors="replace")
        for line in f:
            if line.isspace() or line.startswith('#'):
                continue
            line = line.rstrip('\r\n')
            temp = line.split("\t")
            if len(temp) > 1:
                key = temp.pop(0)
                self._entries[key] = temp
            else:
                log.warning("can't parse line '%s'" % line)
        log.debug("Loaded %d entries." % len(self._entries))
        f.close()

        # nvdajp charaters.dic
        self._readings = {}
        fileName = os.path.join('locale', locale, 'characters.dic')
        if os.path.isfile(fileName):
            f = codecs.open(fileName, "r", "utf_8_sig", errors="replace")
            for line in f:
                if line.isspace() or line.startswith('#'):
                    continue
                line = line.rstrip('\r\n')
                temp = line.split("\t")
                if len(temp) > 1:
                    key = temp.pop(0)
                    code = temp.pop(0)
                    rd = temp.pop(0)
                    if rd.startswith('[') and rd.endswith(']'):
                        self._readings[key] = rd[1:-1]
                    self._entries[key] = temp
                else:
                    log.warning("can't parse line '%s'" % line)
            log.debug("Loaded %d readings." % len(self._readings))
            f.close()
        # nvdajp charaters.dic end

        # nvdajp users chardesc
        fileName = os.path.join(globalVars.appArgs.configPath,
                                "characterDescriptions-%s.dic" % locale)
        if os.path.isfile(fileName):
            log.debug("Loading users characterDescriptions-%s.dic" % locale)
            f = codecs.open(fileName, "r", "utf_8_sig", errors="replace")
            for line in f:
                if line.isspace() or line.startswith('#'):
                    continue
                line = line.rstrip('\r\n')
                temp = line.split("\t")
                if len(temp) > 1:
                    key = temp.pop(0)
                    self._entries[key] = temp
                else:
                    log.warning("can't parse line '%s'" % line)
            log.debug("Loaded users characterDescriptions.")
            f.close()
        # nvdajp users chardesc end

        # nvdajp users characters
        fileName = os.path.join(globalVars.appArgs.configPath,
                                "characters-%s.dic" % locale)
        if os.path.isfile(fileName):
            f = codecs.open(fileName, "r", "utf_8_sig", errors="replace")
            for line in f:
                if line.isspace() or line.startswith('#'):
                    continue
                line = line.rstrip('\r\n')
                temp = line.split("\t")
                if len(temp) > 1:
                    key = temp.pop(0)
                    code = temp.pop(0)
                    rd = temp.pop(0)
                    if rd.startswith('[') and rd.endswith(']'):
                        self._readings[key] = rd[1:-1]
                    self._entries[key] = temp
                else:
                    log.warning("can't parse line '%s'" % line)
            log.debug("Loaded users characters.")
            f.close()
Esempio n. 36
0
def winEventToNVDAEvent(eventID, window, objectID, childID, useCache=True):
	"""Tries to convert a win event ID to an NVDA event name, and instanciate or fetch an NVDAObject for
	 the win event parameters.
	@param eventID: the win event ID (type)
	@type eventID: integer
	@param window: the win event's window handle
	@type window: integer
	@param objectID: the win event's object ID
	@type objectID: integer
	@param childID: the win event's childID
	@type childID: the win event's childID
	@param useCache: C{True} to use the L{liveNVDAObjectTable} cache when
	 retrieving an NVDAObject, C{False} if the cache should not be used.
	@type useCache: boolean
	@returns: the NVDA event name and the NVDAObject the event is for
	@rtype: tuple of string and L{NVDAObjects.IAccessible.IAccessible}
	"""
	if isMSAADebugLoggingEnabled():
		log.debug(
			f"Creating NVDA event from winEvent: {getWinEventLogInfo(window, objectID, childID, eventID)}, "
			f"use cache {useCache}"
		)
	NVDAEventName = internalWinEventHandler.winEventIDsToNVDAEventNames.get(eventID, None)
	if not NVDAEventName:
		log.debugWarning(f"No NVDA event name for {getWinEventName(eventID)}")
		return None
	if isMSAADebugLoggingEnabled():
		log.debug(f"winEvent mapped to NVDA event: {NVDAEventName}")
	# Ignore any events with invalid window handles
	if not window or not winUser.isWindow(window):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Invalid window. Dropping winEvent {getWinEventLogInfo(window, objectID, childID, eventID)}"
			)
		return None
	# Make sure this window does not have a ghost window if possible
	if NVDAObjects.window.GhostWindowFromHungWindow and NVDAObjects.window.GhostWindowFromHungWindow(window):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Ghosted hung window. Dropping winEvent {getWinEventLogInfo(window, objectID, childID, eventID)}"
			)
		return None
	# We do not support MSAA object proxied from native UIA
	if UIAHandler.handler and UIAHandler.handler.isUIAWindow(window):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Native UIA window. Dropping winEvent {getWinEventLogInfo(window, objectID, childID, eventID)}"
			)
		return None
	obj = None
	if useCache:
		# See if we already know an object by this win event info
		obj = liveNVDAObjectTable.get((window, objectID, childID), None)
		if isMSAADebugLoggingEnabled() and obj:
			log.debug(
				f"Fetched existing NVDAObject {obj} from liveNVDAObjectTable"
				f" for winEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
	# If we don't yet have the object, then actually instanciate it.
	if not obj:
		obj = NVDAObjects.IAccessible.getNVDAObjectFromEvent(window, objectID, childID)
	# At this point if we don't have an object then we can't do any more
	if not obj:
		if isMSAADebugLoggingEnabled():
			log.debug(
				"Could not instantiate an NVDAObject for winEvent: "
				f"{getWinEventLogInfo(window, objectID, childID, eventID)}"
			)
		return None
	# SDM MSAA objects sometimes don't contain enough information to be useful Sometimes there is a real
	# window that does, so try to get the SDMChild property on the NVDAObject, and if successull use that as
	# obj instead.
	if 'bosa_sdm' in obj.windowClassName:
		SDMChild = getattr(obj, 'SDMChild', None)
		if SDMChild:
			obj = SDMChild
	if isMSAADebugLoggingEnabled():
		log.debug(
			f"Successfully created NVDA event {NVDAEventName} for {obj} "
			f"from winEvent {getWinEventLogInfo(window, objectID, childID, eventID)}"
		)
	return (NVDAEventName, obj)
Esempio n. 37
0
def main():
	"""NVDA's core main loop.
This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI. Then it initialises the wx application object and sets up the core pump, which checks the queues and executes functions when requested. Finally, it starts the wx main loop.
"""
	log.debug("Core starting")

	ctypes.windll.user32.SetProcessDPIAware()

	import config
	if not globalVars.appArgs.configPath:
		globalVars.appArgs.configPath=config.getUserDefaultConfigPath(useInstalledPathIfExists=globalVars.appArgs.launcher)
	#Initialize the config path (make sure it exists)
	config.initConfigPath()
	log.info("Config dir: %s"%os.path.abspath(globalVars.appArgs.configPath))
	log.debug("loading config")
	import config
	config.initialize()
	if not globalVars.appArgs.minimal and config.conf["general"]["playStartAndExitSounds"]:
		try:
			nvwave.playWaveFile("waves\\start.wav")
		except:
			pass
	logHandler.setLogLevelFromConfig()
	try:
		lang = config.conf["general"]["language"]
		import languageHandler
		log.debug("setting language to %s"%lang)
		languageHandler.setLanguage(lang)
	except:
		log.warning("Could not set language to %s"%lang)
	import versionInfo
	log.info("NVDA version %s" % versionInfo.version)
	log.info("Using Windows version %s" % winVersion.winVersionText)
	log.info("Using Python version %s"%sys.version)
	log.info("Using comtypes version %s"%comtypes.__version__)
	import configobj
	log.info("Using configobj version %s with validate version %s"%(configobj.__version__,configobj.validate.__version__))
	# Set a reasonable timeout for any socket connections NVDA makes.
	import socket
	socket.setdefaulttimeout(10)
	log.debug("Initializing add-ons system")
	addonHandler.initialize()
	if globalVars.appArgs.disableAddons:
		log.info("Add-ons are disabled. Restart NVDA to enable them.")
	import appModuleHandler
	log.debug("Initializing appModule Handler")
	appModuleHandler.initialize()
	import NVDAHelper
	log.debug("Initializing NVDAHelper")
	NVDAHelper.initialize()
	import speechDictHandler
	log.debug("Speech Dictionary processing")
	speechDictHandler.initialize()
	import speech
	log.debug("Initializing speech")
	speech.initialize()
	if not globalVars.appArgs.minimal and (time.time()-globalVars.startTime)>5:
		log.debugWarning("Slow starting core (%.2f sec)" % (time.time()-globalVars.startTime))
		# Translators: This is spoken when NVDA is starting.
		speech.speakMessage(_("Loading NVDA. Please wait..."))
	import wx
	# wxPython 4 no longer has either of these constants (despite the documentation saying so), some add-ons may rely on
	# them so we add it back into wx. https://wxpython.org/Phoenix/docs/html/wx.Window.html#wx.Window.Centre
	wx.CENTER_ON_SCREEN = wx.CENTRE_ON_SCREEN = 0x2
	log.info("Using wx version %s"%wx.version())
	class App(wx.App):
		def OnAssert(self,file,line,cond,msg):
			message="{file}, line {line}:\nassert {cond}: {msg}".format(file=file,line=line,cond=cond,msg=msg)
			log.debugWarning(message,codepath="WX Widgets",stack_info=True)
	app = App(redirect=False)
	# We support queryEndSession events, but in general don't do anything for them.
	# However, when running as a Windows Store application, we do want to request to be restarted for updates
	def onQueryEndSession(evt):
		if config.isAppX:
			# Automatically restart NVDA on Windows Store update
			ctypes.windll.kernel32.RegisterApplicationRestart(None,0)
	app.Bind(wx.EVT_QUERY_END_SESSION, onQueryEndSession)
	def onEndSession(evt):
		# NVDA will be terminated as soon as this function returns, so save configuration if appropriate.
		config.saveOnExit()
		speech.cancelSpeech()
		if not globalVars.appArgs.minimal and config.conf["general"]["playStartAndExitSounds"]:
			try:
				nvwave.playWaveFile("waves\\exit.wav",async=False)
			except:
				pass
		log.info("Windows session ending")
	app.Bind(wx.EVT_END_SESSION, onEndSession)
	log.debug("Initializing braille input")
	import brailleInput
	brailleInput.initialize()
	import braille
	log.debug("Initializing braille")
	braille.initialize()
	import displayModel
	log.debug("Initializing displayModel")
	displayModel.initialize()
	log.debug("Initializing GUI")
	import gui
	gui.initialize()
	import audioDucking
	if audioDucking.isAudioDuckingSupported():
		# the GUI mainloop must be running for this to work so delay it
		wx.CallAfter(audioDucking.initialize)

	# #3763: In wxPython 3, the class name of frame windows changed from wxWindowClassNR to wxWindowNR.
	# NVDA uses the main frame to check for and quit another instance of NVDA.
	# To remain compatible with older versions of NVDA, create our own wxWindowClassNR.
	# We don't need to do anything else because wx handles WM_QUIT for all windows.
	import windowUtils
	class MessageWindow(windowUtils.CustomWindow):
		className = u"wxWindowClassNR"
		#Just define these constants here, so we don't have to import win32con
		WM_POWERBROADCAST = 0x218
		WM_DISPLAYCHANGE = 0x7e
		PBT_APMPOWERSTATUSCHANGE = 0xA
		UNKNOWN_BATTERY_STATUS = 0xFF
		AC_ONLINE = 0X1
		NO_SYSTEM_BATTERY = 0X80
		#States for screen orientation
		ORIENTATION_NOT_INITIALIZED = 0
		ORIENTATION_PORTRAIT = 1
		ORIENTATION_LANDSCAPE = 2

		def __init__(self, windowName=None):
			super(MessageWindow, self).__init__(windowName)
			self.oldBatteryStatus = None
			self.orientationStateCache = self.ORIENTATION_NOT_INITIALIZED
			self.orientationCoordsCache = (0,0)
			self.handlePowerStatusChange()

		def windowProc(self, hwnd, msg, wParam, lParam):
			post_windowMessageReceipt.notify(msg=msg, wParam=wParam, lParam=lParam)
			if msg == self.WM_POWERBROADCAST and wParam == self.PBT_APMPOWERSTATUSCHANGE:
				self.handlePowerStatusChange()
			elif msg == self.WM_DISPLAYCHANGE:
				self.handleScreenOrientationChange(lParam)

		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 handlePowerStatusChange(self):
			#Mostly taken from script_say_battery_status, but modified.
			import ui
			import winKernel
			sps = winKernel.SYSTEM_POWER_STATUS()
			if not winKernel.GetSystemPowerStatus(sps) or sps.BatteryFlag is self.UNKNOWN_BATTERY_STATUS:
				return
			if sps.BatteryFlag & self.NO_SYSTEM_BATTERY:
				return
			if self.oldBatteryStatus is None:
				#Just initializing the cache, do not report anything.
				self.oldBatteryStatus = sps.ACLineStatus
				return
			if sps.ACLineStatus == self.oldBatteryStatus:
				#Sometimes, this double fires. This also fires when the battery level decreases by 3%.
				return
			self.oldBatteryStatus = sps.ACLineStatus
			if sps.ACLineStatus & self.AC_ONLINE:
				#Translators: Reported when the battery is plugged in, and now is charging.
				ui.message(_("Charging battery. %d percent") % sps.BatteryLifePercent)
			else:
				#Translators: Reported when the battery is no longer plugged in, and now is not charging.
				ui.message(_("Not charging battery. %d percent") %sps.BatteryLifePercent)

	messageWindow = MessageWindow(unicode(versionInfo.name))

	# initialize wxpython localization support
	locale = wx.Locale()
	lang=languageHandler.getLanguage()
	wxLang=locale.FindLanguageInfo(lang)
	if not wxLang and '_' in lang:
		wxLang=locale.FindLanguageInfo(lang.split('_')[0])
	if hasattr(sys,'frozen'):
		locale.AddCatalogLookupPathPrefix(os.path.join(os.getcwdu(),"locale"))
	# #8064: Wx might know the language, but may not actually contain a translation database for that language.
	# If we try to initialize this language, wx will show a warning dialog.
	# Therefore treat this situation like wx not knowing the language at all.
	if not locale.IsAvailable(wxLang.Language):
		wxLang=None
	if wxLang:
		try:
			locale.Init(wxLang.Language)
		except:
			log.error("Failed to initialize wx locale",exc_info=True)
	else:
		log.debugWarning("wx does not support language %s" % lang)

	import api
	import winUser
	import NVDAObjects.window
	desktopObject=NVDAObjects.window.Window(windowHandle=winUser.getDesktopWindow())
	api.setDesktopObject(desktopObject)
	api.setFocusObject(desktopObject)
	api.setNavigatorObject(desktopObject)
	api.setMouseObject(desktopObject)
	import JABHandler
	log.debug("initializing Java Access Bridge support")
	try:
		JABHandler.initialize()
	except NotImplementedError:
		log.warning("Java Access Bridge not available")
	except:
		log.error("Error initializing Java Access Bridge support", exc_info=True)
	import winConsoleHandler
	log.debug("Initializing winConsole support")
	winConsoleHandler.initialize()
	import UIAHandler
	log.debug("Initializing UIA support")
	try:
		UIAHandler.initialize()
	except NotImplementedError:
		log.warning("UIA not available")
	except:
		log.error("Error initializing UIA support", exc_info=True)
	import IAccessibleHandler
	log.debug("Initializing IAccessible support")
	IAccessibleHandler.initialize()
	log.debug("Initializing input core")
	import inputCore
	inputCore.initialize()
	import keyboardHandler
	log.debug("Initializing keyboard handler")
	keyboardHandler.initialize()
	import mouseHandler
	log.debug("initializing mouse handler")
	mouseHandler.initialize()
	import touchHandler
	log.debug("Initializing touchHandler")
	try:
		touchHandler.initialize()
	except NotImplementedError:
		pass
	import globalPluginHandler
	log.debug("Initializing global plugin handler")
	globalPluginHandler.initialize()
	if globalVars.appArgs.install or globalVars.appArgs.installSilent:
		import gui.installerGui
		wx.CallAfter(gui.installerGui.doSilentInstall,startAfterInstall=not globalVars.appArgs.installSilent)
	elif globalVars.appArgs.portablePath and (globalVars.appArgs.createPortable or globalVars.appArgs.createPortableSilent):
		import gui.installerGui
		wx.CallAfter(gui.installerGui.doCreatePortable,portableDirectory=globalVars.appArgs.portablePath,
			silent=globalVars.appArgs.createPortableSilent,startAfterCreate=not globalVars.appArgs.createPortableSilent)
	elif not globalVars.appArgs.minimal:
		try:
			# Translators: This is shown on a braille display (if one is connected) when NVDA starts.
			braille.handler.message(_("NVDA started"))
		except:
			log.error("", exc_info=True)
		if globalVars.appArgs.launcher:
			gui.LauncherDialog.run()
			# LauncherDialog will call doStartupDialogs() afterwards if required.
		else:
			wx.CallAfter(doStartupDialogs)
	import queueHandler
	# Queue the handling of initial focus,
	# as API handlers might need to be pumped to get the first focus event.
	queueHandler.queueFunction(queueHandler.eventQueue, _setInitialFocus)
	import watchdog
	import baseObject

	# Doing this here is a bit ugly, but we don't want these modules imported
	# at module level, including wx.
	log.debug("Initializing core pump")
	class CorePump(gui.NonReEntrantTimer):
		"Checks the queues and executes functions."
		def run(self):
			global _isPumpPending
			_isPumpPending = False
			watchdog.alive()
			try:
				if touchHandler.handler:
					touchHandler.handler.pump()
				JABHandler.pumpAll()
				IAccessibleHandler.pumpAll()
				queueHandler.pumpAll()
				mouseHandler.pumpAll()
				braille.pumpAll()
			except:
				log.exception("errors in this core pump cycle")
			baseObject.AutoPropertyObject.invalidateCaches()
			watchdog.asleep()
			if _isPumpPending and not _pump.IsRunning():
				# #3803: Another pump was requested during this pump execution.
				# As our pump is not re-entrant, schedule another pump.
				_pump.Start(PUMP_MAX_DELAY, True)
	global _pump
	_pump = CorePump()
	requestPump()

	log.debug("Initializing watchdog")
	watchdog.initialize()
	try:
		import updateCheck
	except RuntimeError:
		updateCheck=None
		log.debug("Update checking not supported")
	else:
		log.debug("initializing updateCheck")
		updateCheck.initialize()
	log.info("NVDA initialized")
	postNvdaStartup.notify()

	log.debug("entering wx application main loop")
	app.MainLoop()

	log.info("Exiting")
	if updateCheck:
		_terminate(updateCheck)

	_terminate(watchdog)
	_terminate(globalPluginHandler, name="global plugin handler")
	_terminate(gui)
	config.saveOnExit()

	try:
		if globalVars.focusObject and hasattr(globalVars.focusObject,"event_loseFocus"):
			log.debug("calling lose focus on object with focus")
			globalVars.focusObject.event_loseFocus()
	except:
		log.exception("Lose focus error")
	try:
		speech.cancelSpeech()
	except:
		pass

	import treeInterceptorHandler
	_terminate(treeInterceptorHandler)
	_terminate(IAccessibleHandler, name="IAccessible support")
	_terminate(UIAHandler, name="UIA support")
	_terminate(winConsoleHandler, name="winConsole support")
	_terminate(JABHandler, name="Java Access Bridge support")
	_terminate(appModuleHandler, name="app module handler")
	_terminate(NVDAHelper)
	_terminate(touchHandler)
	_terminate(keyboardHandler, name="keyboard handler")
	_terminate(mouseHandler)
	_terminate(inputCore)
	_terminate(brailleInput)
	_terminate(braille)
	_terminate(speech)
	_terminate(addonHandler)

	if not globalVars.appArgs.minimal and config.conf["general"]["playStartAndExitSounds"]:
		try:
			nvwave.playWaveFile("waves\\exit.wav",async=False)
		except:
			pass
	# #5189: Destroy the message window as late as possible
	# so new instances of NVDA can find this one even if it freezes during exit.
	messageWindow.destroy()
	log.debug("core done")
Esempio n. 38
0
 def terminate(self):
     log.debug("Terminating the systemTestSpy")
     self._testSpy.stop()
Esempio n. 39
0
 def onLaterButton(self, evt):
     log.debug("Usage stats gathering question has been deferred")
     # evt.Skip() is called since wx.ID_CANCEL is used as the ID for the Ask Later button,
     # wx automatically ends the modal itself.
     evt.Skip()
Esempio n. 40
0
    def __init__(self, port: typing.Union[None, str, DeviceMatch]):
        super().__init__()
        self.numCells = 0
        self.numBtns = 0
        self.numRoutingKeys = 0
        self.handle = None
        self._hidBuffer = b""
        self._command: typing.Optional[bytes] = None
        self._argsLen: typing.Optional[int] = None

        log.debug(f"Seika Notetaker braille driver: ({port!r})")
        dev: typing.Optional[typing.Union[hwIo.Hid, hwIo.Serial]] = None
        for match in self._getTryPorts(port):
            self.isHid = match.type == bdDetect.KEY_HID
            self.isSerial = match.type == bdDetect.KEY_SERIAL
            try:
                if self.isHid:
                    log.info(f"Trying Seika notetaker on USB-HID")
                    self._dev = dev = hwIo.Hid(
                        path=match.
                        port,  # for a Hid match type 'port' is actually 'path'.
                        onReceive=self._onReceiveHID)
                    dev.setFeature(
                        SEIKA_HID_FEATURES)  # baud rate, stop bit usw
                    dev.setFeature(SEIKA_CMD_ON)  # device on
                elif self.isSerial:
                    log.info(
                        f"Trying Seika notetaker on Bluetooth (serial) port:{match.port}"
                    )
                    self._dev = dev = hwIo.Serial(
                        port=match.port,
                        onReceive=self._onReceiveSerial,
                        baudrate=BAUD,
                        parity=serial.PARITY_NONE,
                        bytesize=serial.EIGHTBITS,
                        stopbits=serial.STOPBITS_ONE,
                    )
                    # Note: SEIKA_CMD_ON not sent as per USB-HID, testing from users hasn't indicated any problems.
                    # The exact purpose of SEIKA_CMD_ON isn't known/documented here.
                else:
                    log.debug(f"Port type not handled: {match.type}")
                    continue
            except EnvironmentError:
                log.debugWarning("", exc_info=True)
                continue
            if self._getDeviceInfo(dev):
                break
            elif dev:
                dev.close()
                dev = None

        if not dev:
            RuntimeError("No MINI-SEIKA display found")
        elif self.numCells == 0:
            dev.close()
            dev = None
            raise RuntimeError("No MINI-SEIKA display found, no response")
        else:
            log.info(f"Seika notetaker,"
                     f" Cells {self.numCells}"
                     f" Buttons {self.numBtns}")
Esempio n. 41
0
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
"""This file provides spy and robot library behaviour for NVDA system tests.
It is copied into the (system test specific) NVDA profile directory. It becomes the '__init__.py' file as part of a
package. This allows us to share utility methods between the global plugin and the nvdaRobotLib library.
"""
import globalPluginHandler
import threading
from .systemTestUtils import _blockUntilConditionMet
from logHandler import log
from time import clock as _timer

import sys
import os

log.debug("before pathmod: {}".format(sys.path))
# Get the path to the top of the package
TOP_DIR = os.path.abspath(os.path.dirname(__file__))
# imports that require libraries not distributed with an install of NVDA
sys.path.append(os.path.join(TOP_DIR, "libs"))
log.debug("after pathmod: {}".format(sys.path))
from robotremoteserver import RobotRemoteServer

whitespaceMinusSlashN = '\t\x0b\x0c\r '


class SystemTestSpy(object):
    SPEECH_HAS_FINISHED_SECONDS = 0.5

    def __init__(self):
        self._nvdaSpeech = [
Esempio n. 42
0
    def _hasCaretMoved(self,
                       bookmark,
                       retryInterval=0.01,
                       timeout=None,
                       origWord=None):
        """
		Waits for the caret to move, for a timeout to elapse, or for a new focus event or script to be queued.
		@param bookmark: a bookmark representing the position of the caret before  it was instructed to move
		@type bookmark: bookmark
		@param retryInterval: the interval of time in seconds this method should  wait before checking the caret each time.
		@type retryInterval: float 
		@param timeout: the over all amount of time in seconds the method should wait before giving up completely,
			C{None} to use the value from the configuration.
		@type timeout: float
		@param origWord: The word at the caret before the movement command,
			C{None} if the word at the caret should not be used to detect movement.
			This is intended for use with the delete key.
		@return: a tuple containing a boolean denoting whether this method timed out, and  a TextInfo representing the old or updated caret position or None if interupted by a script or focus event.
		@rtype: tuple
		"""
        if timeout is None:
            timeoutMs = config.conf["editableText"]["caretMoveTimeoutMs"]
        else:
            # This function's arguments are in seconds, but we want ms.
            timeoutMs = timeout * 1000
        timeoutMs *= self._caretMovementTimeoutMultiplier
        # time.sleep accepts seconds, so retryInterval is in seconds.
        # Convert to integer ms to avoid floating point precision errors when adding to elapsed.
        retryMs = int(retryInterval * 1000)
        elapsed = 0
        newInfo = None
        while True:
            if isScriptWaiting():
                return (False, None)
            api.processPendingEvents(processEventQueue=False)
            if eventHandler.isPendingEvents("gainFocus"):
                log.debug("Focus event. Elapsed: %d ms" % elapsed)
                return (True, None)
            # If the focus changes after this point, fetching the caret may fail,
            # but we still want to stay in this loop.
            try:
                newInfo = self.makeTextInfo(textInfos.POSITION_CARET)
            except (RuntimeError, NotImplementedError):
                newInfo = None
            else:
                # Caret events are unreliable in some controls.
                # Only use them if we consider them safe to rely on for a particular control,
                # and only if they arrive within C{_useEvents_maxTimeoutMs} mili seconds
                # after causing the event to occur.
                if (elapsed <= self._useEvents_maxTimeoutMs
                        and self.caretMovementDetectionUsesEvents
                        and (eventHandler.isPendingEvents("caret")
                             or eventHandler.isPendingEvents("textChange"))):
                    log.debug(
                        "Caret move detected using event. Elapsed: %d ms" %
                        elapsed)
                    return (True, newInfo)
            # Try to detect with bookmarks.
            newBookmark = None
            if newInfo:
                try:
                    newBookmark = newInfo.bookmark
                except (RuntimeError, NotImplementedError):
                    pass
            if newBookmark and newBookmark != bookmark:
                log.debug(
                    "Caret move detected using bookmarks. Elapsed: %d ms" %
                    elapsed)
                return (True, newInfo)
            if origWord is not None and newInfo and elapsed >= self._hasCaretMoved_minWordTimeoutMs:
                # When pressing delete, bookmarks might not be enough to detect caret movement.
                # Therefore try detecting if the word under the caret has changed, such as when pressing delete.
                # some editors such as Mozilla Gecko can have text and units that get out of sync with eachother while a character is being deleted.
                # Therefore, only check if the word has changed after a particular amount of time has elapsed, allowing the text and units to settle down.
                wordInfo = newInfo.copy()
                wordInfo.expand(textInfos.UNIT_WORD)
                word = wordInfo.text
                if word != origWord:
                    log.debug("Word at caret changed. Elapsed: %d ms" %
                              elapsed)
                    return (True, newInfo)
            if elapsed >= timeoutMs:
                break
            time.sleep(retryInterval)
            elapsed += retryMs
        log.debug("Caret didn't move before timeout. Elapsed: %d ms" % elapsed)
        return (False, newInfo)
Esempio n. 43
0
def listHidDevices(onlyAvailable=True):
    """List HID devices on the system.
	@param onlyAvailable: Only return devices that are currently available.
	@type onlyAvailable: bool
	@return: Generates dicts including keys such as hardwareID,
		usbID (in the form "VID_xxxx&PID_xxxx")
		and devicePath.
	@rtype: generator of dict
	"""
    global _hidGuid
    if not _hidGuid:
        _hidGuid = GUID()
        ctypes.windll.hid.HidD_GetHidGuid(ctypes.byref(_hidGuid))

    flags = DIGCF_DEVICEINTERFACE
    if onlyAvailable:
        flags |= DIGCF_PRESENT

    buf = ctypes.create_unicode_buffer(1024)
    g_hdi = SetupDiGetClassDevs(_hidGuid, None, NULL, flags)
    try:
        for dwIndex in xrange(256):
            did = SP_DEVICE_INTERFACE_DATA()
            did.cbSize = ctypes.sizeof(did)

            if not SetupDiEnumDeviceInterfaces(g_hdi, None, _hidGuid, dwIndex,
                                               ctypes.byref(did)):
                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                    raise ctypes.WinError()
                break

            dwNeeded = DWORD()
            # get the size
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded),
                    None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            # allocate buffer
            class SP_DEVICE_INTERFACE_DETAIL_DATA_W(ctypes.Structure):
                _fields_ = (
                    ('cbSize', DWORD),
                    ('DevicePath',
                     WCHAR * (dwNeeded.value - ctypes.sizeof(DWORD))),
                )

                def __str__(self):
                    return "DevicePath:%s" % (self.DevicePath, )

            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_W()
            idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_W
            devinfo = SP_DEVINFO_DATA()
            devinfo.cbSize = ctypes.sizeof(devinfo)
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded,
                    None, ctypes.byref(devinfo)):
                raise ctypes.WinError()

            # hardware ID
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None,
                    ctypes.byref(buf),
                    ctypes.sizeof(buf) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            else:
                hwId = buf.value
                info = _getHidInfo(hwId, idd.DevicePath)
                if _isDebug():
                    log.debug("%r" % info)
                yield info
    finally:
        SetupDiDestroyDeviceInfoList(g_hdi)
    if _isDebug():
        log.debug("Finished listing HID devices")
 def onDefaultDictionaryCommand(self, evt):
     # linting is complaining about from .settingsDialogs import * names
     # too risky to change it all, so we will specify what we want on a method based aproach
     log.debug("chamasticocact")
     dic = dictHelper.getDictionary("default")
     guiHelper.showEnhancedDictionaryDialog(dic)
Esempio n. 45
0
def main():
    """NVDA's core main loop.
This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI. Then it initialises the wx application object and sets up the core pump, which checks the queues and executes functions when requested. Finally, it starts the wx main loop.
"""
    log.debug("Core starting")

    try:
        # Windows >= Vista
        ctypes.windll.user32.SetProcessDPIAware()
    except AttributeError:
        pass

    import config
    if not globalVars.appArgs.configPath:
        globalVars.appArgs.configPath = config.getUserDefaultConfigPath(
            useInstalledPathIfExists=globalVars.appArgs.launcher)
    #Initialize the config path (make sure it exists)
    config.initConfigPath()
    log.info("Config dir: %s" % os.path.abspath(globalVars.appArgs.configPath))
    log.debug("loading config")
    import config
    config.initialize()
    if not globalVars.appArgs.minimal and config.conf["general"][
            "playStartAndExitSounds"]:
        try:
            nvwave.playWaveFile("waves\\start.wav")
        except:
            pass
    logHandler.setLogLevelFromConfig()
    logHandler.setPlayErrorSoundFromConfig()
    try:
        lang = config.conf["general"]["language"]
        import languageHandler
        log.debug("setting language to %s" % lang)
        languageHandler.setLanguage(lang)
    except:
        log.warning("Could not set language to %s" % lang)
    import versionInfo
    log.info("NVDA version %s" % versionInfo.version)
    log.info("Using Windows version %s" % winVersion.winVersionText)
    log.info("Using Python version %s" % sys.version)
    log.info("Using comtypes version %s" % comtypes.__version__)
    # Set a reasonable timeout for any socket connections NVDA makes.
    import socket
    socket.setdefaulttimeout(10)
    log.debug("Initializing add-ons system")
    addonHandler.initialize()
    if globalVars.appArgs.disableAddons:
        log.info("Add-ons are disabled. Restart NVDA to enable them.")
    import appModuleHandler
    log.debug("Initializing appModule Handler")
    appModuleHandler.initialize()
    import NVDAHelper
    log.debug("Initializing NVDAHelper")
    NVDAHelper.initialize()
    import speechDictHandler
    log.debug("Speech Dictionary processing")
    speechDictHandler.initialize()
    import speech
    log.debug("Initializing speech")
    speech.initialize()
    if not globalVars.appArgs.minimal and (time.time() -
                                           globalVars.startTime) > 5:
        log.debugWarning("Slow starting core (%.2f sec)" %
                         (time.time() - globalVars.startTime))
        # Translators: This is spoken when NVDA is starting.
        speech.speakMessage(_("Loading NVDA. Please wait..."))
    import wx
    log.info("Using wx version %s" % wx.version())

    class App(wx.App):
        def OnAssert(self, file, line, cond, msg):
            message = "{file}, line {line}:\nassert {cond}: {msg}".format(
                file=file, line=line, cond=cond, msg=msg)
            log.debugWarning(message, codepath="WX Widgets", stack_info=True)

    app = App(redirect=False)
    # We do support QueryEndSession events, but we don't want to do anything for them.
    app.Bind(wx.EVT_QUERY_END_SESSION, lambda evt: None)

    def onEndSession(evt):
        # NVDA will be terminated as soon as this function returns, so save configuration if appropriate.
        config.saveOnExit()
        speech.cancelSpeech()
        if not globalVars.appArgs.minimal and config.conf["general"][
                "playStartAndExitSounds"]:
            try:
                nvwave.playWaveFile("waves\\exit.wav", async=False)
            except:
                pass
        log.info("Windows session ending")

    app.Bind(wx.EVT_END_SESSION, onEndSession)
    import braille
    log.debug("Initializing braille")
    braille.initialize()
    log.debug("Initializing braille input")
    import brailleInput
    brailleInput.initialize()
    import displayModel
    log.debug("Initializing displayModel")
    displayModel.initialize()
    log.debug("Initializing GUI")
    import gui
    gui.initialize()
    import audioDucking
    if audioDucking.isAudioDuckingSupported():
        # the GUI mainloop must be running for this to work so delay it
        wx.CallAfter(audioDucking.initialize)

    # #3763: In wxPython 3, the class name of frame windows changed from wxWindowClassNR to wxWindowNR.
    # NVDA uses the main frame to check for and quit another instance of NVDA.
    # To remain compatible with older versions of NVDA, create our own wxWindowClassNR.
    # We don't need to do anything else because wx handles WM_QUIT for all windows.
    import windowUtils

    class MessageWindow(windowUtils.CustomWindow):
        className = u"wxWindowClassNR"

    messageWindow = MessageWindow(unicode(versionInfo.name))

    # initialize wxpython localization support
    locale = wx.Locale()
    lang = languageHandler.getLanguage()
    wxLang = locale.FindLanguageInfo(lang)
    if not wxLang and '_' in lang:
        wxLang = locale.FindLanguageInfo(lang.split('_')[0])
    if hasattr(sys, 'frozen'):
        locale.AddCatalogLookupPathPrefix(os.path.join(os.getcwdu(), "locale"))
    if wxLang:
        try:
            locale.Init(wxLang.Language)
        except:
            log.error("Failed to initialize wx locale", exc_info=True)
    else:
        log.debugWarning("wx does not support language %s" % lang)

    import api
    import winUser
    import NVDAObjects.window
    desktopObject = NVDAObjects.window.Window(
        windowHandle=winUser.getDesktopWindow())
    api.setDesktopObject(desktopObject)
    api.setFocusObject(desktopObject)
    api.setNavigatorObject(desktopObject)
    api.setMouseObject(desktopObject)
    import JABHandler
    log.debug("initializing Java Access Bridge support")
    try:
        JABHandler.initialize()
    except NotImplementedError:
        log.warning("Java Access Bridge not available")
    except:
        log.error("Error initializing Java Access Bridge support",
                  exc_info=True)
    import winConsoleHandler
    log.debug("Initializing winConsole support")
    winConsoleHandler.initialize()
    import UIAHandler
    log.debug("Initializing UIA support")
    try:
        UIAHandler.initialize()
    except NotImplementedError:
        log.warning("UIA not available")
    except:
        log.error("Error initializing UIA support", exc_info=True)
    import IAccessibleHandler
    log.debug("Initializing IAccessible support")
    IAccessibleHandler.initialize()
    log.debug("Initializing input core")
    import inputCore
    inputCore.initialize()
    import keyboardHandler
    log.debug("Initializing keyboard handler")
    keyboardHandler.initialize()
    import mouseHandler
    log.debug("initializing mouse handler")
    mouseHandler.initialize()
    import touchHandler
    log.debug("Initializing touchHandler")
    try:
        touchHandler.initialize()
    except NotImplementedError:
        pass
    import globalPluginHandler
    log.debug("Initializing global plugin handler")
    globalPluginHandler.initialize()
    if globalVars.appArgs.install or globalVars.appArgs.installSilent:
        import wx
        import gui.installerGui
        wx.CallAfter(gui.installerGui.doSilentInstall,
                     startAfterInstall=not globalVars.appArgs.installSilent)
    elif not globalVars.appArgs.minimal:
        try:
            # Translators: This is shown on a braille display (if one is connected) when NVDA starts.
            braille.handler.message(_("NVDA started"))
        except:
            log.error("", exc_info=True)
        if globalVars.appArgs.launcher:
            gui.LauncherDialog.run()
            # LauncherDialog will call doStartupDialogs() afterwards if required.
        else:
            wx.CallAfter(doStartupDialogs)
    import queueHandler
    # Queue the handling of initial focus,
    # as API handlers might need to be pumped to get the first focus event.
    queueHandler.queueFunction(queueHandler.eventQueue, _setInitialFocus)
    import watchdog
    import baseObject

    # Doing this here is a bit ugly, but we don't want these modules imported
    # at module level, including wx.
    log.debug("Initializing core pump")

    class CorePump(wx.Timer):
        "Checks the queues and executes functions."

        def Notify(self):
            global _isPumpPending
            _isPumpPending = False
            watchdog.alive()
            try:
                if touchHandler.handler:
                    touchHandler.handler.pump()
                JABHandler.pumpAll()
                IAccessibleHandler.pumpAll()
                queueHandler.pumpAll()
                mouseHandler.pumpAll()
                braille.pumpAll()
            except:
                log.exception("errors in this core pump cycle")
            baseObject.AutoPropertyObject.invalidateCaches()
            watchdog.asleep()
            if _isPumpPending and not _pump.IsRunning():
                # #3803: A pump was requested, but the timer was ignored by a modal loop
                # because timers aren't re-entrant.
                # Therefore, schedule another pump.
                _pump.Start(PUMP_MAX_DELAY, True)

    global _pump
    _pump = CorePump()
    requestPump()

    log.debug("Initializing watchdog")
    watchdog.initialize()
    try:
        import updateCheck
    except RuntimeError:
        updateCheck = None
        log.debug("Update checking not supported")
    else:
        log.debug("initializing updateCheck")
        updateCheck.initialize()
    log.info("NVDA initialized")

    log.debug("entering wx application main loop")
    app.MainLoop()

    log.info("Exiting")
    if updateCheck:
        _terminate(updateCheck)

    _terminate(watchdog)
    _terminate(globalPluginHandler, name="global plugin handler")
    _terminate(gui)
    config.saveOnExit()

    try:
        if globalVars.focusObject and hasattr(globalVars.focusObject,
                                              "event_loseFocus"):
            log.debug("calling lose focus on object with focus")
            globalVars.focusObject.event_loseFocus()
    except:
        log.exception("Lose focus error")
    try:
        speech.cancelSpeech()
    except:
        pass

    import treeInterceptorHandler
    _terminate(treeInterceptorHandler)
    _terminate(IAccessibleHandler, name="IAccessible support")
    _terminate(UIAHandler, name="UIA support")
    _terminate(winConsoleHandler, name="winConsole support")
    _terminate(JABHandler, name="Java Access Bridge support")
    _terminate(appModuleHandler, name="app module handler")
    _terminate(NVDAHelper)
    _terminate(touchHandler)
    _terminate(keyboardHandler, name="keyboard handler")
    _terminate(mouseHandler)
    _terminate(inputCore)
    _terminate(brailleInput)
    _terminate(braille)
    _terminate(speech)
    _terminate(addonHandler)

    if not globalVars.appArgs.minimal and config.conf["general"][
            "playStartAndExitSounds"]:
        try:
            nvwave.playWaveFile("waves\\exit.wav", async=False)
        except:
            pass
    # #5189: Destroy the message window as late as possible
    # so new instances of NVDA can find this one even if it freezes during exit.
    messageWindow.destroy()
    log.debug("core done")
Esempio n. 46
0
 def postInit(self):
     super(AtcMixin, self).postInit()
     log.debug("Enabling ATC")
     self._display.atc = True
Esempio n. 47
0
	def enable(self):
		"""Tells NVDA that you require that background audio be ducked from now until you call disable.
		This method may block for a short time while background audio ducks to a suitable level.
		It is safe to call this method more than once.
		@ returns: True if ducking was enabled, false if ducking was subsiquently disabled while waiting for the background audio to drop.
		"""
		debug = _isDebug()
		with self._lock:
			if self._enabled:
				if debug:
					log.debug("ignoring duplicate enable")
				return True
			self._enabled=True
			if debug:
				log.debug("enabling")
			whenWasDucked,modeChangeEvent=_ensureDucked()
			deltaMS=int((INITIAL_DUCKING_DELAY-whenWasDucked)*1000)
			disableEvent=self._disabledEvent=AutoEvent()
			if debug:
				log.debug("whenWasDucked %s, deltaMS %s"%(whenWasDucked,deltaMS))
			if deltaMS<=0 or _audioDuckingMode==AUDIODUCKINGMODE_NONE:
				return True
		import NVDAHelper
		if not NVDAHelper.localLib.audioDucking_shouldDelay():
			if debug:
				log.debug("No background audio, not delaying")
			return True
		if debug:
			log.debug("waiting %s ms or mode change"%deltaMS)
		wasCanceled=windll.kernel32.WaitForMultipleObjects(2,(wintypes.HANDLE*2)(disableEvent,modeChangeEvent),False,deltaMS)!=WAIT_TIMEOUT
		if debug:
			log.debug("Wait canceled" if wasCanceled else "timeout exceeded")
		return not wasCanceled
Esempio n. 48
0
def listComPorts(onlyAvailable=True):
    """List com ports on the system.
	@param onlyAvailable: Only return ports that are currently available.
	@type onlyAvailable: bool
	@return: Generates dicts including keys of port, friendlyName and hardwareID.
	@rtype: generator of dict
	"""
    flags = DIGCF_DEVICEINTERFACE
    if onlyAvailable:
        flags |= DIGCF_PRESENT

    buf = ctypes.create_unicode_buffer(1024)
    g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL,
                                flags)
    try:
        for dwIndex in xrange(256):
            entry = {}
            did = SP_DEVICE_INTERFACE_DATA()
            did.cbSize = ctypes.sizeof(did)

            if not SetupDiEnumDeviceInterfaces(
                    g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex,
                    ctypes.byref(did)):
                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                    raise ctypes.WinError()
                break

            dwNeeded = DWORD()
            # get the size
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded),
                    None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            # allocate buffer
            class SP_DEVICE_INTERFACE_DETAIL_DATA_W(ctypes.Structure):
                _fields_ = (
                    ('cbSize', DWORD),
                    ('DevicePath',
                     WCHAR * (dwNeeded.value - ctypes.sizeof(DWORD))),
                )

                def __str__(self):
                    return "DevicePath:%s" % (self.DevicePath, )

            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_W()
            idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_W
            devinfo = SP_DEVINFO_DATA()
            devinfo.cbSize = ctypes.sizeof(devinfo)
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded,
                    None, ctypes.byref(devinfo)):
                raise ctypes.WinError()

            # hardware ID
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None,
                    ctypes.byref(buf),
                    ctypes.sizeof(buf) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            else:
                hwID = entry["hardwareID"] = buf.value

            regKey = ctypes.windll.setupapi.SetupDiOpenDevRegKey(
                g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV,
                winreg.KEY_READ)
            try:
                try:
                    port = entry["port"] = winreg.QueryValueEx(
                        regKey, "PortName")[0]
                except WindowsError:
                    # #6015: In some rare cases, this value doesn't exist.
                    log.debugWarning("No PortName value for hardware ID %s" %
                                     hwID)
                    continue
                if not port:
                    log.debugWarning(
                        "Empty PortName value for hardware ID %s" % hwID)
                    continue
                if hwID.startswith("BTHENUM\\"):
                    # This is a Microsoft bluetooth port.
                    try:
                        addr = winreg.QueryValueEx(
                            regKey,
                            "Bluetooth_UniqueID")[0].split("#",
                                                           1)[1].split("_",
                                                                       1)[0]
                        addr = int(addr, 16)
                        entry["bluetoothAddress"] = addr
                        if addr:
                            entry["bluetoothName"] = getBluetoothDeviceInfo(
                                addr).szName
                    except:
                        pass
                elif hwID == r"Bluetooth\0004&0002":
                    # This is a Toshiba bluetooth port.
                    try:
                        entry["bluetoothAddress"], entry[
                            "bluetoothName"] = getToshibaBluetoothPortInfo(
                                port)
                    except:
                        pass
                elif hwID == r"{95C7A0A0-3094-11D7-A202-00508B9D7D5A}\BLUETOOTHPORT":
                    try:
                        entry["bluetoothAddress"], entry[
                            "bluetoothName"] = getWidcommBluetoothPortInfo(
                                port)
                    except:
                        pass
            finally:
                ctypes.windll.advapi32.RegCloseKey(regKey)

            # friendly name
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None,
                    ctypes.byref(buf),
                    ctypes.sizeof(buf) - 1, None):
                # #6007: SPDRP_FRIENDLYNAME sometimes doesn't exist/isn't valid.
                log.debugWarning("Couldn't get SPDRP_FRIENDLYNAME for %r: %s" %
                                 (port, ctypes.WinError()))
                entry["friendlyName"] = port
            else:
                entry["friendlyName"] = buf.value

            if _isDebug():
                log.debug("%r" % entry)
            yield entry

    finally:
        SetupDiDestroyDeviceInfoList(g_hdi)
    if _isDebug():
        log.debug("Finished listing com ports")
Esempio n. 49
0
 def postInit(self):
     super(TimeSyncMixin, self).postInit()
     log.debug("Request current display time")
     self._display.sendExtendedPacket(HT_EXTPKT_GET_RTC)
Esempio n. 50
0
	def _doPostNvdaStartupAction():
		log.debug("Notify of postNvdaStartup action")
		postNvdaStartup.notify()
Esempio n. 51
0
 def onNoButton(self, evt):
     log.debug("Usage stats gathering has been disallowed")
     config.conf['update']['askedAllowUsageStats'] = True
     config.conf['update']['allowUsageStats'] = False
     self.EndModal(wx.ID_NO)
Esempio n. 52
0
 def IUIAutomationEventHandler_HandleAutomationEvent(self, sender, eventID):
     if not self.MTAThreadInitEvent.isSet():
         # UIAHandler hasn't finished initialising yet, so just ignore this event.
         if _isDebug():
             log.debug(
                 "HandleAutomationEvent: event received while not fully initialized"
             )
         return
     if eventID == UIA_MenuOpenedEventId and eventHandler.isPendingEvents(
             "gainFocus"):
         # We don't need the menuOpened event if focus has been fired,
         # as focus should be more correct.
         if _isDebug():
             log.debug(
                 "HandleAutomationEvent: Ignored MenuOpenedEvent while focus event pending"
             )
         return
     NVDAEventName = UIAEventIdsToNVDAEventNames.get(eventID, None)
     if not NVDAEventName:
         if _isDebug():
             log.debugWarning(
                 f"HandleAutomationEvent: Don't know how to handle event {eventID}"
             )
         return
     focus = api.getFocusObject()
     import NVDAObjects.UIA
     if (isinstance(focus, NVDAObjects.UIA.UIA) and
             self.clientObject.compareElements(focus.UIAElement, sender)):
         pass
     elif not self.isNativeUIAElement(sender):
         if _isDebug():
             log.debug(
                 f"HandleAutomationEvent: Ignoring event {NVDAEventName} for non native element"
             )
         return
     window = self.getNearestWindowHandle(sender)
     if window and not eventHandler.shouldAcceptEvent(NVDAEventName,
                                                      windowHandle=window):
         if _isDebug():
             log.debug(
                 f"HandleAutomationEvent: Ignoring event {NVDAEventName} for shouldAcceptEvent=False"
             )
         return
     try:
         obj = NVDAObjects.UIA.UIA(UIAElement=sender)
     except Exception:
         if _isDebug():
             log.debugWarning(
                 f"HandleAutomationEvent: Exception while creating object for event {NVDAEventName}",
                 exc_info=True)
         return
     if (not obj or
         (NVDAEventName == "gainFocus" and not obj.shouldAllowUIAFocusEvent)
             or (NVDAEventName == "liveRegionChange"
                 and not obj._shouldAllowUIALiveRegionChangeEvent)):
         if _isDebug():
             log.debug(
                 "HandleAutomationEvent: "
                 f"Ignoring event {NVDAEventName} because no object or ignored by object itself"
             )
         return
     if obj == focus:
         obj = focus
     eventHandler.queueEvent(NVDAEventName, obj)
Esempio n. 53
0
def resetConfiguration(factoryDefaults=False):
    """Loads the configuration, installs the correct language support and initialises audio so that it will use the configured synth and speech settings.
	"""
    import config
    import braille
    import brailleInput
    import speech
    import vision
    import languageHandler
    import inputCore
    import tones
    log.debug("Terminating vision")
    vision.terminate()
    log.debug("Terminating braille")
    braille.terminate()
    log.debug("Terminating brailleInput")
    brailleInput.terminate()
    log.debug("terminating speech")
    speech.terminate()
    log.debug("terminating tones")
    tones.terminate()
    log.debug("terminating addonHandler")
    addonHandler.terminate()
    log.debug("Reloading config")
    config.conf.reset(factoryDefaults=factoryDefaults)
    logHandler.setLogLevelFromConfig()
    #Language
    lang = config.conf["general"]["language"]
    log.debug("setting language to %s" % lang)
    languageHandler.setLanguage(lang)
    # Addons
    addonHandler.initialize()
    # Tones
    tones.initialize()
    #Speech
    log.debug("initializing speech")
    speech.initialize()
    #braille
    log.debug("Initializing brailleInput")
    brailleInput.initialize()
    log.debug("Initializing braille")
    braille.initialize()
    # Vision
    log.debug("initializing vision")
    vision.initialize()
    log.debug("Reloading user and locale input gesture maps")
    inputCore.manager.loadUserGestureMap()
    inputCore.manager.loadLocaleGestureMap()
    import audioDucking
    if audioDucking.isAudioDuckingSupported():
        audioDucking.handlePostConfigProfileSwitch()
    log.info("Reverted to saved configuration")
Esempio n. 54
0
 def IUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent(
         self, sender, propertyId, newValue):
     # #3867: For now manually force this VARIANT type to empty to get around a nasty double free in comtypes/ctypes.
     # We also don't use the value in this callback.
     newValue.vt = VT_EMPTY
     if not self.MTAThreadInitEvent.isSet():
         # UIAHandler hasn't finished initialising yet, so just ignore this event.
         if _isDebug():
             log.debug(
                 "HandlePropertyChangedEvent: event received while not fully initialized"
             )
         return
     try:
         processId = sender.CachedProcessID
     except COMError:
         pass
     else:
         appMod = appModuleHandler.getAppModuleFromProcessID(processId)
         if not appMod.shouldProcessUIAPropertyChangedEvent(
                 sender, propertyId):
             return
     NVDAEventName = UIAPropertyIdsToNVDAEventNames.get(propertyId, None)
     if not NVDAEventName:
         if _isDebug():
             log.debugWarning(
                 f"HandlePropertyChangedEvent: Don't know how to handle property {propertyId}"
             )
         return
     focus = api.getFocusObject()
     import NVDAObjects.UIA
     if (isinstance(focus, NVDAObjects.UIA.UIA) and
             self.clientObject.compareElements(focus.UIAElement, sender)):
         pass
     elif not self.isNativeUIAElement(sender):
         if _isDebug():
             log.debug(
                 f"HandlePropertyChangedEvent: Ignoring event {NVDAEventName} for non native element"
             )
         return
     window = self.getNearestWindowHandle(sender)
     if window and not eventHandler.shouldAcceptEvent(NVDAEventName,
                                                      windowHandle=window):
         if _isDebug():
             log.debug(
                 f"HandlePropertyChangedEvent: Ignoring event {NVDAEventName} for shouldAcceptEvent=False"
             )
         return
     try:
         obj = NVDAObjects.UIA.UIA(UIAElement=sender)
     except Exception:
         if _isDebug():
             log.debugWarning(
                 f"HandlePropertyChangedEvent: Exception while creating object for event {NVDAEventName}",
                 exc_info=True)
         return
     if not obj:
         if _isDebug():
             log.debug(
                 f"HandlePropertyChangedEvent: Ignoring event {NVDAEventName} because no object"
             )
         return
     if obj == focus:
         obj = focus
     eventHandler.queueEvent(NVDAEventName, obj)
def _handlePostConfigProfileSwitch(resetSpeechIfNeeded=True):
    log.debug("changing profile")
    dictHelper.reloadDictionaries()
def getActiveProfile(self):
    if globalVars.appArgs.secure:
        log.debug("safe profile")
        return
    log.debug(f"will return {self.profiles[-1].name}")
    return self.profiles[-1]
Esempio n. 57
0
 def dumpSpeechToLog(self):
     log.debug("All speech:\n{}".format(repr(self._nvdaSpeech)))
Esempio n. 58
0
def processFocusWinEvent(window, objectID, childID, force=False):
	"""checks to see if the focus win event is not the same as the existing focus,
	then converts the win event to an NVDA event (instantiating an NVDA Object) then calls
	processFocusNVDAEvent. If all is ok it returns True.
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@param force: If True, the shouldAllowIAccessibleFocusEvent property of the object is ignored.
	@type force: boolean
	@returns: True if the focus is valid and was handled, False otherwise.
	@rtype: boolean
	"""
	if isMSAADebugLoggingEnabled():
		log.debug(
			f"Processing focus winEvent: {getWinEventLogInfo(window, objectID, childID)}, "
			f"force {force}"
		)
	windowClassName = winUser.getClassName(window)
	# Generally, we must ignore focus on child windows of SDM windows as we only want the SDM MSAA events.
	# However, we don't want to ignore focus if the child ID isn't 0,
	# as this is a child control and the SDM MSAA events don't handle child controls.
	if (
		childID == 0
		and not windowClassName.startswith('bosa_sdm')
		and winUser.getClassName(winUser.getAncestor(window, winUser.GA_PARENT)).startswith('bosa_sdm')
	):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Focus event for child window of MS Office SDM window. "
				f"Dropping winEvent {getWinEventLogInfo(window, objectID, childID)}, "
			)
		return False
	# Notify appModuleHandler of this new foreground window
	appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
	# If Java access bridge is running, and this is a java window, then pass it to java and forget about it
	if (
		childID == 0
		and objectID == winUser.OBJID_CLIENT
		and JABHandler.isRunning
		and JABHandler.isJavaWindow(window)
	):
		if isMSAADebugLoggingEnabled():
			log.debug(
				f"Redirecting focus to Java window. WinEvent {getWinEventLogInfo(window, objectID, childID)}"
			)
		JABHandler.event_enterJavaWindow(window)
		return True
	# Convert the win event to an NVDA event
	NVDAEvent = winEventToNVDAEvent(winUser.EVENT_OBJECT_FOCUS, window, objectID, childID, useCache=False)
	if not NVDAEvent:
		return False
	eventName, obj = NVDAEvent
	if (
		(childID == 0 and obj.IAccessibleRole == oleacc.ROLE_SYSTEM_LIST)
		or (objectID == winUser.OBJID_CLIENT and "SysListView32" in obj.windowClassName)
	):
		# Some controls incorrectly fire focus on child ID 0, even when there is a child with focus.
		try:
			realChildID = obj.IAccessibleObject.accFocus
		except:  # noqa: E722 Bare except
			realChildID = None
		if isinstance(realChildID, int) and realChildID > 0 and realChildID != childID:
			realObj = NVDAObjects.IAccessible.IAccessible(
				IAccessibleObject=obj.IAccessibleObject,
				IAccessibleChildID=realChildID,
				event_windowHandle=window,
				event_objectID=objectID,
				event_childID=realChildID
			)
			if realObj:
				obj = realObj
	return processFocusNVDAEvent(obj, force=force)
Esempio n. 59
0
def listUsbDevices(onlyAvailable=True):
    """List USB devices on the system.
	@param onlyAvailable: Only return devices that are currently available.
	@type onlyAvailable: bool
	@return: The USB vendor and product IDs in the form "VID_xxxx&PID_xxxx"
	@rtype: generator of unicode
	"""
    flags = DIGCF_DEVICEINTERFACE
    if onlyAvailable:
        flags |= DIGCF_PRESENT

    buf = ctypes.create_unicode_buffer(1024)
    g_hdi = SetupDiGetClassDevs(GUID_DEVINTERFACE_USB_DEVICE, None, NULL,
                                flags)
    try:
        for dwIndex in xrange(256):
            did = SP_DEVICE_INTERFACE_DATA()
            did.cbSize = ctypes.sizeof(did)

            if not SetupDiEnumDeviceInterfaces(
                    g_hdi, None, GUID_DEVINTERFACE_USB_DEVICE, dwIndex,
                    ctypes.byref(did)):
                if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:
                    raise ctypes.WinError()
                break

            dwNeeded = DWORD()
            # get the size
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded),
                    None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            # allocate buffer
            class SP_DEVICE_INTERFACE_DETAIL_DATA_W(ctypes.Structure):
                _fields_ = (
                    ('cbSize', DWORD),
                    ('DevicePath',
                     WCHAR * (dwNeeded.value - ctypes.sizeof(DWORD))),
                )

                def __str__(self):
                    return "DevicePath:%s" % (self.DevicePath, )

            idd = SP_DEVICE_INTERFACE_DETAIL_DATA_W()
            idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_W
            devinfo = SP_DEVINFO_DATA()
            devinfo.cbSize = ctypes.sizeof(devinfo)
            if not SetupDiGetDeviceInterfaceDetail(
                    g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded,
                    None, ctypes.byref(devinfo)):
                raise ctypes.WinError()

            # hardware ID
            if not SetupDiGetDeviceRegistryProperty(
                    g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None,
                    ctypes.byref(buf),
                    ctypes.sizeof(buf) - 1, None):
                # Ignore ERROR_INSUFFICIENT_BUFFER
                if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                    raise ctypes.WinError()
            else:
                # The string is of the form "usb\VID_xxxx&PID_xxxx&..."
                usbId = buf.value[4:21]  # VID_xxxx&PID_xxxx
                if _isDebug():
                    log.debug("%r" % usbId)
                yield usbId
    finally:
        SetupDiDestroyDeviceInfoList(g_hdi)
    if _isDebug():
        log.debug("Finished listing USB devices")
Esempio n. 60
0
 def stop(self):
     log.debug("Stop SystemTestSpyServer called")
     self._server.stop()