Package AccessEngine :: Module AEDeviceManager'
[hide private]
[frames] | no frames]

Source Code for Module AccessEngine.AEDeviceManager'

  1  ''' 
  2  Defines a class responsible for managing all input and output devices and 
  3  monitors. 
  4   
  5  @author: Larry Weiss 
  6  @author: Peter Parente 
  7  @author: Brett Clippingdale 
  8  @author: Scott Haeger 
  9  @organization: IBM Corporation 
 10  @copyright: Copyright (c) 2005, 2007 IBM Corporation 
 11   
 12  @author: Frank Zenker 
 13  @author: Martina Weicht 
 14  @author: Ramona Bunk 
 15  @organization: IT Science Center Ruegen gGmbH, Germany 
 16  @copyright: Copyright (c) 2007, 2008 ITSC Ruegen 
 17   
 18  @license: I{The BSD License} 
 19  All rights reserved. This program and the accompanying materials are made 
 20  available under the terms of the BSD license which accompanies 
 21  this distribution, and is available at 
 22  U{http://www.opensource.org/licenses/bsd-license.php} 
 23  ''' 
 24  import logging, sys 
 25  import AccessEngine 
 26  from AccessEngine import AERegistrar, AEEvent, AEOutput, AEInput, AEMonitor 
 27  from AEDevice.AEDeviceEvent import InputEvent, OutputEvent 
 28  import AEConstants 
 29  import SUEConstants 
 30  from AccessEngine.AEAccInterfaces import implements 
 31  from AERegistrar import DEVICE, MONITOR 
 32  from Tools.i18n import _ 
 33   
 34  log = logging.getLogger('Device') 
 35   
36 -class _AEDeviceManager(object):
37 ''' 38 Creates and manages the devices and monitors use by SUE. 39 40 Keeps a list of each and also defines a "default" for devices. Provides a 41 common interface to all output and input devices and mirrors I/O to the 42 monitors. Provides a mapping from output styles to semantic concepts in the 43 user interface to allow customization of how information is presented. 44 45 @note: RB: instance variable C{marks} is currently not used 46 47 @ivar out_devs: All output devices registered and initialized 48 @type out_devs: list 49 @ivar in_devs: All input devices registered and initialized 50 @type in_devs: list 51 @ivar in_mons: Collection of monitors to notify about input 52 @type in_mons: L{MonitorCollection <AEMonitor.MonitorCollection.MonitorCollection>} 53 @ivar out_mons: Collection of monitors to notify about output 54 @type out_mons: L{MonitorCollection <AEMonitor.MonitorCollection.MonitorCollection>} 55 @ivar marks: Maps index markers on devices 56 @type marks: dictionary 57 @ivar temp_devs: List of L{AEOutput <AEOutput.AEOutput>} and 58 L{AEInput <AEInput.AEInput>} devices last removed in 59 L{unloadDevices} and held until the next call of L{loadDevices}. 60 61 The purpose of this list is to ensure strong references to all devices exist, 62 and thus weak references are not destroyed, until the the L{AEDeviceManager} 63 is repopulated with devices. 64 @type temp_devs: list 65 ''' 66
67 - def __init__(self):
68 ''' 69 Creates the empty lists for devices and monitors. 70 ''' 71 self.out_devs = [] 72 self.in_devs = [] 73 self.in_mons = AEMonitor.MonitorCollection() 74 self.out_mons = AEMonitor.MonitorCollection() 75 self.marks = {} 76 self.temp_devs = []
77
78 - def init(self):
79 ''' 80 Loads all I/O monitors and devices to be created at startup. 81 82 Called by L{AEMain} at startup. 83 ''' 84 # load all I/O monitor classes to be created at startup 85 mons = AERegistrar.loadAssociated(MONITOR, 86 AccessEngine.AESettingsManager.getProfileName()) 87 self.addMonitors(*mons) 88 89 # load all device classes to be created at startup 90 self.loadDevices()
91
92 - def loadDevices(self):
93 ''' 94 Iterates over all devices in the active profile and loads ones that provide 95 functionality different from those already loaded. 96 ''' 97 devs = AERegistrar.loadAssociated(DEVICE, 98 AccessEngine.AESettingsManager.getProfileName()) 99 # register all devices, making the first input and output the defaults 100 for d in devs: 101 # call registerDevice which will automatically set defaults 102 try: 103 self.registerDevice(d) 104 except (AEOutput.AEOutputError, AEInput.AEInputError): 105 log.debug('could not initialize device: %s', d.getName()) 106 except NotImplementedError, e: 107 log.debug('device %s does not provide a new interface: %s' % 108 (d.getName(), str(e))) 109 110 # warn if we didn't initialize at least one output device 111 if not len(self.out_devs): 112 log.warn(_('no output available')) 113 if not len(self.in_devs): 114 log.warn(_('no input available')) 115 self.temp_devs = []
116
117 - def unloadDevices(self):
118 ''' 119 Unloads all devices from L{out_devs} and L{in_devs}, but keeps strong 120 references to all objects in L{temp_devs} until L{loadDevices} is called 121 again. 122 123 Keeping strong references ensures weak references in L{AEScript}s 124 continue to exist until the L{AEDeviceManager} has new devices available 125 for I/O. 126 ''' 127 for d in self.out_devs[:]: 128 self.temp_devs.append(d) 129 self.unregisterDevice(d)
130 #for d in self.in_devs: 131 #self.unregisterDevice(d) 132
133 - def close(self):
134 ''' 135 Shuts down this manager and all its registered 136 L{AEOutput <AEOutput.AEOutput>} and L{AEInput <AEInput.AEInput>} 137 devices and L{AEMonitor <AEMonitor.Base>}s. 138 139 Saves all style information for currently loaded devices. 140 ''' 141 for d in self.out_devs[:]: 142 self.unregisterDevice(d) 143 for d in self.in_devs[:]: 144 self.unregisterDevice(d) 145 self.in_mons.clear() 146 self.out_mons.clear()
147
148 - def send(self, dev, name, value, sem, layer):
149 ''' 150 Sends arbitrary data to a device. The device must recognize the name in 151 order to decide what to do with the value data. 152 153 This is a generic method which receives all content and commands to be 154 rendered and executed on a device. Standard name identifiers should be 155 used whenever possible. For instance, L{AEConstants.Output.CMD_STOP} and 156 L{AEConstants.Output.CMD_TALK}. However, device specific names and values 157 are certainly possible. 158 159 @param dev: Device that should receive the command 160 @type dev: L{AEOutput <AEOutput.AEOutput>} 161 @param name: Descriptor of the data value sent 162 @type name: object 163 @param value: Content value 164 @type value: object 165 @param sem: The semantic stream on which to send output; defaults to C{None} 166 for the default semantic. 167 @type sem: integer 168 @param layer: Layer on which the event occurred 169 @type layer: integer 170 171 @return: Return value specific to the given command 172 @rtype: object 173 ''' 174 # notify monitors 175 self.out_mons.show(OutputEvent(name), value=value, dev=dev, sem=sem, 176 layer=layer) 177 # quit if no device specified 178 if dev is None: return 179 if sem is None or layer is None: 180 try: 181 return dev.send(name, value, None) 182 except NotImplementedError: 183 return None 184 else: 185 style = dev.getStyle((sem, layer)) 186 # respect muting 187 if style.Mute: return 188 # send the data 189 try: 190 rv = dev.send(name, value, style) 191 except NotImplementedError: 192 # no return value when not implemented 193 rv = None 194 # mark the style as clean 195 style.makeClean() 196 return rv
197
198 - def sendStop(self, dev, sem, layer):
199 ''' 200 Sends the stop command to the referenced output device. 201 202 @param dev: Device that should receive the command 203 @type dev: L{AEOutput <AEOutput.AEOutput>} 204 @param sem: Semantic description of the information to stop or C{None} to 205 indicate stopping all output 206 @type sem: integer 207 @param layer: Layer on which the event occurred 208 @type layer: integer 209 ''' 210 # notify monitors 211 self.out_mons.show(OutputEvent(AEConstants.CMD_STOP), dev=dev, sem=sem, 212 layer=layer) 213 if dev is None: return 214 if sem is None and layer is None: 215 # send a global stop 216 dev.send(AEConstants.CMD_STOP, None, None) 217 elif sem is None: 218 # find all styles associated with the given layer 219 all = set([dev.getStyle((sem, layer)) for sem in 220 AEConstants.SEMANTIC_STYLES.keys()]) 221 for style in all: 222 dev.send(AEConstants.CMD_STOP, None, style) 223 else: 224 style = dev.getStyle((sem, layer)) 225 dev.send(AEConstants.CMD_STOP, None, style)
226
227 - def sendTalk(self, dev, sem, layer):
228 ''' 229 Tells the specified output device to send buffered data. 230 231 @param dev: Device that should receive the command 232 @type dev: L{AEOutput <AEOutput.AEOutput>} 233 @param sem: Semantic information to start outputting or C{None} to indicate 234 that all buffered information should be output 235 @type sem: integer 236 @param layer: Layer on which the event occurred 237 @type layer: integer 238 ''' 239 # notify monitors 240 self.out_mons.show(OutputEvent(AEConstants.CMD_TALK), dev=dev, sem=sem, 241 layer=layer) 242 if dev is None: return 243 if sem is None: 244 style = None 245 else: 246 style = dev.getStyle((sem, layer)) 247 # send the command 248 dev.send(AEConstants.CMD_TALK, None, style)
249
250 - def sendFilename(self, dev, filename, sem, layer):
251 ''' 252 Sends the filename to the specified output device. 253 254 @param dev: Device that should receive the command 255 @type dev: L{AEOutput <AEOutput.AEOutput>} 256 @param filename: The filename to send to the referenced device 257 @type filename: string 258 @param sem: Semantic description of the text to send or C{None} to indicate 259 the information is void of any known semantic 260 @type sem: integer 261 @param layer: Layer on which the event occurred 262 @type layer: integer 263 ''' 264 # notify monitors 265 # TODO: where does AEOutput.NAME_FILENAME come from? 266 self.out_mons.show(OutputEvent(AEOutput.NAME_FILENAME), value=filename, 267 dev=dev, sem=sem, layer=layer) 268 if dev is None: return 269 # find the style 270 style = dev.getStyle((sem, layer)) 271 # respect muting 272 if style.Mute: return 273 try: 274 dev.send(AEConstants.CMD_FILENAME, filename, style) 275 except NotImplementedError: 276 pass 277 # make the style clean 278 style.makeClean()
279
280 - def sendString(self, dev, text, sem, layer, por=None):
281 ''' 282 Sends the string to the specified output device. 283 284 @param dev: Device that should receive the command 285 @type dev: L{AEOutput <AEOutput.AEOutput>} 286 @param text: The text to send to the referenced device 287 @type text: string 288 @param sem: Semantic description of the text to send or C{None} to indicate 289 the information is void of any known semantic 290 @type sem: integer 291 @param layer: Layer on which the event occurred 292 @type layer: integer 293 @param por: Point of regard to the start of the string if one exists or 294 C{None} if the string did not originate from an L{AEPor <AEPor.AEPor>} 295 @type por: L{AEPor <AEPor.AEPor>} 296 ''' 297 # notify monitors 298 self.out_mons.show(OutputEvent(AEConstants.CMD_STRING), value=text, 299 dev=dev, sem=sem, layer=layer) 300 if dev is None: return 301 # get the style 302 style = dev.getStyle((sem, layer)) 303 # respect muting 304 if style.Mute: return 305 # parse the string using the current style 306 parsed = dev.parseString(text, style, por, sem) 307 # send all words, pors, and styles 308 for word, por, new_style in parsed: 309 dev.send(AEConstants.CMD_STRING, word, new_style) 310 # mark the style as clean 311 new_style.makeClean() 312 # mark the style clean 313 style.makeClean()
314
315 - def sendIndex(self, dev, sem, layer):
316 ''' 317 Sends the referenced index marker to the referenced device. 318 319 @param dev: Device that should receive the command 320 @type dev: L{AEOutput <AEOutput.AEOutput>} 321 @param sem: Semantic description of the index text to send or C{None} to 322 indicate the information is void of any known semantic 323 @type sem: integer 324 @param layer: Layer on which the event occurred 325 @type layer: integer 326 ''' 327 # notify registered monitors 328 self.out_mons.show(OutputEvent(AEConstants.CMD_INDEX), dev=dev, sem=sem, 329 layer=layer) 330 if dev is None: return 331 # get the style 332 style = dev.getStyle((sem, layer)) 333 # respect muting 334 if style.Mute: return 335 try: 336 # generate a new marker on the device 337 mark = dev.send(AEConstants.CMD_INDEX, None, style) 338 except NotImplementedError: 339 # do nothing when indexing not implemented 340 return
341 # store the mark and associated data for later retrieval 342 #self.marks[(dev, mark)] = (sem, layer, data) 343
344 - def sendWelcome(self):
345 ''' 346 Outputs the SUE welcome message on all output devices. 347 348 Instead of just sending the message to the default output device, 349 it is now sent to all output devices, so you know your braille display 350 works properly. 351 352 One question remains: Is there a case where you would not want a welcome 353 message sent to an output device? 354 ''' 355 356 msg = _('welcome to %s version %s, revision %s') % \ 357 (SUEConstants.NAME, SUEConstants.PROG_VERSION, SUEConstants.PROG_DATE) 358 359 try: 360 for dev in self.out_devs: 361 st = dev.getStyle((AEConstants.SEM_ITEM, AEConstants.LAYER_FOCUS)) 362 dev.send(AEConstants.CMD_STRING, msg, st) 363 dev.send(AEConstants.CMD_TALK, None) 364 except IndexError: 365 # no output available 366 return
367
368 - def sendGoodbye(self):
369 ''' 370 Outputs the SUE goodbye message on all output devices. 371 372 Instead of just sending the message to the default output device, 373 it is now sent to all output devices. 374 375 One question remains: Is there a case where you would not want a goodbye 376 message sent to your output device? 377 ''' 378 try: 379 for dev in self.out_devs: 380 st = dev.getStyle((AEConstants.SEM_ITEM, AEConstants.LAYER_FOCUS)) 381 dev.send(AEConstants.CMD_STRING_SYNC, _('sue exiting'), st) 382 except IndexError: 383 # no output available 384 return
385 386
387 - def _isDuplicateDevice(self, dev, output):
388 ''' 389 Checks if the given device is a duplicate in that it provides no new 390 interfaces beyond those provided by the devices already registered. 391 392 @param dev: A device class 393 @type dev: L{AEInput <AEInput.AEInput>} or L{AEOutput <AEOutput.AEOutput>} class 394 @param output: Is the device an output device (C{True}) or input (C{False})? 395 @type output: boolean 396 ''' 397 if output: 398 reg_devs = self.out_devs 399 else: 400 reg_devs = self.in_devs 401 # get interfaces device implements 402 dev_int = dev.getCapabilities() 403 # check if some registered device already implements all of these 404 # interfaces 405 for reg_dev in reg_devs: 406 reg_int = reg_dev.getCapabilities() 407 if set(reg_int).issuperset(dev_int): 408 return True 409 return False
410
411 - def _registerInputDevice(self, dev):
412 ''' 413 Registers the given device as an input device if the device implements the 414 L{AEInput <AEInput.AEInput>} base class and provides some 415 capabilities not already provided by another registered input device. 416 417 For instance, if a device reports it supports the "system keyboard" 418 capability, no other system keyboard device will be loaded. 419 420 @param dev: Device to attempt to register 421 @type dev: L{AEInput <AEInput.AEInput>} 422 @return: C{True} if the device was registered, C{False} if it is not an 423 L{AEInput <AEInput.AEInput>} device, and C{None} if it provides no 424 new interfaces. 425 @rtype: boolean or None 426 ''' 427 if not implements(dev, AEInput.AEInput): 428 # don't register something that isn't an input device 429 return False 430 if self._isDuplicateDevice(dev, False): 431 # don't register a device that provides all the same interfaces as a 432 # previous device 433 return False 434 if dev not in self.out_devs: 435 # don't reinitialize a device that was added to out_devs 436 dev.init() 437 # add DeviceManager as a gesture listener 438 dev.addInputListener(self._onGesture) 439 # append to the in_devs list after successfully initialized 440 self.in_devs.append(dev) 441 log.debug('added input device %s', str(dev)) 442 return True
443
444 - def _unregisterInputDevice(self, dev):
445 ''' 446 Unregisters the given input device. Removes this manager from 447 the list of gesture listeners stored in the device. 448 449 @param dev: Device to unregister 450 @type dev: L{AEInput <AEInput.AEInput>} 451 ''' 452 try: 453 # remove from list of input devices 454 self.in_devs.remove(dev) 455 log.debug('removed input device %s', dev.getName()) 456 except ValueError: 457 pass 458 try: 459 # do not observe gestures 460 dev.removeInputListener(self._onGesture) 461 except AttributeError: 462 pass
463
464 - def _unregisterOutputDevice(self, dev):
465 ''' 466 Unregisters the given output device. 467 468 Provides the device with a reference to the L{AESettingsManager} so it can 469 save state. Removes this manager from the list of index listeners stored in 470 the device. 471 472 @param dev: Device to unregister 473 @type dev: L{AEOutput <AEOutput.AEOutput>} 474 ''' 475 try: 476 # let an output device save its styles 477 dev.saveStyles() 478 except AttributeError: 479 pass 480 try: 481 # remove from list of output devices 482 self.out_devs.remove(dev) 483 log.debug('removed output device %s', dev.getName()) 484 except ValueError: 485 pass 486 try: 487 # do not observe indices 488 dev.removeIndexListener(self._onIndex) 489 except AttributeError: 490 pass
491
492 - def _registerOutputDevice(self, dev):
493 ''' 494 Registers the given device as an output device if the device implements the 495 L{AEOutput <AEOutput.AEOutput>} base class and provides some subinterface 496 not already provided by another registered output device. 497 498 For instance, if a device reports having "audio" capability, no other device 499 providing just this capability will be loaded. 500 501 @param dev: Device to attempt to register 502 @type dev: L{AEOutput <AEOutput.AEOutput>} 503 @return: C{True} if the device was registered, 504 C{False} if it is not an L{AEOutput <AEOutput.AEOutput>} device, and 505 C{None} if it provides no new interfaces 506 @rtype: boolean or None 507 ''' 508 if not implements(dev, AEOutput.AEOutput): 509 # don't register something that isn't an output device 510 return False 511 dev = dev.getProxy() 512 #if self._isDuplicateDevice(dev, True): 513 # mw: im zuge der ueberlegungen zum braillemonitor wollen wir auch dupalicate devices zulassen 514 #if self._isDuplicateDevice(dev, True): 515 # don't register a device that provides all the same interfaces as a 516 # previous device 517 #return None 518 if dev not in self.in_devs: 519 # don't reinitialize a device that was added to in_devs 520 dev.init() 521 # add DeviceManager as an index listener when implemented 522 try: 523 dev.addIndexListener(self._onIndex) 524 except (AttributeError, NotImplementedError): 525 # do nothing when indexing not implemented or supported 526 pass 527 # append to the out_devs list after successfully initialized 528 self.out_devs.append(dev) 529 log.debug('added output device %s', str(dev)) 530 # first output device registered is default 531 532 try: 533 # try to load styles for the device 534 dev.loadStyles() 535 except KeyError: 536 # or initialize new output styles 537 self._initOutputStyles(dev) 538 # finally, always call postInit to let the device do more initialization 539 # after the styles are available 540 dev.postInit() 541 return True
542
543 - def _initOutputStyles(self, dev):
544 ''' 545 Initializes styles for an L{AEOutput <AEOutput.AEOutput>} device. 546 547 Calls L{AEOutput.AEOutput.createDistinctStyles 548 <AEDevice.AEOutput.Base.AEOutput.createDistinctStyles>} on the device to get 549 an initial batch of styles to use to distinguish some types of information. 550 If that method is not implemented, the exception is ignored. 551 552 Future requests to use styles per semantic tag will resort to making 553 flyweights for the default style on the device. 554 555 @param dev: Device reference 556 @type dev: L{AEOutput <AEOutput.AEOutput>} 557 ''' 558 # create styles based on the abilities of this device 559 num_layers = len(AEConstants.LAYERS_ALL) 560 num_groups = len(AEConstants.STYLE_GROUP_ALL) 561 try: 562 styles = dev.createDistinctStyles(num_groups, num_layers) 563 except NotImplementedError: 564 return 565 # create semantics, layer to styles mapping for device 566 for layer, i in enumerate(AEConstants.LAYERS_ALL): 567 # provide a default style for a semantic of None 568 s = styles[i*num_groups] 569 dev.setStyle((None, layer), s) 570 for sem, grp in AEConstants.SEMANTIC_STYLES.items(): 571 # provide a style for (semantic, layer, device) 572 s = styles[i*num_groups + (grp % num_groups)] 573 dev.setStyle((sem, layer), s)
574
575 - def registerDevice(self, dev):
576 ''' 577 Registers the referenced device based on its one or more interfaces. 578 579 When the interface is determined, the C{init()} method is called on the 580 device. 581 582 @param dev: The device to register 583 @type dev: L{AEOutput <AEOutput.AEOutput>} or L{AEInput <AEInput.AEInput>} 584 @raise NotImplementedError: When the device implements none of the required 585 interfaces 586 @raise AEOutputError: When output device initialization fails 587 @raise AEInputError: When input device initialization fails 588 ''' 589 is_out = self._registerOutputDevice(dev) 590 is_in = self._registerInputDevice(dev) 591 592 if is_out == False and is_in == False: 593 # raise an exception if none of the required interfaces was implemented 594 raise NotImplementedError
595
596 - def unregisterDevice(self, dev):
597 ''' 598 Unregisters a device from both the input and output lists based on its 599 capabilities. 600 601 @param dev: The device to unregister 602 @type dev: L{AEOutput <AEOutput.AEOutput>} or L{AEInput <AEInput.AEInput>} 603 ''' 604 try: 605 dev.close() 606 except Exception: 607 pass 608 self._unregisterOutputDevice(dev) 609 self._unregisterInputDevice(dev)
610
611 - def addMonitors(self, *monitors):
612 ''' 613 Adds one or more L{AEMonitor <AEMonitor.AEMonitor>}s to the list of monitors 614 to be notified about IO events. 615 616 @param monitors: L{AEMonitor <AEMonitor.AEMonitor>}s to notify 617 @type monitors: tuple of L{AEMonitor <AEMonitor.AEMonitor>}s 618 ''' 619 self.in_mons.add(InputEvent, monitors) 620 self.out_mons.add(OutputEvent, monitors)
621
622 - def getMonitors(self):
623 ''' 624 Gets all loaded input and output L{AEMonitor <AEMonitor.AEMonitor>}s. 625 626 @return: Collections of all loaded input and output 627 L{AEMonitor <AEMonitor.AEMonitor>}s in that order 628 @rtype: 2-tuple L{AEMonitor.MonitorCollection} 629 ''' 630 return self.in_mons, self.out_mons
631
632 - def getFirstOutput(self):
633 ''' 634 Gets the first L{AEOutput <AEOutput.AEOutput>} device to successfully load. 635 636 @return: First loaded output device or C{None} if no output is available 637 @rtype: L{AEOutput <AEOutput.AEOutput>} 638 ''' 639 try: 640 return self.out_devs[0] 641 except IndexError: 642 return None
643
644 - def getOutputByName(self, name):
645 ''' 646 Gets the L{AEOutput <AEOutput.AEOutput>} device registered under the given 647 name. 648 649 @param name: Name of the output device 650 @type name: string 651 @return: Output device or C{None} if not registered 652 @rtype: L{AEOutput <AEOutput.AEOutput>} 653 ''' 654 for dev in self.out_devs: 655 if dev.getClassName() == name: 656 return dev 657 return None
658
659 - def getOutputByCaps(self, caps):
660 ''' 661 Gets all L{AEOutput <AEOutput.AEOutput>} devices registered with the given 662 capabilities. 663 664 @note: MW: We decided not to limit output devices to unique capabilities anymore. 665 Instead roles are used to distingish the devices' funtions. 666 667 @param caps: Desired capabilities of the output device. 668 @type caps: list of string 669 @return: Output devices or C{None} if caps could not be satisfied 670 @rtype: L{AEOutput <AEOutput.AEOutput>} 671 ''' 672 cap_devs = [] 673 for dev in self.out_devs: 674 if set(dev.getCapabilities()).issuperset(caps): 675 cap_devs.append(dev) 676 return cap_devs
677
678 - def getInputByName(self, name):
679 ''' 680 Gets the L{AEInput <AEInput.AEInput>} device registered under the given name. 681 682 @param name: Name of the input device 683 @type name: string 684 @return: Input device or C{None} if not registered 685 @rtype: L{AEInput <AEInput.AEInput>} 686 ''' 687 for dev in self.in_devs: 688 if dev.getClassName() == name: 689 return dev 690 return None
691
692 - def getInputByCaps(self, caps):
693 ''' 694 Gets the L{AEInput <AEInput.AEInput>} device registered with the given 695 capabilities. 696 697 @param caps: Desired capabilities of the input device. 698 @type caps: list of string 699 @return: Output device or C{None} if C{caps} could not be satisfied 700 @rtype: L{AEOutput <AEOutput.AEOutput>} 701 ''' 702 for dev in self.in_devs: 703 if set(dev.getCapabilities()).issuperset(caps): 704 return dev 705 return None
706
707 - def _onGesture(self, gesture, timestamp, **kwargs):
708 ''' 709 Creates an L{AEEvent <AEEvent.AEEvent>} indicating the given gesture was 710 found on a registered input device. 711 712 When executed, the L{AEEvent <AEEvent.AEEvent>} will notify the 713 L{AETierManager} about the gesture and allow it to activate the appropriate 714 script task, which is registered to respond to the gesture in the active 715 L{AETier}. 716 717 @param gesture: Gesture seen on an input device 718 @type gesture: L{AEInput.Gesture} 719 @param timestamp: Time at which the event occurred 720 @type timestamp: float 721 @param kwargs: Additional keyword arguments to pass to the script task 722 @type kwargs: dictionary 723 ''' 724 event = AEEvent.InputGesture(gesture, timestamp, **kwargs) 725 AccessEngine.AEEventManager.postEvents(event) 726 # notify monitors 727 self.in_mons.show(InputEvent(AEConstants.CMD_GESTURE), value=gesture, 728 dev=gesture.getDevice())
729
730 - def _onIndex(self, dev, index):
731 ''' 732 @todo: RB: Taken over from LSR. Used in L{_unregisterOutputDevice} and 733 L{_registerOutputDevice}. This function needs to be implemented or 734 removed. (Note: This function isn't implemented in any subclass either, 735 because there are no subclasses of _AEDeviceManager) 736 ''' 737 pass
738 # notify monitors 739 #self.out_mons.show(event=OutputEvent.MARKER) 740
741 - def getDevices(self):
742 ''' 743 Gets a list of all loaded devices. 744 745 @return: References to all loaded devices 746 @rtype: list of L{AEUserInterface <AccessEngine.AEUserInterface.AEUserInterface>} 747 ''' 748 return list(set(self.in_devs).union(self.out_devs))
749
750 - def getStyle(self, dev, sem, layer):
751 ''' 752 Gets the style for semantic/layer of a given device. 753 754 @param dev: The device from which to get the style. 755 @type dev: L{AEOutput <AEOutput.AEOutput>} 756 @param sem: The device semantic from which to get the style, or C{None} to 757 get the device's default style. 758 @type sem: integer 759 @param layer: Layer on which the event occurred 760 @type layer: integer 761 @return: the L{AEOutput.Style} for the given semantic of a device 762 @rtype: L{AEOutput.Style} 763 @raise KeyError: When the semantic or layer is invalid 764 ''' 765 if dev is None: return None 766 if sem is None or layer is None: 767 return dev.getDefaultStyle() 768 return dev.getStyle((sem, layer))
769