diff -Naur pyspi-0.6.1-old/cspi.pxd pyspi-0.6.1/cspi.pxd --- pyspi-0.6.1-old/cspi.pxd 2006-08-04 06:27:10.000000000 +1000 +++ pyspi-0.6.1/cspi.pxd 2009-05-09 15:24:31.000000000 +1000 @@ -14,9 +14,7 @@ ctypedef struct AccessibleTextRange ctypedef struct AccessibleKeySet - ctypedef enum SPIBoolean: - FALSE = 0, - TRUE + ctypedef unsigned int SPIBoolean ctypedef struct AccessibleEvent: char *type diff -Naur pyspi-0.6.1-old/pyspi.pyx pyspi-0.6.1/pyspi.pyx --- pyspi-0.6.1-old/pyspi.pyx 2006-10-03 02:46:41.000000000 +1000 +++ pyspi-0.6.1/pyspi.pyx 2009-05-09 15:24:31.000000000 +1000 @@ -25,9 +25,15 @@ cdef class Event (EventBase) cdef class DeviceEvent -ctypedef enum bool: +ctypedef unsigned int bool + +import __builtin__ +try: + False = __builtin__.False + True = __builtin__.True +except AttributeError: False = 0 - True + True = 1 # SPIExceptionCode values: (SPI_EXCEPTION_UNSPECIFIED, SPI_EXCEPTION_DISCONNECT, SPI_EXCEPTION_NO_IMPL, SPI_EXCEPTION_IO, SPI_EXCEPTION_BAD_DATA)=range(5) @@ -731,7 +737,7 @@ Wrapper around the low-level cspi.AccessibleComponent_ functions, giving an OO-style API. """ - def getExtents (self, type=0): + def getExtents (self, key_type=0): """ Wraps cspi.AccessibleComponent_getExtents, returning an (x,y,w,h) tuple. @@ -741,7 +747,7 @@ cspi.AccessibleComponent_getExtents (self.__item, &x, &y, &w, &h, type) return (x, y, w, h) - def getPosition (self, type = 0): + def getPosition (self, key_type = 0): """ Wraps cspi.AccessibleComponent_getPosition, returning an (x,y) tuple. @@ -991,11 +997,11 @@ Wraps cspi.AccessibleHyperlink_getObject """ self.__checkSelf () - cdef Accessible object - object = Accessible () - object.__setItem (cspi.AccessibleHyperlink_getObject (self.__item, i)) - object.__checkSelf () - return object + cdef Accessible obj + obj = Accessible () + obj.__setItem (cspi.AccessibleHyperlink_getObject (self.__item, i)) + obj.__checkSelf () + return obj def getURI (self, i): """ @@ -1032,7 +1038,7 @@ cspi.AccessibleImage_getImageSize(self.__item, &w, &h); return [w, h] - def getImagePosition (self, type=0): + def getImagePosition (self, key_type=0): """ Wraps cspi.AccessibleImage_getImagePosition, returning a (x,y) pair @@ -1042,7 +1048,7 @@ cspi.AccessibleImage_getImagePosition(self.__item, &x, &y, type) return [x, y] - def getImageExtents (self, type=0): + def getImageExtents (self, key_type=0): """ Wraps cspi.AccessibleImage_getImageExtents, returning a (x,y,w,h) tuple @@ -1551,7 +1557,7 @@ cdef cspi.AccessibleDeviceListener *__item cdef public object modMasks - def __init__ (self, callback, eventMask = cspi.SPI_KEY_PRESSED | cspi.SPI_KEY_RELEASED): + def __init__ (self, callback, eventMask = cspi.SPI_KEY_PRESSED | cspi.SPI_KEY_RELEASED): """ Registers a python callback function to be called. diff -Naur pyspi-0.6.1-old/pyspi.pyx.orig pyspi-0.6.1/pyspi.pyx.orig --- pyspi-0.6.1-old/pyspi.pyx.orig 1970-01-01 10:00:00.000000000 +1000 +++ pyspi-0.6.1/pyspi.pyx.orig 2006-10-03 02:46:41.000000000 +1000 @@ -0,0 +1,1592 @@ +# Authors: +# Zack Cerza +# Chris Lee +# Lawrence Lim +# David Malcolm + +cdef class Registry + +cdef class Base +cdef class EventBase +cdef class StateSet +cdef class Accessible (Base) +cdef class Desktop (Accessible) +cdef class Application (Accessible) +cdef class Component (Accessible) +cdef class Action (Base) +cdef class Text (Base) +cdef class EditableText (Text) +cdef class Hypertext (Text) +cdef class Hyperlink (Base) +cdef class Image (Base) +cdef class Value (Base) +cdef class Selection (Base) +cdef class Table (Base) +cdef class Event (EventBase) +cdef class DeviceEvent + +ctypedef enum bool: + False = 0 + True + +# SPIExceptionCode values: +(SPI_EXCEPTION_UNSPECIFIED, SPI_EXCEPTION_DISCONNECT, SPI_EXCEPTION_NO_IMPL, SPI_EXCEPTION_IO, SPI_EXCEPTION_BAD_DATA)=range(5) + +# SPIExceptionType values: +(SPI_EXCEPTION_SOURCE_UNSPECIFIED, SPI_EXCEPTION_SOURCE_ACCESSIBLE, SPI_EXCEPTION_SOURCE_REGISTRY, SPI_EXCEPTION_SOURCE_DEVICE)=range(4) + +# Accessible roles +(SPI_ROLE_INVALID, SPI_ROLE_ACCEL_LABEL, SPI_ROLE_ALERT, SPI_ROLE_ANIMATION, SPI_ROLE_ARROW, SPI_ROLE_CALENDAR, SPI_ROLE_CANVAS, SPI_ROLE_CHECK_BOX, SPI_ROLE_CHECK_MENU_ITEM, SPI_ROLE_COLOR_CHOOSER, SPI_ROLE_COLUMN_HEADER, SPI_ROLE_COMBO_BOX, SPI_ROLE_DATE_EDITOR, SPI_ROLE_DESKTOP_ICON, SPI_ROLE_DESKTOP_FRAME, SPI_ROLE_DIAL, SPI_ROLE_DIALOG, SPI_ROLE_DIRECTORY_PANE, SPI_ROLE_DRAWING_AREA, SPI_ROLE_FILE_CHOOSER, SPI_ROLE_FILLER, SPI_ROLE_FONT_CHOOSER, SPI_ROLE_FRAME, SPI_ROLE_GLASS_PANE, SPI_ROLE_HTML_CONTAINER, SPI_ROLE_ICON, SPI_ROLE_IMAGE, SPI_ROLE_INTERNAL_FRAME, SPI_ROLE_LABEL, SPI_ROLE_LAYERED_PANE, SPI_ROLE_LIST, SPI_ROLE_LIST_ITEM, SPI_ROLE_MENU, SPI_ROLE_MENU_BAR, SPI_ROLE_MENU_ITEM, SPI_ROLE_OPTION_PANE, SPI_ROLE_PAGE_TAB, SPI_ROLE_PAGE_TAB_LIST, SPI_ROLE_PANEL, SPI_ROLE_PASSWORD_TEXT, SPI_ROLE_POPUP_MENU, SPI_ROLE_PROGRESS_BAR, SPI_ROLE_PUSH_BUTTON, SPI_ROLE_RADIO_BUTTON, SPI_ROLE_RADIO_MENU_ITEM, SPI_ROLE_ROOT_PANE, SPI_ROLE_ROW_HEADER, SPI_ROLE_SCROLL_BAR, SPI_ROLE_SCROLL_PANE, SPI_ROLE_SEPARATOR, SPI_ROLE_SLIDER, SPI_ROLE_SPIN_BUTTON, SPI_ROLE_SPLIT_PANE, SPI_ROLE_STATUS_BAR, SPI_ROLE_TABLE, SPI_ROLE_TABLE_CELL, SPI_ROLE_TABLE_COLUMN_HEADER, SPI_ROLE_TABLE_ROW_HEADER, SPI_ROLE_TEAROFF_MENU_ITEM, SPI_ROLE_TERMINAL, SPI_ROLE_TEXT, SPI_ROLE_TOGGLE_BUTTON, SPI_ROLE_TOOL_BAR, SPI_ROLE_TOOL_TIP, SPI_ROLE_TREE, SPI_ROLE_TREE_TABLE, SPI_ROLE_UNKNOWN, SPI_ROLE_VIEWPORT, SPI_ROLE_WINDOW, SPI_ROLE_EXTENDED, SPI_ROLE_HEADER, SPI_ROLE_FOOTER, SPI_ROLE_PARAGRAPH, SPI_ROLE_RULER, SPI_ROLE_APPLICATION, SPI_ROLE_AUTOCOMPLETE, SPI_ROLE_EDITBAR, SPI_ROLE_EMBEDDED, SPI_ROLE_LAST_DEFINED)=range(79) + +# Accessible states +(SPI_STATE_INVALID, SPI_STATE_ACTIVE, SPI_STATE_ARMED, SPI_STATE_BUSY, SPI_STATE_CHECKED, SPI_STATE_COLLAPSED, SPI_STATE_DEFUNCT, SPI_STATE_EDITABLE, SPI_STATE_ENABLED, SPI_STATE_EXPANDABLE, SPI_STATE_EXPANDED, SPI_STATE_FOCUSABLE, SPI_STATE_FOCUSED, SPI_STATE_HORIZONTAL, SPI_STATE_ICONIFIED, SPI_STATE_MODAL, SPI_STATE_MULTI_LINE, SPI_STATE_MULTISELECTABLE, SPI_STATE_OPAQUE, SPI_STATE_PRESSED, SPI_STATE_RESIZABLE, SPI_STATE_SELECTABLE, SPI_STATE_SELECTED, SPI_STATE_SENSITIVE, SPI_STATE_SHOWING, SPI_STATE_SINGLE_LINE, SPI_STATE_STALE, SPI_STATE_TRANSIENT, SPI_STATE_VERTICAL, SPI_STATE_VISIBLE, SPI_STATE_MANAGES_DESCENDANTS, SPI_STATE_INDETERMINATE) = range(32); + +# Accessible relation types +(SPI_RELATION_NULL, SPI_RELATION_LABEL_FOR, SPI_RELATION_LABELED_BY, SPI_RELATION_CONTROLLER_FOR, SPI_RELATION_CONTROLLED_BY, SPI_RELATION_MEMBER_OF, SPI_RELATION_NODE_CHILD_OF, SPI_RELATION_EXTENDED, SPI_RELATION_FLOWS_TO, SPI_RELATION_FLOWS_FROM, SPI_RELATION_SUBWINDOW_OF, SPI_RELATION_EMBEDS, SPI_RELATION_EMBEDDED_BY, SPI_RELATION_POPUP_FOR, SPI_RELATION_LAST_DEFINED) = range (15); + +# AccessibleComponent layers +(SPI_LAYER_INVALID, SPI_LAYER_BACKGROUND, SPI_LAYER_CANVAS, SPI_LAYER_WIDGET, SPI_LAYER_MDI, SPI_LAYER_POPUP, SPI_LAYER_OVERLAY, SPI_LAYER_WINDOW, SPI_LAYER_LAST_DEFINED) = range(9) + +#AccessibleKeySynthType +(SPI_KEY_PRESS, SPI_KEY_RELEASE, SPI_KEY_PRESSRELEASE, SPI_KEY_SYM, SPI_KEY_STRING) = range(5) + +# AccessibleKeyListenerSyncType +(SPI_KEYLISTENER_NOSYNC, SPI_KEYLISTENER_SYNCHRONOUS, SPI_KEYLISTENER_CANCONSUME, SPI_KEYLISTENER_ALL_WINDOWS) = range(4) + +# AccessibleDeviceEventType +SPI_KEY_PRESSED = 1<<0 +SPI_KEY_RELEASED = 1<<1 +SPI_BUTTON_PRESSED = 1<<2 +SPI_BUTTON_RELEASED = 1<<3 + +cdef cspi.AccessibleKeySet *SPI_KEYSET_ALL_KEYS +SPI_KEYSET_ALL_KEYS = NULL + +Accessibility_MODIFIER_SHIFT = 1 << 0 +Accessibility_MODIFIER_SHIFTLOCK = 1 << 1 +Accessibility_MODIFIER_CONTROL = 1 << 2 +Accessibility_MODIFIER_ALT = 1 << 3 +Accessibility_MODIFIER_META = 1 << 4 +Accessibility_MODIFIER_META2 = 1 << 5 +Accessibility_MODIFIER_META3 = 1 << 6 +Accessibility_MODIFIER_NUMLOCK = 1 << 7 + + +cdef object string(char * string): + cdef object pyString + pyString = string + cspi.SPI_freeString(string) + return pyString + +import os +class X11Exception(Exception): + def __init__(self, display = os.environ.get('DISPLAY', None)): + self.display = display + def __str__(self): + msg = "Cannot open display" + if self.display: return msg + ': ' + self.display + else: return msg + +class AtspiException(Exception): + """ + Exceptions raised when calls to the AT-SPI C bindings return FALSE to + indicate failure. + """ + def __init__(self, message): + self.message = message + + def __str__(self): + return "AtspiException: %s"%self.message + +class SpiException(Exception): + """ + Exceptions to be raised in response to an installed + SPIExceptionHandler, corresponding to a SPIException. These appear to + be short-lived structs, so we gather all applicable data immediately + """ + def __init__(self, is_fatal, sourceType, exceptionCode, description): + # print "got to __init__" + self.fatal = is_fatal + self.sourceType = sourceType + self.exceptionCode = exceptionCode + self.description = description + + # print "leaving __init__" + # print self.fatal + # print self.sourceType + # print self.exceptionCode + # print self.description + + def __str__(self): + if self.fatal: + fatalStr = "Fatal" + else: + fatalStr = "Non-fatal" + result = '%s SPIException: type:%s source:%s "%s"'%(fatalStr, self.sourceType, self.exceptionCode, self.description) + return result + +cdef make_exception(cspi.SPIException *err, cspi.SPIBoolean is_fatal): + # Don't attempt to use SPIAccessibleException_getSource; this is error + # handling code, we don't want to introduce further complications + return SpiException(is_fatal, + cspi.SPIException_getSourceType (err), + cspi.SPIException_getExceptionCode (err), + cspi.SPIException_getDescription (err)) + + +def event_main(): + cspi.SPI_event_main() + +def event_quit(): + cspi.SPI_event_quit() + +cdef cspi.SPIBoolean exception_handler (cspi.SPIException *err, cspi.SPIBoolean is_fatal) except *: + # print "got exception!!!" + e = make_exception(err, is_fatal) + raise e + +# at-spi-/cpsi.h contains: +# typedef SPIBoolean (*SPIExceptionHandler) (SPIException *err, SPIBoolean is_fatal); +# and +# SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler); +# There's thus an extra unnecessary level of indirection. +# We have to jump through the following hoops to get pyrex to deal with this: +cdef cspi.SPIExceptionHandler exception_handler_as_type +cdef cspi.SPIExceptionHandler* exception_handler_ptr +exception_handler_as_type = exception_handler +exception_handler_ptr = &exception_handler_as_type + +global_exception = None + +cdef class Registry: + def __init__ (self): + cdef Xlib.Display *display + display = Xlib.XOpenDisplay(NULL) + if display == NULL: + raise X11Exception + else: + Xlib.XCloseDisplay(display) + + result = cspi.SPI_init () + #if result!=0: + # raise AtspiException("SPI_init: exit code %s" % str(result)) + + result = cspi.SPI_exceptionHandlerPush (exception_handler_ptr) + if not result: + raise AtspiException("Unable to install SPI exception handler") + + def __dealloc (self): + result = cspi.SPI_exit () + if result!=0: + raise AtspiException("SPI_init: exit code %s" % str(result)) + + def getDesktopCount (self): + return cspi.SPI_getDesktopCount() + + def getDesktop (self, index = 0): + cdef Desktop desktop + desktop = Desktop () + if not desktop.__setItem (cspi.SPI_getDesktop (index)): + return False + return desktop + + def getDesktopList (self): + # Using the bonobo.activation bindings, getDesktopList() returns a + # Python list of Desktop objects. The C bindings seem to do it differently, + # and Pyrex doesn't like that method. So we're re-implementing the function + # using getDesktopCount() and getDesktop() to work around that. + # Yay for Zack! + # + # -Zack + cdef Desktop desktop + desktops = [] + desktop = Desktop () + for i in xrange (cspi.SPI_getDesktopCount ()): + desktop.__setItem (cspi.SPI_getDesktop (i)) + desktops = desktops + [desktop] + return desktops + +registry = Registry() + +cdef class Base: + """ + Wrapper around a cspi.Accessible + """ + + cdef cspi.Accessible *__item + + def __new__ (self): + self.__item = NULL + + def __dealloc__ (self): + if self.__item != NULL: + cspi.Accessible_unref (self.__item) + + cdef bool __setItem (self, cspi.Accessible *obj): + if self.__item != NULL: + cspi.Accessible_unref (self.__item) + if obj != NULL: + self.__item = obj + cspi.Accessible_ref (self.__item) + return True + else: + return False + + def __checkSelf (self): + assert self.__item != NULL + +# WHY OH WHY won't this work? :( +# I need to be able to find out of two Accessible classes contain +# the same cspi.Accessible objects. +# +# def isSameAs (self, base): +# cdef bool foo +# foo = self.__item == base.__item +# return foo + +cdef class EventBase: + """ + Wrapper around a cspi.AccessibleEvent + """ + cdef cspi.AccessibleEvent *__item + + def __new__ (self): + self.__item = NULL + + def __dealloc__ (self): + if self.__item != NULL: + cspi.AccessibleEvent_unref (self.__item) + + cdef bool __setItem (self, cspi.AccessibleEvent *obj): + if self.__item != NULL: + cspi.AccessibleEvent_unref (self.__item) + if obj != NULL: + self.__item = obj + cspi.AccessibleEvent_ref (self.__item) + return True + else: + return False + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + + def __getattr__ (self, attrName): + cdef cspi.Accessible* acc + cdef Accessible result + if attrName == "source": + acc = self.__item.source + if acc!=NULL: + result = Accessible () + result.__setItem (acc) + return result + elif attrName == "detail1": + detail1 = self.__item.detail1 + return detail1 + elif attrName == "detail2": + detail1 = self.__item.detail2 + return detail1 + elif attrName == "type": + return self.__item.type + +cdef class StateSet: + """ + Wrapper around a cspi.AccessibleStateSet + """ + cdef cspi.AccessibleStateSet *__item + + def __new__ (self): + self.__item = NULL + + def __dealloc__ (self): + if self.__item != NULL: + cspi.AccessibleStateSet_unref (self.__item) + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + + cdef bool __setItem (self, cspi.AccessibleStateSet *obj): + if self.__item != NULL: + cspi.AccessibleStateSet_unref (self.__item) + if obj != NULL: + self.__item = obj + cspi.AccessibleStateSet_ref (self.__item) + return True + else: + return False + + cdef bool __contains (self, cspi.AccessibleState s): + self.__checkSelf () + return cspi.AccessibleStateSet_contains (self.__item, s) + + def contains (self, state): + self.__checkSelf () + return self.__contains(state) + + cdef void __add (self, cspi.AccessibleState s): + self.__checkSelf () + cspi.AccessibleStateSet_add(self.__item, s) + + def add (self, state): + self.__checkSelf () + self.__add (state) + + cdef void __remove (self, cspi.AccessibleState s): + self.__checkSelf () + cspi.AccessibleStateSet_remove (self.__item, s) + + def remove (self, state): + self.__checkSelf () + self.__remove (state) + + def __str__ (self): + self.__checkSelf () + return str(self.states) + + def __getattr__(self, name): + if name == "states": + result = [] + for state in range(SPI_STATE_INVALID, SPI_STATE_INDETERMINATE): + if self.contains(state): + result.append(state) + return result + else: + raise AttributeError, name + +cdef class Relation: + """ + Wrapper around a cspi.AccessibleRelation + """ + cdef cspi.AccessibleRelation *__item + + def __new__ (self): + self.__item = NULL + + def __dealloc__ (self): + if self.__item != NULL: + cspi.AccessibleRelation_unref (self.__item) + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + + def __str__ (self): + self.__checkSelf () + return "relation %s -> %s"%(self.getRelationType (), self.getTargets()) + + def __repr__ (self): + self.__checkSelf () + return "relation %s -> %s"%(self.getRelationType (), self.getTargets()) + + cdef bool __setItem (self, cspi.AccessibleRelation *obj): + if self.__item != NULL: + cspi.AccessibleRelation_unref (self.__item) + if obj != NULL: + self.__item = obj + cspi.AccessibleRelation_ref (self.__item) + return True + else: + return False + + def getNTargets (self): + """ + Wrapper around cspi.AccessibleRelation_getNTargets + """ + self.__checkSelf () + return cspi.AccessibleRelation_getNTargets (self.__item) + + def getTarget (self, i): + """ + Wrapper around cspi.AccessibleRelation_getTarget + """ + self.__checkSelf () + cdef Accessible target + target = Accessible () + target.__setItem (cspi.AccessibleRelation_getTarget (self.__item, i)) + target.__checkSelf () + return target + + def getTargets (self): + """ + Gets the targets of this AccessibleRelation as a list of atspi.Accessible + """ + self.__checkSelf () + result = [] + count = self.getNTargets() + for i in range(count): + result.append(self.getTarget(i)) + return result + + def getRelationType (self): + """ + Wrapper around cspi.AccessibleRelation_getRelationType + """ + self.__checkSelf () + return cspi.AccessibleRelation_getRelationType (self.__item) + +cdef class Accessible (Base): + """ + Wrapper around cspi.Accessible + """ + def __getattr__ (self, name): + if name == "name": + return self.getName () + elif name == "role": + return self.getRole () + elif name == "roleName": + return self.getRoleName () + elif name == "description": + return self.getDescription () + elif name == "parent": + return self.getParent () + elif name == "childCount": + return self.getChildCount () + elif name == "indexInParent": + return self.getIndexInParent () + elif name == "stateSet": + return self.getStateSet () + else: + raise AttributeError, name + + def getName (self): + """ + Wrapper around cspi.Accessible_getName + """ + self.__checkSelf() + return string(cspi.Accessible_getName(self.__item)) + + def getDescription (self): + """ + Wrapper around cspi.Accessible_getDescription + """ + self.__checkSelf() + return string(cspi.Accessible_getDescription(self.__item)) + + def getParent (self): + """ + Wrapper around cspi.Accessible_getParent, returning an + atspi.Accessible or None + """ + self.__checkSelf() + cdef Accessible parent + cdef cspi.Accessible* spiParent + + spiParent = cspi.Accessible_getParent (self.__item) + if spiParent!=NULL: + parent = Accessible () + parent.__setItem (spiParent) + parent.__checkSelf () + return parent + else: + return None + + def getChildAtIndex (self, index): + """ + Wrapper around cspi.Accessible_getChildAtIndex, returning an + atspi.Accessible, atspi.Application, or None + """ + self.__checkSelf() + cdef int i + i = index + + # This hairiness is due to the fact that Pyrex doesn't allow cdefs + # inside if blocks. + + cdef cspi.Accessible* spiChild + spiChild = cspi.Accessible_getChildAtIndex (self.__item, i) + # Workaround for GNOME bug #321273 + # http://bugzilla.gnome.org/show_bug.cgi?id=321273 + if spiChild == NULL: return None + + cdef object child + cdef Application app + cdef Accessible acc + cdef Text text + + if cspi.Accessible_isApplication (spiChild): + app = Application () + app.__setItem (spiChild) + child = app + else: + acc = Accessible () + acc.__setItem (spiChild) + child = acc + + return child + + def getIndexInParent (self): + """ + Wrapper around cspi.Accessible_getIndexInParent + """ + self.__checkSelf() + return cspi.Accessible_getIndexInParent (self.__item) + + def getRole (self): + """ + Wrapper around cspi.Accessible_getRole + """ + self.__checkSelf() + return cspi.Accessible_getRole (self.__item) + + def getRoleName (self): + """ + Wrapper around cspi.Accessible_getRoleName + """ + self.__checkSelf() + return string(cspi.Accessible_getRoleName (self.__item)) + + def getChildCount (self): + """ + Wrapper around cspi.Accessible_getChildCount + """ + self.__checkSelf() + return cspi.Accessible_getChildCount (self.__item) + + def getStateSet (self): + """ + Wrapper around cspi.Accessible_getStateSet, returning an + atspi.StateSet + """ + self.__checkSelf() + cdef StateSet set + set = StateSet() + set.__setItem (cspi.Accessible_getStateSet (self.__item)) + return set + + def getInterface (self, interface): + """ + This is NOT part of cspi, it is just for compatibility with + the bonobo bindings and will probably go away soon. + """ + self.__checkSelf() + return getattr(self, "get%s" % interface) () + + def getAction (self): + """ + Wrapper around cspi.Accessible_getAction, returning + an atspi.Action or None + """ + self.__checkSelf() + cdef Action action + action = Action () + action.__setItem (cspi.Accessible_getAction (self.__item)) + if action.__item != NULL: + return action + + def getText (self): + """ + Wrapper around cspi.Accessible_getText, returning an atspi.Text + or None + """ + self.__checkSelf () + cdef Text text + text = Text () + text.__setItem (cspi.Accessible_getText (self.__item)) + if text.__item != NULL: + return text + + def getEditableText (self): + """ + Wrapper around cspi.Accessible_getText, returning an + atspi.EditableText or None + """ + self.__checkSelf () + cdef EditableText etext + etext = EditableText () + etext.__setItem (cspi.Accessible_getEditableText (self.__item)) + if etext.__item != NULL: + return etext + + def getHypertext (self): + """ + Wrapper around cspi.Accessible_getHypertext, returning an + atspi.Hypertext or None + """ + self.__checkSelf () + cdef Hypertext hypertext + hypertext = Hypertext () + hypertext.__setItem (cspi.Accessible_getHypertext (self.__item)) + if hypertext.__item != NULL: + return hypertext + + def getImage (self): + """ + Wrapper around cspi.Accessible_getImage, returning an + atspi.Image or None + """ + self.__checkSelf () + cdef Image image + image = Image () + image.__setItem (cspi.Accessible_getImage (self.__item)) + if image.__item != NULL: + return image + + def getValue (self): + """ + Wrapper around cspi.Accessible_getValue, returning an + atspi.Value or None + """ + self.__checkSelf () + cdef Value value + value = Value () + value.__setItem (cspi.Accessible_getValue (self.__item)) + if value.__item != NULL: + return value + + def getSelection (self): + """ + Wrapper around cspi.Accessible_getSelection, returning an + atspi.Selection or None + """ + self.__checkSelf () + cdef Selection selection + selection = Selection () + selection.__setItem (cspi.Accessible_getSelection (self.__item)) + if selection.__item != NULL: + return selection + + def getComponent (self): + """ + Wrapper around cspi.Accessible_getComponent, returning an + atspi.Component or None + """ + self.__checkSelf () + cdef Component component + component = Component () + component.__setItem (cspi.Accessible_getComponent (self.__item)) + if component.__item != NULL: + return component + + def getRelationSet (self): + """ + Wraps Accessible_getRelationSet, returning a list + of atspi.Relation + """ + # looking at at-poke, result from C API appears to be a NULL-terminated list of pointers, and that we should free the buffer + self.__checkSelf () + cdef Relation relation + + relations = [] + cdef cspi.AccessibleRelation **relationSet + relationSet = cspi.Accessible_getRelationSet (self.__item) + + i=0 + while relationSet[i]: + relation = Relation () + relation.__setItem (relationSet[i]) + relations.append(relation) + i=i+1 + cspi.free (relationSet) + + return relations + + +cdef class Desktop (Accessible): + pass + + +cdef class Application (Accessible): + """ + Wrapper around the low-level cspi.AccessibleApplication_ functions, + giving an OO-style API. + """ + def getToolkit (self): + """ + Wraps AccessibleApplication_getToolkitName, returning a string + """ + self.__checkSelf () + return cspi.AccessibleApplication_getToolkitName (self.__item) + + def getVersion (self): + """ + Wraps AccessibleApplication_getVersion, returning a string + """ + self.__checkSelf () + return cspi.AccessibleApplication_getVersion(self.__item) + + def getID (self): + """ + Wraps AccessibleApplication_getID, returning a string + """ + self.__checkSelf () + return cspi.AccessibleApplication_getID (self.__item) + + def pause (self): + """ + Wraps AccessibleApplication_pause + """ + self.__checkSelf () + return cspi.AccessibleApplication_pause (self.__item) + + def resume (self): + """ + Wraps AccessibleApplication_resume + """ + self.__checkSelf () + return cspi.AccessibleApplication_resume (self.__item) + +cdef class Component (Accessible): + """ + Wrapper around the low-level cspi.AccessibleComponent_ functions, + giving an OO-style API. + """ + def getExtents (self, type=0): + """ + Wraps cspi.AccessibleComponent_getExtents, returning an + (x,y,w,h) tuple. + """ + self.__checkSelf () + cdef long x, y, w, h + cspi.AccessibleComponent_getExtents (self.__item, &x, &y, &w, &h, type) + return (x, y, w, h) + + def getPosition (self, type = 0): + """ + Wraps cspi.AccessibleComponent_getPosition, returning an + (x,y) tuple. + """ + self.__checkSelf () + cdef long x, y + cspi.AccessibleComponent_getPosition (self.__item, &x, &y, type) + return (x, y) + + def getSize (self): + """ + Wraps cspi.AccessibleComponent_getSize, returning a + (w,h) tuple. + """ + self.__checkSelf () + cdef long w, h + cspi.AccessibleComponent_getSize (self.__item, &w, &h) + return (w, h) + + def getLayer (self): + """ + Wraps cspi.AccessibleComponent_getLayer, returning an + AccessibleComponentLayer. + """ + self.__checkSelf () + return cspi.AccessibleComponent_getLayer (self.__item) + + def grabFocus (self): + """ + Wraps cspi.AccessibleComponent_grabFocus, raising AtspiException + if it fails + """ + self.__checkSelf () + if not cspi.AccessibleComponent_grabFocus (self.__item): + raise AtspiException("AccessibleComponent_grabFocus") + + def getMDIZOrder (self): + """ + Wraps cspi.AccessibleComponent_getMDIZOrder, returning an integer. + """ + self.__checkSelf () + return cspi.AccessibleComponent_getMDIZOrder(self.__item) + +cdef class Action (Base): + """ + Wrapper around the low-level cspi.AccessibleAction_ functions, + giving an OO-style API. + """ + def __getattr__ (self, name): + if name == "nActions": + return self.getNActions () + else: + raise AttributeError, name + + def getNActions (self): + """ + Wraps cspi.AccessibleAction_getNActions + """ + self.__checkSelf () + return cspi.AccessibleAction_getNActions (self.__item) + + def doAction (self, index): + """ + Wraps cspi.AccessibleAction_doAction + """ + self.__checkSelf () + return cspi.AccessibleAction_doAction (self.__item, index) + + def getKeyBinding (self, index): + """ + Wraps cspi.AccessibleAction_getKeyBinding + """ + self.__checkSelf () + return cspi.AccessibleAction_getKeyBinding (self.__item, index) + + def getName (self, index): + """ + Wraps cspi.AccessibleAction_getName + """ + self.__checkSelf () + return string(cspi.AccessibleAction_getName (self.__item, index)) + + def getDescription (self, index): + """ + Wraps cspi.AccessibleAction_getDescription + """ + self.__checkSelf () + return string(cspi.AccessibleAction_getDescription (self.__item, index)) + + +cdef class Text (Base): + """ + Wrapper around the low-level cspi.AccessibleText_ functions, + giving an OO-style API. + """ + def addSelection (self, startOffset, endOffset): + """ + Wraps cspi.AccessibleText_addSelection + """ + self.__checkSelf () + if not cspi.AccessibleText_addSelection (self.__item, startOffset, endOffset): + raise AtspiException("AccessibleText_addSelection") + + + #def getAttributes (self, offset, startOffset, endOffset): + # self.__checkSelf () + # return cspi.AccessibleText_getAttributes (self.__item, offset, startOffset, endOffset) + def getCaretOffset (self): + """ + Wraps cspi.AccessibleText_getCaretOffset + """ + self.__checkSelf () + return cspi.AccessibleText_getCaretOffset (self.__item) + + def getCharacterCount (self): + """ + Wraps cspi.AccessibleText_getCharacterCount + """ + self.__checkSelf () + return cspi.AccessibleText_getCharacterCount (self.__item) + + def getNSelections (self): + """ + Wraps cspi.AccessibleText_getNSelections + """ + self.__checkSelf () + return cspi.AccessibleText_getNSelections (self.__item) + + #def getSelection (self, selectionNum, startOffset, endOffset): + # self.__checkSelf () + # return cspi.AccessibleText_getSelection (self.__item, selectionNum, startOffset, endOffset) + + def getText (self, startOffset, endOffset): + """ + Wraps cspi.AccessibleText_getText + """ + self.__checkSelf () + return string(cspi.AccessibleText_getText (self.__item, startOffset, endOffset)) + + def removeSelection (self, selectionNum): + """ + Wraps cspi.AccessibleText_removeSelection, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleText_removeSelection (self.__item, selectionNum): + raise AtspiException("AccessibleText_removeSelection") + + def setSelection (self, selectionNum, startOffset, endOffset): + """ + Wraps cspi.AccessibleText_setSelection, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleText_setSelection (self.__item, selectionNum, startOffset, endOffset): + raise AtspiException("AccessibleText_setSelection") + + def setCaretOffset (self, position): + """ + Wraps cspi.AccessibleText_setCaretOffset, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleText_setCaretOffset (self.__item, position): + raise AtspiException("AccessibleText_setCaretOffset") + +cdef class EditableText (Text): + """ + Wrapper around the low-level cspi.AccessibleEditableText_ functions, + giving an OO-style API. + """ + def setTextContents (self, newContents): + """ + Wraps cspi.AccessibleEditableText_setTextContents, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleEditableText_setTextContents (self.__item, newContents): + raise AtspiException("AccessibleEditableText_setTextContents") + + def setAttributes (self, attributes, startOffset, endOffset): + """ + Wraps cspi.AccessibleEditableText_setAttributes, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleEditableText_setAttributes (self.__item, attributes, startOffset, endOffset): + raise AtspiException("AccessibleEditableText_setAttributes") + + def insertText (self, position, text): + """ + Wraps cspi.AccessibleEditableText_insertText, raising AtspiException if it fails + """ + self.__checkSelf () + if not cspi.AccessibleEditableText_insertText (self.__item, position, text, cspi.strlen(text)): + raise AtspiException("AccessibleEditableText_insertText") + +cdef class Hypertext (Text): + """ + Wrapper around the low-level cspi.AccessibleHypertext_ functions, + giving an OO-style API. + """ + def getNLinks (self): + """ + Wraps cspi.AccessibleHypertext_getNLinks, raising AtspiException if it fails + """ + self.__checkSelf () + return cspi.AccessibleHypertext_getNLinks (self.__item) + + def getLink (self, linkIndex): + """ + Wraps cspi.AccessibleHypertext_getLink, raising AtspiException if it fails + """ + self.__checkSelf () + cdef Hyperlink hyperlink + hyperlink = Hyperlink () + hyperlink.__setItem (cspi.AccessibleHypertext_getLink (self.__item, linkIndex)) + if hyperlink.__item != NULL: + return hyperlink + + def getLinkIndex (self, characterOffset): + """ + Wraps cspi.AccessibleHypertext_getLinkIndex, raising AtspiException if it fails + """ + self.__checkSelf () + return cspi.AccessibleHypertext_getLinkIndex (self.__item, characterOffset) + +cdef class Hyperlink (Base): + """ + Wrapper around the low-level cspi.AccessibleHyperlink_ functions, + giving an OO-style API. + """ + def getNAnchors (self): + """ + Wraps cspi.AccessibleHyperlink_getNAnchors, raising AtspiException if it fails + """ + self.__checkSelf () + return cspi.AccessibleHyperlink_getNAnchors (self.__item) + + def getIndexRange (self): + """ + Wraps cspi.AccessibleHyperlink_getIndexRange, returning [startIndex, endIndex] pair + """ + self.__checkSelf () + cdef long startIndex, endIndex + cspi.AccessibleHyperlink_getIndexRange(self.__item, &startIndex, &endIndex) + return [startIndex, endIndex] + + + def getObject (self, i): + """ + Wraps cspi.AccessibleHyperlink_getObject + """ + self.__checkSelf () + cdef Accessible object + object = Accessible () + object.__setItem (cspi.AccessibleHyperlink_getObject (self.__item, i)) + object.__checkSelf () + return object + + def getURI (self, i): + """ + Wraps cspi.AccessibleHyperlink_getURI, raising AtspiException if it fails + """ + self.__checkSelf () + return cspi.AccessibleHyperlink_getURI (self.__item, i) + + def isValid (self): + """ + Wraps cspi.AccessibleHyperlink_isValid, raising AtspiException if it fails + """ + self.__checkSelf () + return cspi.AccessibleHyperlink_isValid (self.__item) + +cdef class Image (Base): + """ + Wrapper around the low-level cspi.AccessibleImage_ functions, + giving an OO-style API. + """ + def getImageDescription (self): + """ + Wraps cspi.AccessibleImage_getImageDescription + """ + self.__checkSelf () + return cspi.AccessibleImage_getImageDescription (self.__item) + + def getImageSize (self): + """ + Wraps cspi.AccessibleImage_getImageSize, returning a (w,h) pair + """ + self.__checkSelf () + cdef long w, h + cspi.AccessibleImage_getImageSize(self.__item, &w, &h); + return [w, h] + + def getImagePosition (self, type=0): + """ + Wraps cspi.AccessibleImage_getImagePosition, returning a (x,y) + pair + """ + self.__checkSelf () + cdef long x, y + cspi.AccessibleImage_getImagePosition(self.__item, &x, &y, type) + return [x, y] + + def getImageExtents (self, type=0): + """ + Wraps cspi.AccessibleImage_getImageExtents, returning a + (x,y,w,h) tuple + """ + self.__checkSelf () + cdef long x, y, w, h + cspi.AccessibleImage_getImageExtents(self.__item, &x, &y, &w, &h, type) + return [x, y, w, h] + +cdef class Value (Base): + """ + Wrapper around the low-level cspi.AccessibleValue_ functions, + giving an OO-style API. + """ + def getMinimumValue (self): + """ + Wraps cspi.AccessibleValue_getMinimumValue + """ + self.__checkSelf () + return cspi.AccessibleValue_getMinimumValue(self.__item) + + def getCurrentValue (self): + """ + Wraps cspi.AccessibleValue_getMinimumValue + """ + self.__checkSelf () + return cspi.AccessibleValue_getCurrentValue(self.__item) + + def getMaximumValue (self): + """ + Wraps cspi.AccessibleValue_getMinimumValue + """ + self.__checkSelf () + return cspi.AccessibleValue_getMaximumValue(self.__item) + + def setCurrentValue (self, newValue): + """ + Wraps cspi.AccessibleValue_setCurrentValue + """ + self.__checkSelf () + if not cspi.AccessibleValue_setCurrentValue (self.__item, newValue): + raise AtspiException("AccessibleValue_setCurrentValue") + +cdef class Selection (Base): + """ + Wrapper around the low-level cspi.AccessibleSelection_ functions, + giving an OO-style API. + """ + + def getNSelectedChildren (self): + """ + Wraps cspi.AccessibleSelection_getNSelectedChildren + """ + self.__checkSelf () + return cspi.AccessibleSelection_getNSelectedChildren (self.__item) + + def getSelectedChild (self, index): + """ + Wraps cspi.AccessibleSelection_getSelectedChild + """ + self.__checkSelf () + + cdef cspi.Accessible* spiChild + spiChild = cspi.AccessibleSelection_getSelectedChild (self.__item, index) + + assert spiChild != NULL + + cdef object child + cdef Application app + cdef Accessible acc + cdef Text text + + if cspi.Accessible_isApplication (spiChild): + app = Application () + app.__setItem (spiChild) + child = app + else: + acc = Accessible () + acc.__setItem (spiChild) + child = acc + + return child + + def selectChild (self, index): + """ + Wraps cspi.AccessibleSelection_selectChild + """ + self.__checkSelf () + return cspi.AccessibleSelection_selectChild (self.__item, index) + + def deselectSelectedChild (self, index): + """ + Wraps cspi.AccessibleSelection_deselectSelectedChild + """ + self.__checkSelf () + return cspi.AccessibleSelection_deselectSelectedChild (self.__item, index) + + def isChildSelected (self, index): + """ + Wraps cspi.AccessibleSelection_isChildSelected + """ + self.__checkSelf () + return cspi.AccessibleSelection_isChildSelected (self.__item, index) + + def selectAll (self): + """ + Wraps cspi.AccessibleSelection_selectAll + """ + self.__checkSelf () + return cspi.AccessibleSelection_selectAll( self.__item) + + def clearSelection (self): + """ + Wraps cspi.AccessibleSelection_clearSelection + """ + self.__checkSelf () + return cspi.AccessibleSelection_clearSelection (self.__item) + +cdef class Table (Base): + """ + Wrapper around the low-level cspi.AccessibleTable_ functions, + giving an OO-style API. + """ + + # def getTableAccessibleAt (self, row, column): + # def getTableCaption (self): + + def getTableColumnAtIndex (self, index): + """ + Wraps cspi.AccessibleTable_getColumnAtIndex + """ + self.__checkSelf () + return cspi.AccessibleTable_getColumnAtIndex(self.__item, index) + + def getTableColumnDescription (self, column): + """ + Wraps cspi.AccessibleTable_getColumnDescription + """ + self.__checkSelf () + return cspi.AccessibleTable_getColumnDescription(self.__item, column) + + def getTableColumnExtentAt (self, row, column): + """ + Wraps cspi.AccessibleTable_getColumnExtentAt + """ + self.__checkSelf () + return cspi.AccessibleTable_getColumnExtentAt(self.__item, row, column) + + # def getTableColumnHeader (self, column): + + def getTableIndexAt (self, row, column): + """ + Wraps cspi.AccessibleTable_getIndexAt + """ + self.__checkSelf () + return cspi.AccessibleTable_getIndexAt(self.__item, row, column) + + def getTableNColumns (self): + """ + Wraps cspi.AccessibleTable_getNColumns + """ + self.__checkSelf () + return cspi.AccessibleTable_getNColumns(self.__item) + + def getTableNRows (self): + """ + Wraps cspi.AccessibleTable_getNRows + """ + self.__checkSelf () + return cspi.AccessibleTable_getNRows(self.__item) + + def getTableNSelectedColumns (self): + """ + Wraps cspi.AccessibleTable_getNSelectedColumns + """ + self.__checkSelf () + return cspi.AccessibleTable_getNSelectedColumns(self.__item) + + def getTableNSelectedRows (self): + """ +x Wraps cspi.AccessibleTable_getNSelectedRows + """ + self.__checkSelf () + return cspi.AccessibleTable_getNSelectedRows(self.__item) + + def getTableRowAtIndex (self, index): + """ + Wraps cspi.AccessibleTable_getRowAtIndex + """ + self.__checkSelf () + return cspi.AccessibleTable_getRowAtIndex(self.__item, index) + + def getTableRowDescription (self, row): + """ + Wraps cspi.AccessibleTable_getRowDescription + """ + self.__checkSelf () + return cspi.AccessibleTable_getRowDescription(self.__item, row) + + def getTableRowExtentAt (self, row, column): + """ + Wraps cspi.AccessibleTable_getRowExtentAt + """ + self.__checkSelf () + return cspi.AccessibleTable_getRowExtentAt(self.__item, row, column) + + # def getTableRowHeader (self, row): + # def getTableSelectedRows (self, **selectedRows): - Not sure if the variable which is a pointer to a pointer is acceptable + # def getTableSelectedColumns (self, **selectedColumns): - Same issue as above + # def getTableSummary (self): + + def isTableColumnSelected (self, column): + """ + Wraps cspi.AccessibleTable_isColumnSelected + """ + self.__checkSelf () + return cspi.AccessibleTable_isColumnSelected(self.__item, column) + + def isTableRowSelected (self, row): + """ + Wraps cspi.AccessibleTable_isRowSelected + """ + self.__checkSelf () + return cspi.AccessibleTable_isRowSelected(self.__item, row) + + def isTableSelected (self, row, column): + """ + Wraps cspi.AccessibleTable_isSelected + """ + self.__checkSelf () + return cspi.AccessibleTable_isSelected(self.__item, row, column) + + +cdef class Event (EventBase): + #def AccessibleEventListener* SPI_createAccessibleEventListener (AccessibleEventListenerCB callback, void *user_data) + #void AccessibleEventListener_unref (AccessibleEventListener *listener) + #SPIBoolean AccessibleEventListener_addCallback (AccessibleEventListener *listener, AccessibleEventListenerCB callback, void *user_data) + #SPIBoolean AccessibleEventListener_removeCallback (AccessibleEventListener *listener, AccessibleEventListenerCB callback) + + #Accessible* AccessibleActiveDescendantChangedEvent_getActiveDescendant (AccessibleEvent *event) + #Accessible* AccessibleChildChangedEvent_getChildAccessible (AccessibleEvent *event) + + def getDescriptionChangedEventDescriptionString (self): + self.__checkSelf() + return string(cspi.AccessibleDescriptionChangedEvent_getDescriptionString(self.__item)) + + def getNameChangedEventNameString (self): + self.__checkSelf() + return string(cspi.AccessibleNameChangedEvent_getNameString(self.__item)) + + # Accessible* AccessibleParentChangedEvent_getParentAccessible (AccessibleEvent *event) + + def getTableCaptionChangedEventCaptionString(self): + self.__checkSelf() + return string(cspi.AccessibleTableCaptionChangedEvent_getCaptionString(self.__item)) + + def getTableColumnDescriptionChangedEventDescriptionString(self): + self.__checkSelf () + return string(cspi.AccessibleTableColumnDescriptionChangedEvent_getDescriptionString(self.__item)) + + # Accessible* AccessibleTableHeaderChangedEvent_getHeaderAccessible (AccessibleEvent *event) + + def getTableRowDescriptionChangedEventDescriptionString(self): + self.__checkSelf () + return string(cspi.AccessibleTableRowDescriptionChangedEvent_getDescriptionString(self.__item)) + + #Accessible* AccessibleTableSummaryChangedEvent_getSummaryAccessible (AccessibleEvent *event) + + def getTextChangedEventChangeString (self): + self.__checkSelf () + return string(cspi.AccessibleTextChangedEvent_getChangeString(self.__item)) + + def getTextSelectionChangedEventSelectionString (self): + self.__checkSelf () + return string(cspi.AccessibleTextSelectionChangedEvent_getSelectionString(self.__item)) + + def getWindowEventTitleString (self): + self.__checkSelf () + return string(cspi.AccessibleWindowEvent_getTitleString(self.__item)) + +class EventGenerator: + """ + Wrapper layer around SPI_generateKeyboardEvent and + SPI_generateMouseEvent, used for generating input events. + + Use AccessibleAction in preference to this. + """ + def injectKeyboardString (self, string): + """ + Inject a string as if it had been typed using an input method. + """ + # Seems to only work if you do it one character at a time... + for char in string: + self.__generateKeystringEvent (str(char), cspi.SPI_KEY_STRING) + + def __keyStringToKeyCode(self, keyString): + cdef Xlib.Display *display + display = Xlib.XOpenDisplay(NULL) + + cdef Xlib.KeySym sym + sym = Xlib.XStringToKeysym(keyString) + cdef Xlib.KeyCode code + code = Xlib.XKeysymToKeycode(display, sym) + + #print str(keyString), str(int(sym)), code + + Xlib.XCloseDisplay(display) + return int(code) + + def generateKeyCombo (self, keyStrings): + modifiers = keyStrings[:-1] + finalKey = keyStrings[-1] + + for modifier in modifiers: + code = self.__keyStringToKeyCode(modifier) + self.generateKeyboardEvent(code, '', cspi.SPI_KEY_PRESS) + + code = self.__keyStringToKeyCode(finalKey) + self.generateKeyboardEvent(code, '', cspi.SPI_KEY_PRESSRELEASE) + + for modifier in modifiers: + code = self.__keyStringToKeyCode(modifier) + self.generateKeyboardEvent(code, '', cspi.SPI_KEY_RELEASE) + + + def __generateKeyvalEvent (self, keyval, synthType): + self.generateKeyboardEvent (keyval, None, synthType) + + def __generateKeystringEvent (self, keystring, synthType): + self.generateKeyboardEvent (0, keystring, synthType) + + def generateKeyboardEvent (self, keyval, keystring, synthType): + if not cspi.SPI_generateKeyboardEvent (keyval, keystring, synthType): + raise AtspiException("SPI_generateKeyboardEvent") + + def click (self, x, y, button): + """ + Synthesize a mouse button click at (x,y) + """ + self.__generateButtonEvent (x, y, button, "c") + + def doubleClick (self, x, y, button): + """ + Synthesize a mouse button double-click at (x,y) + """ + self.__generateButtonEvent (x, y, button, "d") + + def press (self, x, y, button): + """ + Synthesize a mouse button press at (x,y) + """ + self.__generateButtonEvent (x, y, button, "p") + + def release (self, x, y, button): + """ + Synthesize a mouse button release at (x,y) + """ + self.__generateButtonEvent (x, y, button, "r") + + def absoluteMotion (self, x, y): + """ + Synthesize mouse absolute motion to (x,y) + """ + self.__generateEvent (x, y, "abs") + + def relativeMotion (self, x, y): + """ + Synthesize mouse relative motion of (x,y) + """ + self.__generateEvent (x, y, "rel") + + def drag (self, fromXY, toXY, button): + """ + Synthesize a drag (press, move and release) from (x,y) to (x,y). + + These are absolute screen coordinates + """ + (x,y) = fromXY + self.press (x, y, button) + + (x,y) = toXY + self.absoluteMotion(x,y) + + self.release (x, y, button) + + def __generateEvent (self, x, y, name): + """ + Thin wrapper around SPI_generateMouseEvent. + + Event names: b1p = button 1 press; b2r = button 2 release; + b3c = button 3 click; b2d = button 2 double-click; + abs = absolute motion; rel = relative motion. + """ + if not cspi.SPI_generateMouseEvent (x, y, name): + raise AtspiException("Error generating mouse event") + + def __generateButtonEvent (self, x, y, button, suffix): + self.__generateEvent (x, y, self.__generateButtonName(button)+suffix) + + def __generateButtonName(self, button): + if button==1: + return "b1" + elif button==2: + return "b2" + elif button==3: + return "b3" + else: raise ValueError, "Unknown button" + +# We use this C function to marshal a call to a python function. The Python callback +# function is installed as the userdata of this C callback function. See the +# "cheesefinder" demo in the Pyrex sources. +# We ignore the "const"ness of the AccessibleEvent +cdef void marshalAccessibleEventCallback (cspi.AccessibleEvent *event, void *python_fn) except *: + e = Event() + EventBase.__setItem(e, event) + (python_fn) (e) + +cdef class EventListener: + """ + Wrapper around the low-level cspi.AccessibleEventListener_ functions, + giving an OO-style API. + """ + cdef cspi.AccessibleEventListener *__item + cdef public object eventTypes + + def __init__ (self, callback, eventTypes): + """ + Registers a python callback function to be called. + The callback is expected to have one input, of type atspi.Event, and no return value. + See documentation of SPI_registerGlobalEventListener for the event names + """ + self.eventTypes = eventTypes + self.__item = cspi.SPI_createAccessibleEventListener (marshalAccessibleEventCallback, callback) + for eventType in self.eventTypes: + #char *e + e = eventType + if not cspi.SPI_registerGlobalEventListener (self.__item, e): + raise AtspiException("Unable to register event listener") + + def deregister(self): + for eventType in self.eventTypes: + cspi.SPI_deregisterGlobalEventListener(self.__item, eventType) + + def __dealloc__ (self): + if self.__item != NULL: + self.deregister() + cspi.AccessibleEventListener_unref (self.__item) + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + +cdef class DeviceEvent: + """ + Wrapper around a cspi.AccessibleDeviceEvent + """ + cdef cspi.AccessibleDeviceEvent *__item + cdef public object keyID + cdef public object keyCode + cdef public object keyString + cdef public object timeStamp + cdef public object type + cdef public object modifiers + cdef public object isText + + def __new__ (self): + self.__item = NULL + + cdef bool __setItem (self, cspi.AccessibleDeviceEvent *obj): + if obj != NULL: + self.__item = obj + self.keyID = self.__item.keyID + self.keyCode = self.__item.keycode + self.keyString = self.__item.keystring + self.timeStamp = self.__item.timestamp + self.type = self.__item.type + self.modifiers = self.__item.modifiers + if self.__item.is_text: self.isText = True + else: self.isText = False + return True + else: + return False + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + +# def __dealloc__ (self): +# if self.__item != NULL: +# cspi.AccessibleDeviceEvent_unref (self.__item) + + +cdef cspi.SPIBoolean marshalAccessibleDeviceEventCallback (cspi.AccessibleDeviceEvent *event, void *python_fn) except 1: + k = DeviceEvent() + #k.__setItem(event) + DeviceEvent.__setItem(k, event) + k.__checkSelf() + (python_fn) (k) + return False + +cdef class DeviceListener: + """ + Wrapper around the low-level cspi.AccessibleDeviceListener_ functions, + giving an OO-style API. + """ + cdef cspi.AccessibleDeviceListener *__item + cdef public object modMasks + + def __init__ (self, callback, eventMask = cspi.SPI_KEY_PRESSED | cspi.SPI_KEY_RELEASED): + """ + Registers a python callback function to be called. + + eventMask may be one of the following: + key pressed: 1 + key released: 2 + key pressed or released (default): 3 + """ + self.__item = cspi.SPI_createAccessibleDeviceListener (marshalAccessibleDeviceEventCallback, callback) + cdef cspi.AccessibleKeySet *keySet + keySet = SPI_KEYSET_ALL_KEYS + self.modMasks = [] + cdef short int modMask + syncType = SPI_KEYLISTENER_SYNCHRONOUS | SPI_KEYLISTENER_CANCONSUME + #syncType = SPI_KEYLISTENER_NOSYNC + for modMask from 0 <= modMask < (1 << 8): + self.modMasks.append(modMask) + desc = "keySet "+str( keySet)+" modMask "+str(modMask)+" eventMask "+str(eventMask)+" syncType "+str(syncType) + desc = str(desc) + if not cspi.SPI_registerAccessibleKeystrokeListener (self.__item, keySet, modMask, eventMask, syncType): + raise AtspiException("Unable to register keystroke listener", desc) + + def deregister(self): + if self.__item != NULL: + for modMask in self.modMasks: + cspi.SPI_deregisterAccessibleKeystrokeListener(self.__item, modMask) + + def __dealloc__ (self): + if self.__item != NULL: + self.deregister() + cspi.AccessibleDeviceListener_unref (self.__item) + + def __checkSelf (self): + if self.__item == NULL: + raise AttributeError, "__item must not be NULL" + + +# vim: sw=4 ts=4 sts=4 noet ai