diff --git a/legacy/elementary/src/imported/atspi/atspi-constants.h b/legacy/elementary/src/imported/atspi/atspi-constants.h index 6e0551b312..3675bcca1f 100644 --- a/legacy/elementary/src/imported/atspi/atspi-constants.h +++ b/legacy/elementary/src/imported/atspi/atspi-constants.h @@ -91,13 +91,13 @@ extern "C" { /** * AtspiLocaleType: * @ATSPI_LOCALE_TYPE_MESSAGES: For localizable natural-language messages. - * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string - * collation. - * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character - * classification, conversion, case-sensitive comparison, and wide character - * functions. + * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string + * collation. + * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character + * classification, conversion, case-sensitive comparison, and wide character + * functions. * @ATSPI_LOCALE_TYPE_MONETARY: For monetary formatting. - * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal + * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal * point and the thousands separator). * @ATSPI_LOCALE_TYPE_TIME: For time and date formatting. * @@ -124,7 +124,7 @@ typedef enum { /** * AtspiCoordType: * @ATSPI_COORD_TYPE_SCREEN: Specifies xy coordinates relative to the screen. - * @ATSPI_COORD_TYPE_WINDOW: Specifies xy coordinates relative to the widget's + * @ATSPI_COORD_TYPE_WINDOW: Specifies xy coordinates relative to the widget's * top-level window. * * Enumeration used by #AtspiComponent, #AtspiImage, and #AtspiText interfaces @@ -178,19 +178,19 @@ typedef enum { /** * AtspiCollectionMatchType: - * @ATSPI_Collection_MATCH_INVALID: Indicates an error condition or + * @ATSPI_Collection_MATCH_INVALID: Indicates an error condition or * uninitialized value. * @ATSPI_Collection_MATCH_ALL: #TRUE if all of the criteria are met. * @ATSPI_Collection_MATCH_ANY: #TRUE if any of the criteria are met. * @ATSPI_Collection_MATCH_NONE: #TRUE if none of the criteria are met. * @ATSPI_Collection_MATCH_EMPTY: Same as @ATSPI_Collection_MATCH_ALL if - * the criteria is non-empty; for empty criteria this rule requires returned - * value to also have empty set. + * the criteria is non-empty; for empty criteria this rule requires returned + * value to also have empty set. * @ATSPI_Collection_MATCH_LAST_DEFINED: Used only to determine the end of the * enumeration. * * Enumeration used by #AtspiMatchRule to specify - * how to interpret #AtspiAccesible objects. + * how to interpret #AtspiAccessible objects. * **/ typedef enum { @@ -244,9 +244,9 @@ typedef enum { * UI #AtspiComponent containers. * @ATSPI_LAYER_WIDGET: The layer in which the majority of ordinary * 'foreground' widgets reside. - * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and - * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames) - * reside. See #atspi_component_get_mdi_z_order. + * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and + * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames) + * reside. See #atspi_component_get_mdi_z_order. * @ATSPI_LAYER_POPUP: A layer for popup window content, above * @ATSPI_LAYER_WIDGET. * @ATSPI_LAYER_OVERLAY: The topmost layer. @@ -255,23 +255,23 @@ typedef enum { * @ATSPI_LAYER_LAST_DEFINED: Used only to determine the end of the * enumeration. * - * The #AtspiComponentLayer of an #AtspiComponent instance indicates its - * relative stacking order with respect to the onscreen visual representation - * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds - * information, can be used to compute the visibility of all or part of a - * component. This is important in programmatic determination of - * region-of-interest for magnification, and in + * The #AtspiComponentLayer of an #AtspiComponent instance indicates its + * relative stacking order with respect to the onscreen visual representation + * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds + * information, can be used to compute the visibility of all or part of a + * component. This is important in programmatic determination of + * region-of-interest for magnification, and in * flat screen review models of the screen, as well as - * for other uses. Objects residing in two of the #AtspiComponentLayer - * categories support further z-ordering information, with respect to their - * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and - * @ATSPI_LAYER_MDI. Relative stacking order for other objects within the - * same layer is not available; the recommended heuristic is - * first child paints first. In other words, assume that the - * first siblings in the child list are subject to being overpainted by later + * for other uses. Objects residing in two of the #AtspiComponentLayer + * categories support further z-ordering information, with respect to their + * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and + * @ATSPI_LAYER_MDI. Relative stacking order for other objects within the + * same layer is not available; the recommended heuristic is + * first child paints first. In other words, assume that the + * first siblings in the child list are subject to being overpainted by later * siblings if their bounds intersect. The order of layers, from bottom to top, * is: @ATSPI_LAYER_BACKGROUND, @ATSPI_LAYER_WINDOW, @ATSPI_LAYER_MDI, - * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and + * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and * @ATSPI_LAYER_OVERLAY. * */ @@ -296,15 +296,15 @@ typedef enum { /** * AtspiTextBoundaryType: - * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this - * character only. Start and end offsets differ by one, by definition, + * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this + * character only. Start and end offsets differ by one, by definition, * for this value. * @ATSPI_TEXT_BOUNDARY_WORD_START: Boundary condition is start of a word; i.e. * range is from start of one word to the start of another word. * @ATSPI_TEXT_BOUNDARY_WORD_END: Boundary condition is the end of a word; i.e. * range is from the end of one word to the end of another. Some locales * may not distinguish between words and characters or glyphs. In particular, - * those locales which use wholly or partially ideographic character sets. + * those locales which use wholly or partially ideographic character sets. * In these cases, characters may be returned in lieu of multi-character * substrings. * @ATSPI_TEXT_BOUNDARY_SENTENCE_START: Boundary condition is start of a @@ -323,7 +323,7 @@ typedef enum { * generally means that an end-of-line character will appear at the end of * the range. * @ATSPI_TEXT_BOUNDARY_LINE_END: Boundary condition is the end of a line; i.e. - * range is from start of one line to the start of another. This generally + * range is from start of one line to the start of another. This generally * means that an end-of-line character will be the first character of the * range. * @@ -331,6 +331,8 @@ typedef enum { * #atspi_text_get_text_at_offset, #atspi_text_get_text_after_offset, and * #atspi_text_get_text_before_offset. * + * This enumerationis deprecated since 2.9.90 and should not be used. Use + * AtspiTextGranularity with #atspi_text_get_string_at_offset instead. **/ typedef enum { ATSPI_TEXT_BOUNDARY_CHAR, @@ -342,6 +344,34 @@ typedef enum { ATSPI_TEXT_BOUNDARY_LINE_END, } AtspiTextBoundaryType; +/** + *AtspiTextGranularity: + *@ATSPI_TEXT_GRANULARITY_CHAR: Granularity is defined by the boundaries between characters + * (including non-printing characters) + *@ATSPI_TEXT_GRANULARITY_WORD: Granularity is defined by the boundaries of a word, + * starting at the beginning of the current word and finishing at the beginning of + * the following one, if present. + *@ATSPI_TEXT_GRANULARITY_SENTENCE: Granularity is defined by the boundaries of a sentence, + * starting at the beginning of the current sentence and finishing at the beginning of + * the following one, if present. + *@ATSPI_TEXT_GRANULARITY_LINE: Granularity is defined by the boundaries of a line, + * starting at the beginning of the current line and finishing at the beginning of + * the following one, if present. + *@ATSPI_TEXT_GRANULARITY_PARAGRAPH: Granularity is defined by the boundaries of a paragraph, + * starting at the beginning of the current paragraph and finishing at the beginning of + * the following one, if present. + * + * Text granularity types used for specifying the granularity of the region of + * text we are interested in. + **/ +typedef enum { + ATSPI_TEXT_GRANULARITY_CHAR, + ATSPI_TEXT_GRANULARITY_WORD, + ATSPI_TEXT_GRANULARITY_SENTENCE, + ATSPI_TEXT_GRANULARITY_LINE, + ATSPI_TEXT_GRANULARITY_PARAGRAPH +} AtspiTextGranularity; + /** * ATSPI_TEXT_BOUNDARY_TYPE_COUNT: * @@ -379,7 +409,7 @@ typedef enum { /** * AtspiStateType: - * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error + * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error * condition. * @ATSPI_STATE_ACTIVE: Indicates a window is currently the active window, or * is an active subelement within a container or table. @@ -396,7 +426,7 @@ typedef enum { * @ATSPI_STATE_ENABLED: Indicates that this object is enabled, i.e. that it * currently reflects some application state. Objects that are "greyed out" * may lack this state, and may lack the @ATSPI_STATE_SENSITIVE if direct - * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED. + * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED. * See @ATSPI_STATE_SENSITIVE. * @ATSPI_STATE_EXPANDABLE: Indicates this object allows progressive * disclosure of its children. @@ -433,10 +463,10 @@ typedef enum { * children that has been selected. * @ATSPI_STATE_SENSITIVE: Indicates this object is sensitive, e.g. to user * interaction. @ATSPI_STATE_SENSITIVE usually accompanies. - * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the - * absence of @ATSPI_STATE_ENABLED if the current visible state of the control + * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the + * absence of @ATSPI_STATE_ENABLED if the current visible state of the control * is "disconnected" from the application state. In such cases, direct user - * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE, + * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE, * for instance if a user makes an explicit selection using an object whose * current state is ambiguous or undefined. See @ATSPI_STATE_ENABLED, * @ATSPI_STATE_INDETERMINATE. @@ -448,19 +478,19 @@ typedef enum { * single line of text. * @ATSPI_STATE_STALE: Indicates that the information returned for this object * may no longer be synchronized with the application state. This can occur - * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the + * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the * end of the object peer's lifecycle. * @ATSPI_STATE_TRANSIENT: Indicates this object is transient. * @ATSPI_STATE_VERTICAL: Indicates the orientation of this object is vertical; * for example this state may appear on such objects as scrollbars, text * objects (with vertical text flow), separators, etc. * @ATSPI_STATE_VISIBLE: Indicates this object is visible, e.g. has been - * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no - * guarantee that the object is actually unobscured on the screen, only that - * it is 'potentially' visible, barring obstruction, being scrolled or clipped - * out of the field of view, or having an ancestor container that has not yet - * made visible. A widget is potentially onscreen if it has both - * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of + * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no + * guarantee that the object is actually unobscured on the screen, only that + * it is 'potentially' visible, barring obstruction, being scrolled or clipped + * out of the field of view, or having an ancestor container that has not yet + * made visible. A widget is potentially onscreen if it has both + * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING is * semantically equivalent to saying that an object is 'hidden'. * @ATSPI_STATE_MANAGES_DESCENDANTS: Indicates that "active-descendant-changed" @@ -469,14 +499,14 @@ typedef enum { * in very large containers, like tables. The presence of * @ATSPI_STATE_MANAGES_DESCENDANTS is an indication to the client that the * children should not, and need not, be enumerated by the client. - * Objects implementing this state are expected to provide relevant state - * notifications to listening clients, for instance notifications of - * visibility changes and activation of their contained child objects, without + * Objects implementing this state are expected to provide relevant state + * notifications to listening clients, for instance notifications of + * visibility changes and activation of their contained child objects, without * the client having previously requested references to those children. * @ATSPI_STATE_INDETERMINATE: Indicates that a check box or other boolean * indicator is in a state other than checked or not checked. This * usually means that the boolean value reflected or controlled by the - * object does not apply consistently to the entire current context. + * object does not apply consistently to the entire current context. * For example, a checkbox for the "Bold" attribute of text may have * @ATSPI_STATE_INDETERMINATE if the currently selected text contains a mixture * of weight attributes. In many cases interacting with a @@ -495,13 +525,13 @@ typedef enum { * representation becomes static. Some applications, notably content viewers, * may not be able to detect all kinds of animated content. Therefore the * absence of this state should not be taken as - * definitive evidence that the object's visual representation is + * definitive evidence that the object's visual representation is * static; this state is advisory. * @ATSPI_STATE_INVALID_ENTRY: This object has indicated an error condition * due to failure of input validation. For instance, a form control may * acquire this state in response to invalid or malformed user input. * @ATSPI_STATE_SUPPORTS_AUTOCOMPLETION: This state indicates that the object - * in question implements some form of typeahead or + * in question implements some form of typeahead or * pre-selection behavior whereby entering the first character of one or more * sub-elements causes those elements to scroll into view or become * selected. Subsequent character input may narrow the selection further as @@ -514,7 +544,7 @@ typedef enum { * question supports text selection. It should only be exposed on objects * which implement the #AtspiText interface, in order to distinguish this state * from @ATSPI_STATE_SELECTABLE, which infers that the object in question is a - * selectable child of an object which implements #AtspiSelection. While + * selectable child of an object which implements #AtspiSelection. While * similar, text selection and subelement selection are distinct operations. * @ATSPI_STATE_IS_DEFAULT: This state indicates that the object in question is * the 'default' interaction object in a dialog, i.e. the one that gets @@ -523,12 +553,20 @@ typedef enum { * @ATSPI_STATE_VISITED: This state indicates that the object (typically a * hyperlink) has already been activated or invoked, with the result that * some backing data has been downloaded or rendered. + *@ATSPI_STATE_CHECKABLE: Indicates this object has the potential to + * be checked, such as a checkbox or toggle-able table cell. @Since: + * 2.12 + *@ATSPI_STATE_HAS_POPUP: Indicates that the object has a popup + * context menu or sub-level menu which may or may not be + * showing. This means that activation renders conditional content. + * Note that ordinary tooltips are not considered popups in this + * context. @Since: 2.12 * @ATSPI_STATE_LAST_DEFINED: This value of the enumeration should not be used * as a parameter, it indicates the number of items in the #AtspiStateType * enumeration. * - * - * Enumeration used by various interfaces indicating every possible state + * + * Enumeration used by various interfaces indicating every possible state * an #AtspiAccesible object can assume. * **/ @@ -574,6 +612,8 @@ typedef enum { ATSPI_STATE_SELECTABLE_TEXT, ATSPI_STATE_IS_DEFAULT, ATSPI_STATE_VISITED, + ATSPI_STATE_CHECKABLE, + ATSPI_STATE_HAS_POPUP, ATSPI_STATE_LAST_DEFINED, } AtspiStateType; @@ -606,18 +646,18 @@ typedef enum { /** * AtspiEventType: - * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was + * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was * pressed. - * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was + * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was * released. - * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard + * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard * human interface device (HID) was pressed. * @ATSPI_BUTTON_RELEASED_EVENT: Indicates that a button on a non-keyboard * human interface device (HID) was released. * - * Enumeration used to specify the event types of interest to an - * #AtspiEventListener, or - * to identify the type of an event for which notification has been sent. + * Enumeration used to specify the event types of interest to an + * #AtspiEventListener, or + * to identify the type of an event for which notification has been sent. * **/ typedef enum { @@ -639,19 +679,20 @@ typedef enum { * @ATSPI_KEY_PRESS: Emulates the pressing of a hardware keyboard key. * @ATSPI_KEY_RELEASE: Emulates the release of a hardware keyboard key. * @ATSPI_KEY_PRESSRELEASE: Emulates the pressing and immediate releasing - * ofa hardware keyboard key. + * of a hardware keyboard key. * @ATSPI_KEY_SYM: A symbolic key event is generated, without specifying a * hardware key. Note: if the keysym is not present in the current keyboard - * map, the #AtspiDeviceEventController instance has a limited ability to - * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent - * calls using out-of-keymap keysyms will vary from system to system, and on - * the number of different out-of-keymap being generated in quick succession. - * In practice this is rarely significant, since the keysyms of interest to - * AT clients and keyboard emulators are usually part of the current keymap, - * i.e. present on the system keyboard for the current locale (even if a - * physical hardware keyboard is not connected. + * map, the #AtspiDeviceEventController instance has a limited ability to + * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent + * calls using out-of-keymap keysyms will vary from system to system, and on + * the number of different out-of-keymap keysyms being generated in quick + * succession. + * In practice this is rarely significant, since the keysyms of interest to + * AT clients and keyboard emulators are usually part of the current keymap, + * i.e., present on the system keyboard for the current locale (even if a + * physical hardware keyboard is not connected). * @ATSPI_KEY_STRING: A string is converted to its equivalent keyboard events - * and emitted. If the string consists of complex character or composed + * and emitted. If the string consists of complex characters or composed * characters which are not in the current keymap, string emission is * subject to the out-of-keymap limitations described for * @ATSPI_KEY_SYM. In practice this limitation primarily effects @@ -725,7 +766,7 @@ typedef enum { * modifies the state, onscreen location, or other attributes of one or more * target objects. * @ATSPI_RELATION_CONTROLLED_BY: Object state, position, etc. is - * modified/controlled by user interaction with one or more other objects. + * modified/controlled by user interaction with one or more other objects. * For instance a viewport or scroll pane may be @ATSPI_RELATION_CONTROLLED_BY * scrollbars. * @ATSPI_RELATION_MEMBER_OF: Object has a grouping relationship (e.g. 'same @@ -741,10 +782,10 @@ typedef enum { * object which is not the 'next sibling' in the accessibility hierarchy. * @ATSPI_RELATION_FLOWS_FROM: Reciprocal of @ATSPI_RELATION_FLOWS_TO. * @ATSPI_RELATION_SUBWINDOW_OF: Object is visually and semantically considered - * a subwindow of another object, even though it is not the object's child. + * a subwindow of another object, even though it is not the object's child. * Useful when dealing with embedded applications and other cases where the * widget hierarchy does not map cleanly to the onscreen presentation. - * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but + * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but * specifically used for cross-process embedding. * @ATSPI_RELATION_EMBEDDED_BY: Reciprocal of @ATSPI_RELATION_EMBEDS. Used to * denote content rendered by embedded renderers that live in a separate process @@ -752,9 +793,9 @@ typedef enum { * @ATSPI_RELATION_POPUP_FOR: Denotes that the object is a transient window or * frame associated with another onscreen object. Similar to @ATSPI_TOOLTIP_FOR, * but more general. Useful for windows which are technically toplevels - * but which, for one or more reasons, do not explicitly cause their + * but which, for one or more reasons, do not explicitly cause their * associated window to lose 'window focus'. Creation of an @ATSPI_ROLE_WINDOW - * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires + * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires * some presentation action on the part * of assistive technology clients, even though the previous toplevel * @ATSPI_ROLE_FRAME object may still be the active window. @@ -767,24 +808,24 @@ typedef enum { * descriptive information about this object; more verbose than * @ATSPI_RELATION_LABELLED_BY. * @ATSPI_RELATION_LAST_DEFINED: Do not use as a parameter value, used to - * determine the size of the enumeration. + * determine the size of the enumeration. * - * #AtspiRelationType specifies a relationship between objects + * #AtspiRelationType specifies a relationship between objects * (possibly one-to-many * or many-to-one) outside of the normal parent/child hierarchical * relationship. It allows better semantic identification of how objects - * are associated with one another. For instance the + * are associated with one another. For instance the * @ATSPI_RELATION_LABELLED_BY * relationship may be used to identify labelling information that should * accompany the accessible name property when presenting an object's content or - * identity to the end user. Similarly, + * identity to the end user. Similarly, * @ATSPI_RELATION_CONTROLLER_FOR can be used * to further specify the context in which a valuator is useful, and/or the * other UI components which are directly effected by user interactions with * the valuator. Common examples include association of scrollbars with the * viewport or panel which they control. * - * + * * Enumeration used to specify * the type of relation encapsulated in an #AtspiRelation object. * @@ -862,7 +903,7 @@ typedef enum { * etc. * @ATSPI_ROLE_GLASS_PANE: A pane that is guaranteed to be painted on top of * all panes beneath it. - * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children + * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children * represent the document content. * @ATSPI_ROLE_ICON: A small fixed size picture, typically used to decorate * components. @@ -913,7 +954,7 @@ typedef enum { * @ATSPI_ROLE_SCROLL_PANE: An object that allows a user to incrementally view * a large amount of information. @ATSPI_ROLE_SCROLL_PANE objects are usually * accompanied by @ATSPI_ROLE_SCROLL_BAR controllers, on which the - * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY + * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY * reciprocal relations are set. See #atspi_get_relation_set. * @ATSPI_ROLE_SEPARATOR: An object usually contained in a menu to provide a * visible and logical separation of the contents in a menu. @@ -921,7 +962,7 @@ typedef enum { * range. * @ATSPI_ROLE_SPIN_BUTTON: An object which allows one of a set of choices to * be selected, and which displays the current choice. Unlike - * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control + * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control * 'viewport'-like objects. * @ATSPI_ROLE_SPLIT_PANE: A specialized panel that presents two other panels * at the same time. @@ -930,7 +971,7 @@ typedef enum { * @ATSPI_ROLE_TABLE: An object used to repesent information in terms of rows * and columns. * @ATSPI_ROLE_TABLE_CELL: A 'cell' or discrete child within a Table. Note: - * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other + * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other * #AtspiRoleType values are valid as well. * @ATSPI_ROLE_TABLE_COLUMN_HEADER: An object which labels a particular column * in an #AtspiTable. @@ -954,7 +995,7 @@ typedef enum { * user. * @ATSPI_ROLE_TREE_TABLE: An object that presents both tabular and * hierarchical info to the user. - * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information, + * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information, * but its role is not known. * @ATSPI_ROLE_VIEWPORT: An object usually used in a scroll pane, or to * otherwise clip a larger object or content renderer to a specific @@ -966,11 +1007,11 @@ typedef enum { * @ATSPI_ROLE_FOOTER: An object that serves as a document footer. * @ATSPI_ROLE_PARAGRAPH: An object which is contains a single paragraph of * text content. See also @ATSPI_ROLE_TEXT. - * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc. - * for text objects which it controls (should have + * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc. + * for text objects which it controls (should have * @ATSPI_RELATION_CONTROLLER_FOR relation to such). * @ATSPI_ROLE_APPLICATION: An object corresponding to the toplevel accessible - * of an application, which may contain @ATSPI_ROLE_FRAME objects or other + * of an application, which may contain @ATSPI_ROLE_FRAME objects or other * accessible objects. Children of #AccessibleDesktop objects are generally * @ATSPI_ROLE_APPLICATION objects. * @ATSPI_ROLE_AUTOCOMPLETE: The object is a dialog or list containing items @@ -984,13 +1025,13 @@ typedef enum { * and for embedding of out-of-process component, "panel applets", etc. * @ATSPI_ROLE_ENTRY: The object is a component whose textual content may be * entered or modified by the user, provided @ATSPI_STATE_EDITABLE is present. - * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is - * not present) implies a read-only 'text field' in a form, as opposed to a + * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is + * not present) implies a read-only 'text field' in a form, as opposed to a * title, label, or caption. * @ATSPI_ROLE_CHART: The object is a graphical depiction of quantitative data. * It may contain multiple subelements whose attributes and/or description * may be queried to obtain both the quantitative data and information about - * how the data is being presented. The @ATSPI_LABELLED_BY relation is + * how the data is being presented. The @ATSPI_LABELLED_BY relation is * particularly important in interpreting objects of this type, as is the * accessible description property. See @ATSPI_ROLE_CAPTION. * @ATSPI_ROLE_CAPTION: The object contains descriptive information, usually @@ -1000,7 +1041,7 @@ typedef enum { * contains a view of document content. #AtspiDocument frames may occur within * another #AtspiDocument instance, in which case the second document may be * said to be embedded in the containing instance. HTML frames are often - * @ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant, + * ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant, * should implement the #AtspiDocument interface. * @ATSPI_ROLE_HEADING: The object serves as a heading for content which * follows it in a document. The 'heading level' of the heading, if @@ -1018,22 +1059,22 @@ typedef enum { * this role should be ignored by clients, if they are encountered at all. * @ATSPI_ROLE_FORM: The object is a containing instance of document content * which has within it components with which the user can interact in order - * to input information; i.e. the object is a container for pushbuttons, + * to input information; i.e. the object is a container for pushbuttons, * comboboxes, text input fields, and other 'GUI' components. @ATSPI_ROLE_FORM * should not, in general, be used for toplevel GUI containers or dialogs, * but should be reserved for 'GUI' containers which occur within document * content, for instance within Web documents, presentations, or text - * documents. Unlike other GUI containers and dialogs which occur inside + * documents. Unlike other GUI containers and dialogs which occur inside * application instances, @ATSPI_ROLE_FORM containers' components are - * associated with the current document, rather than the current foreground + * associated with the current document, rather than the current foreground * application or viewer instance. - * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a + * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a * hypertext document. Such objects are distinct from 'inline' content * which may also use the #AtspiHypertext/#AtspiHyperlink interfacesto indicate * the range/location within a text object where an inline or embedded object * lies. * @ATSPI_ROLE_INPUT_METHOD_WINDOW: The object is a window or similar viewport - * which is used to allow composition or input of a 'complex character', + * which is used to allow composition or input of a 'complex character', * in other words it is an "input method window". * @ATSPI_ROLE_TABLE_ROW: A row in a table. * @ATSPI_ROLE_TREE_ITEM: An object that represents an element of a tree. @@ -1064,6 +1105,46 @@ typedef enum { * particular application. * @ATSPI_ROLE_INFO_BAR: An object designed to present a message to the user * within an existing window. + *@ATSPI_ROLE_LEVEL_BAR: A bar that serves as a level indicator to, for + * instance, show the strength of a password or the state of a battery. + * Since: 2.8 + *@ATSPI_ROLE_TITLE_BAR: A bar that serves as the title of a window or a + * dialog. @Since: 2.12 + *@ATSPI_ROLE_BLOCK_QUOTE: An object which contains a text section + * that is quoted from another source. @Since: 2.12 + *@ATSPI_ROLE_AUDIO: An object which represents an audio + * element. @Since: 2.12 + *@ATSPI_ROLE_VIDEO: An object which represents a video + * element. @Since: 2.12 + *@ATSPI_ROLE_DEFINITION: A definition of a term or concept. @Since: 2.12 + *@ATSPI_ROLE_ARTICLE: A section of a page that consists of a + * composition that forms an independent part of a document, page, or + * site. Examples: A blog entry, a news story, a forum post. @Since: + * 2.12 + *@ATSPI_ROLE_LANDMARK: A region of a web page intended as a + * navigational landmark. This is designed to allow Assistive + * Technologies to provide quick navigation among key regions within a + * document. @Since: 2.12 + *@ATSPI_ROLE_LOG: A text widget or container holding log content, such + * as chat history and error logs. In this role there is a + * relationship between the arrival of new items in the log and the + * reading order. The log contains a meaningful sequence and new + * information is added only to the end of the log, not at arbitrary + * points. @Since: 2.12 + *@ATSPI_ROLE_MARQUEE: A container where non-essential information + * changes frequently. Common usages of marquee include stock tickers + * and ad banners. The primary difference between a marquee and a log + * is that logs usually have a meaningful order or sequence of + * important content changes. @Since: 2.12 + *@ATSPI_ROLE_MATH: A text widget or container that holds a mathematical + * expression. @Since: 2.12 + *@ATSPI_ROLE_RATING: A widget whose purpose is to display a rating, + * such as the number of stars associated with a song in a media + * player. Objects of this role should also implement + * AtspiValue. @Since: 2.12 + *@ATSPI_ROLE_TIMER: An object containing a numerical counter which + * indicates an amount of elapsed time from a start point, or the time + * remaining until an end point. @Since: 2.12 * @ATSPI_ROLE_LAST_DEFINED: Not a valid role, used for finding end of * enumeration. * @@ -1175,6 +1256,19 @@ typedef enum { ATSPI_ROLE_IMAGE_MAP, ATSPI_ROLE_NOTIFICATION, ATSPI_ROLE_INFO_BAR, + ATSPI_ROLE_LEVEL_BAR, + ATSPI_ROLE_TITLE_BAR, + ATSPI_ROLE_BLOCK_QUOTE, + ATSPI_ROLE_AUDIO, + ATSPI_ROLE_VIDEO, + ATSPI_ROLE_DEFINITION, + ATSPI_ROLE_ARTICLE, + ATSPI_ROLE_LANDMARK, + ATSPI_ROLE_LOG, + ATSPI_ROLE_MARQUEE, + ATSPI_ROLE_MATH, + ATSPI_ROLE_RATING, + ATSPI_ROLE_TIMER, ATSPI_ROLE_LAST_DEFINED, } AtspiRole; @@ -1187,8 +1281,8 @@ typedef enum { typedef enum { - ATSPI_CACHE_NONE = 0, - ATSPI_CACHE_PARENT = 1 << 0, + ATSPI_CACHE_NONE = 0, + ATSPI_CACHE_PARENT = 1 << 0, ATSPI_CACHE_CHILDREN = 1 << 1, ATSPI_CACHE_NAME = 1 << 2, ATSPI_CACHE_DESCRIPTION = 1 << 3, @@ -1197,10 +1291,7 @@ typedef enum ATSPI_CACHE_INTERFACES = 1 << 6, ATSPI_CACHE_ATTRIBUTES = 1 << 7, ATSPI_CACHE_ALL = 0x3fffffff, - ATSPI_CACHE_DEFAULT = ATSPI_CACHE_PARENT | ATSPI_CACHE_CHILDREN | - ATSPI_CACHE_NAME | ATSPI_CACHE_DESCRIPTION | - ATSPI_CACHE_STATES | ATSPI_CACHE_ROLE | - ATSPI_CACHE_INTERFACES, + ATSPI_CACHE_DEFAULT = ATSPI_CACHE_PARENT | ATSPI_CACHE_CHILDREN | ATSPI_CACHE_NAME | ATSPI_CACHE_DESCRIPTION | ATSPI_CACHE_STATES | ATSPI_CACHE_ROLE | ATSPI_CACHE_INTERFACES, ATSPI_CACHE_UNDEFINED = 0x40000000, } AtspiCache; @@ -1231,6 +1322,7 @@ typedef enum #define ATSPI_DBUS_INTERFACE_IMAGE "org.a11y.atspi.Image" #define ATSPI_DBUS_INTERFACE_SELECTION "org.a11y.atspi.Selection" #define ATSPI_DBUS_INTERFACE_TABLE "org.a11y.atspi.Table" +#define ATSPI_DBUS_INTERFACE_TABLE_CELL "org.a11y.atspi.TableCell" #define ATSPI_DBUS_INTERFACE_TEXT "org.a11y.atspi.Text" #define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value" #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index a2de0d87ed..f76a9df004 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -49,6 +49,7 @@ includesdir = $(includedir)/elementary-@VMAJ@ includesunstable_HEADERS = \ elm_gen_common.h \ elm_interface_atspi_accessible.h \ +elm_interface_atspi_text.h \ elm_interface_fileselector.h \ elm_interface_scrollable.h \ elm_widget.h \ @@ -452,9 +453,11 @@ elm_index.c \ elm_interface_atspi_accessible.c \ elm_interface_atspi_action.c \ elm_interface_atspi_component.c \ +elm_interface_atspi_editable_text.c \ elm_interface_atspi_image.c \ -elm_interface_atspi_value.c \ elm_interface_atspi_selection.c \ +elm_interface_atspi_text.c \ +elm_interface_atspi_value.c \ elm_interface_atspi_widget.c \ elm_interface_atspi_widget_action.c \ elm_interface_atspi_window.c \ @@ -660,16 +663,20 @@ BUILT_SOURCES = \ elm_interface_atspi_action.eo.h \ elm_interface_atspi_component.eo.c \ elm_interface_atspi_component.eo.h \ + elm_interface_atspi_editable_text.eo.c \ + elm_interface_atspi_editable_text.eo.h \ elm_interface_atspi_image.eo.c \ elm_interface_atspi_image.eo.h \ + elm_interface_atspi_selection.eo.c \ + elm_interface_atspi_selection.eo.h \ + elm_interface_atspi_text.eo.c \ + elm_interface_atspi_text.eo.h \ elm_interface_atspi_value.eo.c \ elm_interface_atspi_value.eo.h \ elm_interface_atspi_widget.eo.c \ elm_interface_atspi_widget.eo.h \ elm_interface_atspi_widget_action.eo.c \ elm_interface_atspi_widget_action.eo.h \ - elm_interface_atspi_selection.eo.c \ - elm_interface_atspi_selection.eo.h \ elm_interface_atspi_window.eo.c \ elm_interface_atspi_window.eo.h \ elm_interface_fileselector.eo.c \ @@ -795,9 +802,11 @@ elementaryeolianfiles_DATA = \ elm_interface_atspi_accessible.eo \ elm_interface_atspi_action.eo \ elm_interface_atspi_component.eo \ + elm_interface_atspi_editable_text.eo \ elm_interface_atspi_image.eo \ - elm_interface_atspi_value.eo \ elm_interface_atspi_selection.eo \ + elm_interface_atspi_text.eo \ + elm_interface_atspi_value.eo \ elm_interface_atspi_widget.eo \ elm_interface_atspi_widget_action.eo \ elm_interface_atspi_window.eo \ @@ -889,9 +898,11 @@ nodist_includesunstable_HEADERS = \ elm_interface_atspi_accessible.eo.h \ elm_interface_atspi_action.eo.h \ elm_interface_atspi_component.eo.h \ + elm_interface_atspi_editable_text.eo.h \ elm_interface_atspi_image.eo.h \ - elm_interface_atspi_value.eo.h \ elm_interface_atspi_selection.eo.h \ + elm_interface_atspi_text.eo.h \ + elm_interface_atspi_value.eo.h \ elm_interface_atspi_widget.eo.h \ elm_interface_atspi_widget_action.eo.h \ elm_interface_atspi_window.eo.h \ diff --git a/legacy/elementary/src/lib/elm_atspi_bridge.c b/legacy/elementary/src/lib/elm_atspi_bridge.c index 5101145553..6ebdcf1293 100644 --- a/legacy/elementary/src/lib/elm_atspi_bridge.c +++ b/legacy/elementary/src/lib/elm_atspi_bridge.c @@ -8,6 +8,9 @@ #define ELM_INTERFACE_ATSPI_VALUE_PROTECTED #define ELM_INTERFACE_ATSPI_IMAGE_PROTECTED #define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED +#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED +#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED + #include "atspi/atspi-constants.h" #include @@ -23,6 +26,9 @@ #include "elm_interface_atspi_value.eo.h" #include "elm_interface_atspi_image.eo.h" #include "elm_interface_atspi_selection.eo.h" +#include "elm_interface_atspi_text.h" +#include "elm_interface_atspi_text.eo.h" +#include "elm_interface_atspi_editable_text.eo.h" /* * Accessibility Bus info not defined in atspi-constants.h @@ -51,8 +57,9 @@ static Eina_Hash *_cache; static Eldbus_Service_Interface *_cache_interface = NULL; static Eldbus_Signal_Handler *_register_hdl; static Eldbus_Signal_Handler *_unregister_hdl; -static unsigned short _object_property_broadcast_mask; -static unsigned short _object_children_broadcast_mask; +static unsigned long _object_broadcast_mask; +static unsigned long _object_property_broadcast_mask; +static unsigned long _object_children_broadcast_mask; static unsigned long long _object_state_broadcast_mask; static unsigned long long _window_signal_broadcast_mask; @@ -61,9 +68,13 @@ static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Eve static Eina_Bool _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info); static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); static Eina_Bool _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); +static Eina_Bool _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); +static Eina_Bool _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); +static Eina_Bool _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); +static Eina_Bool _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED); static Eo * _access_object_from_path(const char *path); static char * _path_from_access_object(const Eo *eo); -static void _object_append_reference(Eldbus_Message_Iter *iter, const Eo *obj); +static void _iter_object_reference_append(Eldbus_Message_Iter *iter, const Eo *obj); static void _object_append_desktop_reference(Eldbus_Message_Iter *iter); static void _cache_build(void *obj); static void _object_register(Eo *obj, char *path); @@ -86,6 +97,15 @@ EO_CALLBACKS_ARRAY_DEFINE(_selection_cb, { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send} ); +EO_CALLBACKS_ARRAY_DEFINE(_text_cb, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, _text_caret_moved_send }, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, _text_text_inserted_send }, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, _text_text_removed_send }, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, _text_selection_changed_send }, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_BOUNDS_CHANGED, NULL }, + { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_ATTRIBUTES_CHANGED, NULL } +); + enum _Atspi_Object_Child_Event_Type { ATSPI_OBJECT_CHILD_ADDED = 0, @@ -167,7 +187,7 @@ static const Eldbus_Signal _event_obj_signals[] = { [ATSPI_OBJECT_EVENT_COLUMN_DELETED] = {"ColumnDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, [ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED] = {"TextBoundsChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, [ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED] = {"SelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, - [ATSPI_OBJECT_EVENT_TEXT_CHANGED] = {"TextChaged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, + [ATSPI_OBJECT_EVENT_TEXT_CHANGED] = {"TextChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, [ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED] = {"TextAttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, [ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED] = {"TextCaretMoved", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, [ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED] = {"AttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0}, @@ -196,7 +216,6 @@ static const Eldbus_Signal _window_obj_signals[] = { {NULL, ELDBUS_ARGS({NULL, NULL}), 0} }; - const int elm_roles_to_atspi_roles[][2] = { { ELM_ATSPI_ROLE_INVALID, ATSPI_ROLE_INVALID }, { ELM_ATSPI_ROLE_ACCELERATOR_LABEL, ATSPI_ROLE_ACCELERATOR_LABEL }, @@ -302,7 +321,7 @@ const int elm_roles_to_atspi_roles[][2] = { { ELM_ATSPI_ROLE_NOTIFICATION, ATSPI_ROLE_NOTIFICATION }, { ELM_ATSPI_ROLE_INFO_BAR, ATSPI_ROLE_INFO_BAR }, { ELM_ATSPI_ROLE_LAST_DEFINED, ATSPI_ROLE_LAST_DEFINED }, -}; +}; const int elm_states_to_atspi_state[][2] = { @@ -449,7 +468,7 @@ _accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Mes EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); EINA_LIST_FOREACH(children_list, l, children) - _object_append_reference(iter_array, children); + _iter_object_reference_append(iter_array, children); eldbus_message_iter_container_close(iter, iter_array); eina_list_free(children_list); @@ -467,7 +486,7 @@ _accessible_get_application(const Eldbus_Service_Interface *iface EINA_UNUSED, c Eldbus_Message *ret = eldbus_message_method_return_new(msg); EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret); - _object_append_reference(iter, _root); + _iter_object_reference_append(iter, _root); return ret; } @@ -477,7 +496,7 @@ _accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_M { Eina_List *attrs, *l; Elm_Atspi_Attribute *attr; - Eldbus_Message_Iter *iter, *iter_array; + Eldbus_Message_Iter *iter, *iter_dict, *iter_entry; Eldbus_Message *ret = eldbus_message_method_return_new(msg); EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); @@ -488,12 +507,18 @@ _accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_M eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get()); iter = eldbus_message_iter_get(ret); - iter_array = eldbus_message_iter_container_new(iter, 'a', "ss"); + iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}"); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL); EINA_LIST_FOREACH(attrs, l, attr) - eldbus_message_iter_arguments_append(iter_array, "ss", attr->key, attr->value); + { + iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL); + eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value); + eldbus_message_iter_container_close(iter_dict, iter_entry); + } - eldbus_message_iter_container_close(iter, iter_array); + eldbus_message_iter_container_close(iter, iter_dict); elm_atspi_attributes_list_free(attrs); return ret; @@ -594,7 +619,7 @@ _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, co eo_do(obj, children = elm_interface_atspi_accessible_children_get()); child = eina_list_nth(children, idx); - _object_append_reference(iter, child); + _iter_object_reference_append(iter, child); eina_list_free(children); return ret; @@ -625,7 +650,7 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type)); iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)"); EINA_SAFETY_ON_NULL_GOTO(iter_array2, fail); - _object_append_reference(iter_array2, rel->obj); + _iter_object_reference_append(iter_array2, rel->obj); eldbus_message_iter_container_close(iter_struct, iter_array2); eldbus_message_iter_container_close(iter_array, iter_struct); free(rel); @@ -672,7 +697,7 @@ _selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED, iter = eldbus_message_iter_get(ret); eo_do(obj, child = elm_interface_atspi_selection_selected_child_get(idx)); - _object_append_reference(iter, child); + _iter_object_reference_append(iter, child); return ret; } @@ -1032,6 +1057,657 @@ static const Eldbus_Method image_methods[] = { { NULL, NULL, NULL, NULL, 0 } }; +static Eldbus_Message * +_text_string_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + char *str; + AtspiTextGranularity gran; + int start, end; + Eldbus_Message *ret; + Eo *obj = _access_object_from_path(obj_path); + + if (!eldbus_message_arguments_get(msg, "iu", &start, &gran)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, str = elm_interface_atspi_text_string_get(gran, &start, &end)); + str = str ? str : strdup(""); + + eldbus_message_arguments_append(ret, "sii", str, start, end); + free(str); + + return ret; +} + +static Eldbus_Message * +_text_text_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + char *str; + Eo *obj = _access_object_from_path(obj_path); + int start, end; + + if (!eldbus_message_arguments_get(msg, "ii", &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected."); + + Eldbus_Message *ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, str = elm_interface_atspi_text_text_get(start, end)); + str = str ? str : strdup(""); + + eldbus_message_arguments_append(ret, "s", str); + free(str); + + return ret; +} + +static Eldbus_Message * +_text_caret_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int offset; + Eldbus_Message *ret; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "i", &offset)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_caret_offset_set(offset)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_text_character_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int offset; + Eldbus_Message *ret; + Eina_Unicode res; + + if (!eldbus_message_arguments_get(msg, "i", &offset)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_character_get(offset)); + + eldbus_message_arguments_append(ret, "i", res); + + return ret; +} + +static Eldbus_Message * +_text_attribute_value_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *name, *obj_path = eldbus_service_object_path_get(iface); + char *value = NULL; + Eo *obj = _access_object_from_path(obj_path); + int start, end; + Eldbus_Message *ret; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "is", &start, &name)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and attribute name expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_attribute_get(name, &start, &end, &value)); + eldbus_message_arguments_append(ret, "siib", value ? value : "", start, end, res); + + if (value) free(value); + return ret; +} + +static Eldbus_Message * +_text_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int start, end; + Eldbus_Message *ret; + Eldbus_Message_Iter *iter, *iter_array; + Eina_List *attrs; + Elm_Atspi_Text_Attribute *attr; + + if (!eldbus_message_arguments_get(msg, "i", &start)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + + eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end)); + + EINA_LIST_FREE(attrs, attr) + { + eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value); + elm_atspi_text_text_attribute_free(attr); + } + + eldbus_message_iter_container_close(iter, iter_array); + eldbus_message_iter_arguments_append(iter, "ii", start, end); + + return ret; + +fail: + if (ret) eldbus_message_unref(ret); + return NULL; +} + +static Eldbus_Message * +_text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int start = -1, end; + Eldbus_Message *ret; + Eldbus_Message_Iter *iter, *iter_array; + Eina_List *attrs; + Elm_Atspi_Text_Attribute *attr; + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + + eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end)); + + EINA_LIST_FREE(attrs, attr) + { + eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value); + elm_atspi_text_text_attribute_free(attr); + } + + eldbus_message_iter_container_close(iter, iter_array); + eldbus_message_iter_arguments_append(iter, "ii", start, end); + + return ret; + +fail: + if (ret) eldbus_message_unref(ret); + return NULL; +} + +static Eldbus_Message * +_text_character_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int offset; + Eina_Rectangle rect; + AtspiCoordType type; + Eina_Bool screen_coords, res; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "iu", &offset, &type)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; + + eo_do(obj, res = elm_interface_atspi_text_character_extents_get(offset, screen_coords, &rect)); + + if (!res) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get character extents."); + eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h); + + return ret; +} + +static Eldbus_Message * +_text_offset_at_point_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int offset, x, y; + AtspiCoordType type; + Eina_Bool screen_coords; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &type)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + x = y = -1; + screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; + + eo_do(obj, offset = elm_interface_atspi_text_offset_at_point_get(screen_coords, x, y)); + + eldbus_message_arguments_append(ret, "i", offset); + + return ret; +} + +static Eldbus_Message * +_text_n_selections_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int n; + Eldbus_Message *ret; + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, n = elm_interface_atspi_text_selections_count_get()); + + eldbus_message_arguments_append(ret, "i", n); + + return ret; +} + +static Eldbus_Message * +_text_selection_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int sel_num, start, end; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &sel_num)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, elm_interface_atspi_text_selection_get(sel_num, &start, &end)); + + eldbus_message_arguments_append(ret, "ii", start, end); + + return ret; +} + +static Eldbus_Message * +_text_selection_add(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int start, end; + Eina_Bool res; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "ii", &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end text offset expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_selection_add(start, end)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_text_selection_remove(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int sel_num; + Eina_Bool res; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &sel_num)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_selection_remove(sel_num)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_text_selection_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int sel_num, start, end; + Eina_Bool res; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "iii", &sel_num, &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_text_selection_set(sel_num, start, end)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_text_range_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int start, end; + Eina_Rectangle rect; + Eina_Bool screen_coords, res; + AtspiCoordType type; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "iiu", &start, &end, &type)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; + eo_do(obj, res = elm_interface_atspi_text_range_extents_get(screen_coords, start, end, &rect)); + if (!res) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Can't get range extents."); + + eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h); + + return ret; +} + +static Eldbus_Message * +_text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eina_Rectangle rect; + Eina_Bool screen_coords; + AtspiCoordType type; + AtspiTextClipType xc, yc; + Elm_Atspi_Text_Clip_Type xclip, yclip; + Eina_List *ranges; + Eldbus_Message *ret; + Elm_Atspi_Text_Range *range; + Eldbus_Message_Iter *iter, *iter_array, *iter_struct, *iter_var; + + if (!eldbus_message_arguments_get(msg, "iiiiuuu", &rect.x, &rect.y, &rect.w, &rect.h, &type, &xc, &yc)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected (x,y,w,h) of bounding box, screen coord type and x, y text clip types."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + iter_array = eldbus_message_iter_container_new(iter, 'a', "(iisv)"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + + xclip = xc; + yclip = yc; + + screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; + eo_do(obj, ranges = elm_interface_atspi_text_bounded_ranges_get(screen_coords, rect, xclip, yclip)); + + EINA_LIST_FREE(ranges, range) + { + iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL); + if (iter_struct) + { + eldbus_message_iter_basic_append(iter_struct, 'i', range->start_offset); + eldbus_message_iter_basic_append(iter_struct, 'i', range->end_offset); + range->content = range->content ? range->content : strdup(""); + eldbus_message_iter_basic_append(iter_struct, 's', range->content); + /* AT-SPI specification requires variant type in return, however + * ATK or other implementations as well as AT Clients don't use it . + * To cover spec a dummy value will be returned */ + iter_var = eldbus_message_iter_container_new(iter_struct, 'v', "i"); + if (iter_var) + { + eldbus_message_iter_basic_append(iter_var, 'i', 0); + eldbus_message_iter_container_close(iter_struct, iter_var); + } + eldbus_message_iter_container_close(iter_array, iter_struct); + } + if (range->content) free(range->content); + free(range); + } + + eldbus_message_iter_container_close(iter, iter_array); + + return ret; + +fail: + if (ret) eldbus_message_unref(ret); + return NULL; +} + +static Eldbus_Message * +_text_run_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int start, end; + Eldbus_Message *ret; + Eldbus_Message_Iter *iter, *iter_array; + Eina_List *attrs, *defaults; + Elm_Atspi_Text_Attribute *attr; + Eina_Bool incl_def; + + if (!eldbus_message_arguments_get(msg, "ib", &start, &incl_def)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and include defaults flag expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + + eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end)); + + if (incl_def) + { + eo_do(obj, defaults = elm_interface_atspi_text_default_attributes_get()); + attrs = eina_list_merge(attrs, defaults); + } + + EINA_LIST_FREE(attrs, attr) + { + eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value); + elm_atspi_text_text_attribute_free(attr); + } + + eldbus_message_iter_container_close(iter, iter_array); + eldbus_message_iter_arguments_append(iter, "ii", start, end); + + return ret; + +fail: + if (ret) eldbus_message_unref(ret); + return NULL; +} + +static const Eldbus_Method text_methods[] = { + { "GetTextAtOffset", ELDBUS_ARGS({"i", "offset"}, {"u", "granularity"}), ELDBUS_ARGS({"s", "string"}, {"i", "startOffset"}, {"i", "endOffset"}), _text_string_at_offset_get, 0 }, + { "GetText", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"s", "string"}), _text_text_get, 0 }, + { "SetCaretOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"b", NULL}), _text_caret_offset_set, 0 }, + { "GetCharacterAtOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"i", NULL}), _text_character_at_offset_get, 0 }, + { "GetAttributeValue", ELDBUS_ARGS({"i", "offset"}, {"s", "attributeName"}), ELDBUS_ARGS({"s", NULL}, {"i", "startOffset"}, {"i", "endOffset"}, {"b", "defined"}), _text_attribute_value_get, 0 }, + { "GetAttributes", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_attributes_get, 0 }, + { "GetDefaultAttributes", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 }, + { "GetCharacterExtents", ELDBUS_ARGS({"i", "offset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_character_extents_get, 0 }, + { "GetOffsetAtPoint", ELDBUS_ARGS({"i", "x"}, {"i","y"}, {"u", "coordType"}), ELDBUS_ARGS({"i", NULL}), _text_offset_at_point_get, 0 }, + { "GetNSelections", NULL, ELDBUS_ARGS({"i", NULL}), _text_n_selections_get, 0 }, + { "GetSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), _text_selection_get, 0 }, + { "AddSelection", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_add, 0 }, + { "RemoveSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"b", NULL}), _text_selection_remove, 0 }, + { "SetSelection", ELDBUS_ARGS({"i", "selectionNum"}, {"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_set, 0 }, + { "GetRangeExtents", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_range_extents_get, 0 }, + { "GetBoundedRanges", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "w"}, {"i", "h"}, {"u", "coordType"}, {"u", "xClipType"}, {"u", "yClipType"}), ELDBUS_ARGS({"a(issv)", NULL}), _text_bounded_ranges_get, 0 }, + { "GetAttributeRun", ELDBUS_ARGS({"i", "offset"}, {"b", "includeDefaults"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_run_attributes_get, 0 }, + { "GetDefaultAttributeSet", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + +static Eldbus_Message * +_editable_text_text_content_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + const char *content; + Eldbus_Message *ret; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "s", &content)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "String expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_content_set(content)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_editable_text_text_insert(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + const char *text; + Eldbus_Message *ret; + int pos, len; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "isi", &pos, &text, &len)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Postion, string, length expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_insert(text, pos)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_editable_text_text_copy(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eldbus_Message *ret; + int start, end; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "ii", &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_copy(start, end)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_editable_text_text_cut(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eldbus_Message *ret; + int start, end; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "ii", &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_cut(start, end)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_editable_text_text_delete(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eldbus_Message *ret; + int start, end; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "ii", &start, &end)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_delete(start, end)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static Eldbus_Message * +_editable_text_text_paste(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eldbus_Message *ret; + int pos; + Eina_Bool res; + + if (!eldbus_message_arguments_get(msg, "i", &pos)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, res = elm_interface_atspi_editable_text_paste(pos)); + + eldbus_message_arguments_append(ret, "b", res); + + return ret; +} + +static const Eldbus_Method editable_text_methods[] = { + { "SetTextContents", ELDBUS_ARGS({"s", "newcontents"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_content_set, 0 }, + { "InsertText", ELDBUS_ARGS({"i", "position"}, {"s", "text"}, {"i", "length"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_insert, 0 }, + { "CopyText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), NULL, _editable_text_text_copy, 0 }, + { "CutText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_cut, 0 }, + { "DeleteText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_delete, 0 }, + { "PasteText", ELDBUS_ARGS({"i", "position"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_paste, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + static Eo * _access_object_from_path(const char *path) { @@ -1101,7 +1777,7 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char * if ((!ret_obj) && (ELM_ATSPI_ROLE_APPLICATION == role)) _object_append_desktop_reference(iter); else - _object_append_reference(iter, ret_obj); + _iter_object_reference_append(iter, ret_obj); return EINA_TRUE; } else if (!strcmp(property, "ChildCount")) @@ -1249,6 +1925,32 @@ _image_properties_get(const Eldbus_Service_Interface *interface, const char *pro return EINA_FALSE; } +static Eina_Bool +_text_properties_get(const Eldbus_Service_Interface *interface, const char *property, + Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED, + Eldbus_Message **error EINA_UNUSED) +{ + const char *obj_path = eldbus_service_object_path_get(interface); + Eo *obj = _access_object_from_path(obj_path); + int val; + + EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); + + if (!strcmp(property, "CharacterCount")) + { + eo_do(obj, val = elm_interface_atspi_text_character_count_get()); + eldbus_message_iter_basic_append(iter, 'i', val); + return EINA_TRUE; + } + if (!strcmp(property, "CaretOffset")) + { + eo_do(obj, val = elm_interface_atspi_text_caret_offset_get()); + eldbus_message_iter_basic_append(iter, 'i', val); + return EINA_TRUE; + } + return EINA_FALSE; +} + static const Eldbus_Property accessible_properties[] = { { "Name", "s", _accessible_property_get, NULL, 0 }, { "Description", "s", _accessible_property_get, NULL, 0 }, @@ -1281,6 +1983,12 @@ static const Eldbus_Property selection_properties[] = { { NULL, NULL, NULL, NULL, 0 } }; +static const Eldbus_Property text_properties[] = { + { "CharacterCount", "i", NULL, NULL, 0 }, + { "CaretOffset", "i", NULL, NULL, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + static const Eldbus_Service_Interface_Desc accessible_iface_desc = { ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL }; @@ -1309,8 +2017,16 @@ static const Eldbus_Service_Interface_Desc selection_iface_desc = { ATSPI_DBUS_INTERFACE_SELECTION, selection_methods, NULL, selection_properties, NULL, NULL }; +static const Eldbus_Service_Interface_Desc text_iface_desc = { + ATSPI_DBUS_INTERFACE_TEXT, text_methods, NULL, text_properties, _text_properties_get, NULL +}; + +static const Eldbus_Service_Interface_Desc editable_text_iface_desc = { + ATSPI_DBUS_INTERFACE_EDITABLE_TEXT, editable_text_methods, NULL, NULL, NULL, NULL +}; + static void -_object_append_reference(Eldbus_Message_Iter *iter, const Eo *obj) +_iter_object_reference_append(Eldbus_Message_Iter *iter, const Eo *obj) { Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); EINA_SAFETY_ON_NULL_RETURN(iter); @@ -1349,10 +2065,10 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE); /* Marshall object path */ - _object_append_reference(iter_struct, data); + _iter_object_reference_append(iter_struct, data); /* Marshall application */ - _object_append_reference(iter_struct, _root); + _iter_object_reference_append(iter_struct, _root); Eo *parent = NULL; eo_do(data, parent = elm_interface_atspi_accessible_parent_get()); @@ -1360,7 +2076,7 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role)) _object_append_desktop_reference(iter_struct); else - _object_append_reference(iter_struct, parent); + _iter_object_reference_append(iter_struct, parent); /* Marshall children */ Eina_List *children_list = NULL, *l; @@ -1371,7 +2087,7 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail); EINA_LIST_FOREACH(children_list, l, child) - _object_append_reference(iter_sub_array, child); + _iter_object_reference_append(iter_sub_array, child); eldbus_message_iter_container_close(iter_struct, iter_sub_array); eina_list_free(children_list); @@ -1389,6 +2105,12 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_VALUE); if (eo_isa(data, ELM_INTERFACE_ATSPI_IMAGE_CLASS)) eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_IMAGE); + if (eo_isa(data, ELM_INTERFACE_ATSPI_SELECTION_CLASS)) + eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_SELECTION); + if (eo_isa(data, ELM_INTERFACE_ATSPI_TEXT_CLASS)) + eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_TEXT); + if (eo_isa(data, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_CLASS)) + eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT); eldbus_message_iter_container_close(iter_struct, iter_sub_array); @@ -1510,7 +2232,7 @@ _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UN iter = eldbus_message_iter_get(ret); Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; eo_do(obj, accessible = elm_interface_atspi_component_accessible_at_point_get(type, x, y)); - _object_append_reference(iter, accessible); + _iter_object_reference_append(iter, accessible); return ret; } @@ -1772,7 +2494,7 @@ _elm_atspi_bridge_app_register(void) "Embed"); Eldbus_Message_Iter *iter = eldbus_message_iter_get(message); - _object_append_reference(iter, _root); + _iter_object_reference_append(iter, _root); eldbus_connection_send(_a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1); return EINA_TRUE; @@ -1788,7 +2510,7 @@ _elm_atspi_bridge_app_unregister(void) "Unembed"); Eldbus_Message_Iter *iter = eldbus_message_iter_get(message); - _object_append_reference(iter, _root); + _iter_object_reference_append(iter, _root); eldbus_connection_send(_a11y_bus, message, NULL, NULL, -1); return EINA_TRUE; @@ -1845,6 +2567,16 @@ _set_broadcast_flag(const char *event) else if (!strcmp(tokens[2], "remove")) STATE_TYPE_SET(_object_children_broadcast_mask, ATSPI_OBJECT_CHILD_ADDED); } + else if (!strcmp(tokens[1], "TextChanged")) + STATE_TYPE_SET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED); + else if (!strcmp(tokens[1], "TextCaretMoved")) + STATE_TYPE_SET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED); + else if (!strcmp(tokens[1], "TextBoundsChanged")) + STATE_TYPE_SET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED); + else if (!strcmp(tokens[1], "TextSelectionChanged")) + STATE_TYPE_SET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED); + else if (!strcmp(tokens[1], "TextAttributesChanged")) + STATE_TYPE_SET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED); } else if (!strcmp(tokens[0], "Window")) { @@ -1866,6 +2598,7 @@ static void _registered_listeners_get(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) { DBG("Updating registered ATSPI signals list."); + _object_broadcast_mask = 0; _object_children_broadcast_mask = 0; _object_property_broadcast_mask = 0; _object_state_broadcast_mask = 0; @@ -1906,7 +2639,7 @@ _handle_listener_change(void *data EINA_UNUSED, const Eldbus_Message *msg) } static Eina_Bool -_state_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) +_state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) { Eldbus_Message *msg; Eldbus_Message_Iter *iter, *viter; @@ -1936,6 +2669,9 @@ _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc case ELM_ATSPI_STATE_VISIBLE: type_desc = "visible"; break; + case ELM_ATSPI_STATE_ACTIVE: + type_desc = "active"; + break; default: return EINA_FALSE; } @@ -1951,7 +2687,7 @@ _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc eldbus_message_iter_arguments_append(viter, "i", 0); eldbus_message_iter_container_close(iter, viter); - _object_append_reference(iter, obj); + _iter_object_reference_append(iter, _root); eldbus_service_signal_send(events, msg); DBG("signal sent StateChanged:%s:%d", type_desc, state_data->new_value); @@ -2097,10 +2833,10 @@ _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *d viter = eldbus_message_iter_container_new(iter, 'v', "(so)"); EINA_SAFETY_ON_NULL_RETURN_VAL(viter, EINA_FALSE); - _object_append_reference(viter, ev_data->child); + _iter_object_reference_append(viter, ev_data->child); eldbus_message_iter_container_close(iter, viter); - _object_append_reference(iter, _root); + _iter_object_reference_append(iter, _root); eldbus_service_signal_send(events, msg); DBG("signal sent childrenChanged:%s:%d", atspi_desc, idx); @@ -2159,7 +2895,7 @@ _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void eldbus_message_iter_arguments_append(viter, "i", 0); eldbus_message_iter_container_close(iter, viter); - _object_append_reference(iter, obj); + _iter_object_reference_append(iter, obj); eldbus_service_signal_send(window, msg); DBG("signal sent Window:%s", event_desc); @@ -2204,12 +2940,128 @@ _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, vo eldbus_message_iter_arguments_append(viter, "i", 0); eldbus_message_iter_container_close(iter, viter); - _object_append_reference(iter, obj); + _iter_object_reference_append(iter, obj); eldbus_service_signal_send(selection, msg); - DBG("signal sent Selection:%s", event_desc); + return EINA_TRUE; } + +static void _object_signal_send(Eldbus_Service_Interface *infc, int sig_id, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...) +{ + Eldbus_Message *msg; + Eldbus_Message_Iter *iter , *viter; + va_list va; + va_start(va, variant_sig); + + EINA_SAFETY_ON_NULL_RETURN(infc); + EINA_SAFETY_ON_NULL_RETURN(minor); + + msg = eldbus_service_signal_new(infc, sig_id); + EINA_SAFETY_ON_NULL_RETURN(msg); + + iter = eldbus_message_iter_get(msg); + + eldbus_message_iter_arguments_append(iter, "sii", minor, det1, det2); + + if (variant_sig) + { + viter = eldbus_message_iter_container_new(iter, 'v', variant_sig); + const char *tmp = variant_sig; + while (*tmp) + { + switch (*tmp) + { + case 's': + eldbus_message_iter_basic_append(viter, 's', va_arg(va, char*)); + break; + default: + ERR("Not supported type: %c. Invalid variant signature %s. ", *tmp, variant_sig); + break; + } + tmp++; + } + } + else // AT-SPI implementation forces checks on signature even if varint is not used. + { + viter = eldbus_message_iter_container_new(iter, 'v', "i"); + eldbus_message_iter_basic_append(viter, 'i', 0); + } + + va_end(va); + eldbus_message_iter_container_close(iter, viter); + + _iter_object_reference_append(iter, _root); + + eldbus_service_signal_send(infc, msg); +} + +static Eina_Bool +_text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eldbus_Service_Interface *event = data; + int cursor_pos = 0; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, EINA_TRUE); + + if (!STATE_TYPE_GET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED)) + return EINA_TRUE; + + eo_do(obj, cursor_pos = elm_interface_atspi_text_caret_offset_get()); + + _object_signal_send(event, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED, "", cursor_pos, 0, NULL, NULL); + return EINA_TRUE; +} + +static Eina_Bool +_text_text_inserted_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) +{ + Eldbus_Service_Interface *event = data; + Elm_Atspi_Text_Change_Info *info = event_info; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, EINA_TRUE); + EINA_SAFETY_ON_NULL_RETURN_VAL(event_info, EINA_TRUE); + + if (!STATE_TYPE_GET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED)) + return EINA_TRUE; + + _object_signal_send(event, ATSPI_OBJECT_EVENT_TEXT_CHANGED, "insert", info->pos, info->len, "s", info->content); + + return EINA_TRUE; +} + +static Eina_Bool +_text_text_removed_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) +{ + Eldbus_Service_Interface *event = data; + Elm_Atspi_Text_Change_Info *info = event_info; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, EINA_TRUE); + EINA_SAFETY_ON_NULL_RETURN_VAL(event_info, EINA_TRUE); + + if (!STATE_TYPE_GET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED)) + return EINA_TRUE; + + _object_signal_send(event, ATSPI_OBJECT_EVENT_TEXT_CHANGED, "delete", info->pos, info->len, "s", info->content); + + return EINA_TRUE; +} + +static Eina_Bool +_text_selection_changed_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eldbus_Service_Interface *event = data; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, EINA_TRUE); + + if (!STATE_TYPE_GET(_object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED)) + return EINA_TRUE; + + _object_signal_send(event, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED, "", 0, 0, NULL, NULL); + + return EINA_TRUE; +} + static void _event_handlers_register(void) { @@ -2292,7 +3144,7 @@ end: static void _object_register(Eo *obj, char *path) { - Eldbus_Service_Interface *infc = NULL; + Eldbus_Service_Interface *infc = NULL, *event_infc; if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_CLASS)) { @@ -2304,22 +3156,16 @@ static void _object_register(Eo *obj, char *path) { eldbus_service_interface_register(_a11y_bus, path, &accessible_iface_desc); - infc = eldbus_service_interface_register(_a11y_bus, path, &event_iface_desc); - eo_do(obj, eo_key_data_set("event_interface", infc, NULL)); - - eo_do(obj, eo_event_callback_array_add(_events_cb(), infc)); + event_infc = eldbus_service_interface_register(_a11y_bus, path, &event_iface_desc); + eo_do(obj, eo_key_data_set("event_interface", event_infc, NULL)); + eo_do(obj, eo_event_callback_array_add(_events_cb(), event_infc)); if (eo_isa(obj, ELM_INTERFACE_ATSPI_COMPONENT_CLASS)) - { - infc = eldbus_service_interface_register(_a11y_bus, path, &component_iface_desc); - eo_do(obj, eo_key_data_set("component_interface", infc, NULL)); - } - + eldbus_service_interface_register(_a11y_bus, path, &component_iface_desc); if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_CLASS)) { infc = eldbus_service_interface_register(_a11y_bus, path, &window_iface_desc); eo_do(obj, eo_key_data_set("window_interface", infc, NULL)); - eo_do(obj, eo_event_callback_array_add(_window_cb(), infc)); } if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_CLASS)) @@ -2330,40 +3176,43 @@ static void _object_register(Eo *obj, char *path) eldbus_service_interface_register(_a11y_bus, path, &image_iface_desc); if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_CLASS)) { - infc = eldbus_service_interface_register(_a11y_bus, path, &selection_iface_desc); - eo_do(obj, eo_key_data_set("selection_interface", infc, NULL)); - eo_do(obj, eo_event_callback_array_add(_selection_cb(), infc)); + eldbus_service_interface_register(_a11y_bus, path, &selection_iface_desc); + eo_do(obj, eo_event_callback_array_add(_selection_cb(), event_infc)); } - + if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_CLASS)) + { + eldbus_service_interface_register(_a11y_bus, path, &text_iface_desc); + eo_do(obj, eo_event_callback_array_add(_text_cb(), event_infc)); + } + if (eo_isa(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_CLASS)) + eldbus_service_interface_register(_a11y_bus, path, &editable_text_iface_desc); } } static void _object_unregister(void *obj) { - Eldbus_Service_Interface *infc = NULL; + Eldbus_Service_Interface *infc, *event_infc = NULL; - eo_do(obj, infc = eo_key_data_get("event_interface")); - if (_a11y_bus && infc) + eo_do(obj, event_infc = eo_key_data_get("event_interface")); + if (_a11y_bus && event_infc) { - eldbus_service_object_unregister(infc); + eldbus_service_object_unregister(event_infc); eo_do(obj, eo_key_data_set("event_interface", NULL, NULL)); } eo_do(obj, eo_event_callback_del(EO_EV_DEL, _on_cache_item_del, NULL)); if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_CLASS)) - eo_do(obj, eo_event_callback_array_del(_events_cb(), infc)); - + eo_do(obj, eo_event_callback_array_del(_events_cb(), event_infc)); if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_CLASS)) { eo_do(obj, infc = eo_key_data_get("window_interface")); eo_do(obj, eo_event_callback_array_del(_window_cb(), infc)); } if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_CLASS)) - { - eo_do(obj, infc = eo_key_data_get("selection_interface")); - eo_do(obj, eo_event_callback_array_del(_selection_cb(), infc)); - } + eo_do(obj, eo_event_callback_array_del(_selection_cb(), event_infc)); + if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_CLASS)) + eo_do(obj, eo_event_callback_array_del(_text_cb(), event_infc)); } void diff --git a/legacy/elementary/src/lib/elm_entry.c b/legacy/elementary/src/lib/elm_entry.c index 8390b3573a..a4bc1acd9b 100644 --- a/legacy/elementary/src/lib/elm_entry.c +++ b/legacy/elementary/src/lib/elm_entry.c @@ -9,6 +9,16 @@ #define MY_CLASS ELM_ENTRY_CLASS +#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED +#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED +#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED + +#include "elm_interface_atspi_accessible.h" +#include "elm_interface_atspi_accessible.eo.h" +#include "elm_interface_atspi_text.h" +#include "elm_interface_atspi_text.eo.h" +#include "elm_interface_atspi_editable_text.eo.h" + #define MY_CLASS_NAME "Elm_Entry" #define MY_CLASS_NAME_LEGACY "elm_entry" @@ -1888,6 +1898,24 @@ _entry_changed_user_signal_cb(void *data, { evas_object_smart_callback_call(data, SIG_CHANGED_USER, NULL); } + if (_elm_config->atspi_mode) + { + Elm_Atspi_Text_Change_Info atspi_info; + if (edje_info && edje_info->insert) + { + atspi_info.content = edje_info->change.insert.content; + atspi_info.pos = edje_info->change.insert.pos; + atspi_info.len = edje_info->change.insert.plain_length; + eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, &atspi_info)); + } + else if (edje_info && !edje_info->insert) + { + atspi_info.content = edje_info->change.del.content; + atspi_info.pos = MIN(edje_info->change.del.start, edje_info->change.del.end); + atspi_info.len = abs(edje_info->change.del.end - edje_info->change.del.start); + eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, &atspi_info)); + } + } } static void @@ -1970,6 +1998,8 @@ _entry_selection_changed_signal_cb(void *data, evas_object_smart_callback_call(data, SIG_SELECTION_CHANGED, NULL); _selection_store(ELM_SEL_TYPE_PRIMARY, data); _update_selection_handler(data); + if (_elm_config->atspi_mode) + eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, NULL)); } static void @@ -2073,6 +2103,8 @@ _entry_cursor_changed_signal_cb(void *data, if (elm_widget_focus_get(data)) edje_object_signal_emit(sd->entry_edje, "elm,action,show,cursor", "elm"); _cursor_geometry_recalc(data); + if (_elm_config->atspi_mode) + eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL)); } static void @@ -2082,6 +2114,8 @@ _entry_cursor_changed_manual_signal_cb(void *data, const char *source EINA_UNUSED) { evas_object_smart_callback_call(data, SIG_CURSOR_CHANGED_MANUAL, NULL); + if (_elm_config->atspi_mode) + eo_do(data, eo_event_callback_call(ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, NULL)); } static void @@ -3625,7 +3659,8 @@ _elm_entry_eo_base_constructor(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED) eo_do_super(obj, MY_CLASS, eo_constructor()); eo_do(obj, evas_obj_type_set(MY_CLASS_NAME_LEGACY), - evas_obj_smart_callbacks_descriptions_set(_smart_callbacks)); + evas_obj_smart_callbacks_descriptions_set(_smart_callbacks), + elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_TEXT)); } EOLIAN static void @@ -4951,5 +4986,545 @@ _elm_entry_class_constructor(Eo_Class *klass) evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass); } +// ATSPI Accessibility + +EOLIAN static Eina_Unicode +_elm_entry_elm_interface_atspi_text_character_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset) +{ + char *txt; + int index = 0; + Eina_Unicode ret = 0; + if (offset < 0) return ret; + + txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj)); + if (!txt) return ret; + + ret = eina_unicode_utf8_next_get(txt, &index); + while (offset--) ret = eina_unicode_utf8_next_get(txt, &index); + + free(txt); + + return ret; +} + +EOLIAN static int +_elm_entry_elm_interface_atspi_text_character_count_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED) +{ + char *txt; + int ret = -1; + + txt = _elm_util_mkup_to_text(elm_entry_entry_get(obj)); + if (!txt) return ret; + + ret = eina_unicode_utf8_get_len(txt); + free(txt); + + return ret; +} + +EOLIAN static char* +_elm_entry_elm_interface_atspi_text_string_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Elm_Atspi_Text_Granularity granularity, int *start_offset, int *end_offset) +{ + Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL; + Evas_Object *tblk; + char *ret = NULL; + + tblk = elm_entry_textblock_get(obj); + if (!tblk) goto fail; + + cur = evas_object_textblock_cursor_new(tblk); + cur2 = evas_object_textblock_cursor_new(tblk); + if (!cur2 || !cur2) goto fail; + + evas_textblock_cursor_pos_set(cur, *start_offset); + if (evas_textblock_cursor_pos_get(cur) != *start_offset) goto fail; + + switch (granularity) + { + case ELM_ATSPI_TEXT_GRANULARITY_CHAR: + break; + case ELM_ATSPI_TEXT_GRANULARITY_WORD: + evas_textblock_cursor_word_start(cur); + break; + case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE: + // TODO - add sentence support in textblock first + break; + case ELM_ATSPI_TEXT_GRANULARITY_LINE: + evas_textblock_cursor_line_char_first(cur); + break; + case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH: + evas_textblock_cursor_paragraph_char_first(cur); + break; + } + + *start_offset = evas_textblock_cursor_pos_get(cur); + evas_textblock_cursor_copy(cur, cur2); + + switch (granularity) + { + case ELM_ATSPI_TEXT_GRANULARITY_CHAR: + evas_textblock_cursor_char_next(cur2); + break; + case ELM_ATSPI_TEXT_GRANULARITY_WORD: + evas_textblock_cursor_word_end(cur2); + // since word_end sets cursor position ON (before) last + // char of word, we need to manually advance cursor to get + // proper string from function range_text_get + evas_textblock_cursor_char_next(cur2); + break; + case ELM_ATSPI_TEXT_GRANULARITY_SENTENCE: + // TODO - add sentence support in textblock first + break; + case ELM_ATSPI_TEXT_GRANULARITY_LINE: + evas_textblock_cursor_line_char_last(cur2); + break; + case ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH: + evas_textblock_cursor_paragraph_char_last(cur2); + break; + } + + if (end_offset) *end_offset = evas_textblock_cursor_pos_get(cur2); + + ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN); + + evas_textblock_cursor_free(cur); + evas_textblock_cursor_free(cur2); + + return ret; + +fail: + if (start_offset) *start_offset = -1; + if (end_offset) *end_offset = -1; + if (cur) evas_textblock_cursor_free(cur); + if (cur2) evas_textblock_cursor_free(cur2); + return NULL; +} + +EOLIAN static char* +_elm_entry_elm_interface_atspi_text_text_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset) +{ + Evas_Textblock_Cursor *cur = NULL, *cur2 = NULL; + Evas_Object *tblk; + char *ret = NULL; + + tblk = elm_entry_textblock_get(obj); + if (!tblk) goto fail; + + cur = evas_object_textblock_cursor_new(tblk); + cur2 = evas_object_textblock_cursor_new(tblk); + if (!cur2 || !cur2) goto fail; + + evas_textblock_cursor_pos_set(cur, start_offset); + if (evas_textblock_cursor_pos_get(cur) != start_offset) goto fail; + + evas_textblock_cursor_pos_set(cur2, end_offset); + if (evas_textblock_cursor_pos_get(cur2) != end_offset) goto fail; + + ret = evas_textblock_cursor_range_text_get(cur, cur2, EVAS_TEXTBLOCK_TEXT_PLAIN); + + evas_textblock_cursor_free(cur); + evas_textblock_cursor_free(cur2); + + return ret; + +fail: + if (cur) evas_textblock_cursor_free(cur); + if (cur2) evas_textblock_cursor_free(cur2); + return NULL; +} + +EOLIAN static int +_elm_entry_elm_interface_atspi_text_caret_offset_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED) +{ + return elm_entry_cursor_pos_get(obj); +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_caret_offset_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset) +{ + elm_entry_cursor_pos_set(obj, offset); + return EINA_TRUE; +} + +EOLIAN static int +_elm_entry_elm_interface_atspi_text_selections_count_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED) +{ + return elm_entry_selection_get(obj) ? 1 : 0; +} + +EOLIAN static void +_elm_entry_elm_interface_atspi_text_selection_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int *start_offset, int *end_offset) +{ + *start_offset = *end_offset = -1; + if (!elm_entry_selection_get(obj)) return; + if (selection_number != 0) return; + + *start_offset = edje_object_part_text_cursor_pos_get(_pd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_BEGIN); + *end_offset = edje_object_part_text_cursor_pos_get(_pd->entry_edje, "elm.text", EDJE_CURSOR_SELECTION_END); +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_selection_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int selection_number, int start_offset, int end_offset) +{ + if (selection_number != 0) return EINA_FALSE; + + elm_entry_select_region_set(obj, start_offset, end_offset); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_selection_remove(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int selection_number) +{ + if (selection_number != 0) return EINA_FALSE; + elm_entry_select_none(obj); + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_selection_add(Eo *obj, Elm_Entry_Data *pd EINA_UNUSED, int start_offset, int end_offset) +{ + elm_entry_select_region_set(obj, start_offset, end_offset); + + return EINA_TRUE; +} + +EOLIAN static Eina_List* +_elm_entry_elm_interface_atspi_text_bounded_ranges_get(Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods EINA_UNUSED, Eina_Rectangle rect EINA_UNUSED, Elm_Atspi_Text_Clip_Type xclip EINA_UNUSED, Elm_Atspi_Text_Clip_Type yclip EINA_UNUSED) +{ + return NULL; +} + +EOLIAN static int +_elm_entry_elm_interface_atspi_text_offset_at_point_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int x, int y) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur; + int ret; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return -1; + + cur = evas_object_textblock_cursor_new(txtblk); + if (!cur) return -1; + + if (screen_coods) + { + int ee_x, ee_y; + Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); + ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL); + x -= ee_x; + y -= ee_y; + } + + if (!evas_textblock_cursor_char_coord_set(cur, x, y)) + { + evas_textblock_cursor_free(cur); + return -1; + } + + ret = evas_textblock_cursor_pos_get(cur); + evas_textblock_cursor_free(cur); + + return ret; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_character_extents_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int offset, Eina_Bool screen_coods, Eina_Rectangle *rect) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur; + int ret; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return EINA_FALSE; + + cur = evas_object_textblock_cursor_new(txtblk); + if (!cur) return EINA_FALSE; + + evas_textblock_cursor_pos_set(cur, offset); + + ret = evas_textblock_cursor_char_geometry_get(cur, &rect->x, &rect->y, &rect->w, &rect->h); + evas_textblock_cursor_free(cur); + + if (ret == -1) return EINA_FALSE; + + if (screen_coods) + { + int ee_x, ee_y; + Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); + ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL); + rect->x += ee_x; + rect->y += ee_y; + } + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_range_extents_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, Eina_Bool screen_coods, int start_offset, int end_offset, Eina_Rectangle *rect) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur1, *cur2; + int ret; + int x1, x2, y1, y2; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return EINA_FALSE; + + cur1 = evas_object_textblock_cursor_new(txtblk); + if (!cur1) return EINA_FALSE; + + cur2 = evas_object_textblock_cursor_new(txtblk); + if (!cur2) + { + evas_textblock_cursor_free(cur1); + return EINA_FALSE; + } + + evas_textblock_cursor_pos_set(cur1, start_offset); + evas_textblock_cursor_pos_set(cur2, end_offset); + + ret = evas_textblock_cursor_char_geometry_get(cur1, &x1, &y1, NULL, NULL); + ret += evas_textblock_cursor_char_geometry_get(cur2, &x2, &y2, NULL, NULL); + + evas_textblock_cursor_free(cur1); + evas_textblock_cursor_free(cur2); + + if (ret != 0) return EINA_FALSE; + + rect->x = x1 < x2 ? x1 : x2; + rect->y = y1 < y2 ? y1 : y2; + rect->w = abs(x1 - x2); + rect->h = abs(y1 - y2); + + if (screen_coods) + { + int ee_x, ee_y; + Ecore_Evas *ee= ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); + ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL); + rect->x += ee_x; + rect->y += ee_y; + } + + return EINA_TRUE; +} + +static Elm_Atspi_Text_Attribute* +_textblock_node_format_to_atspi_text_attr(const Evas_Object_Textblock_Node_Format *format) +{ + Elm_Atspi_Text_Attribute *ret = NULL; + const char *txt; + + txt = evas_textblock_node_format_text_get(format); + if (!txt) return NULL; + + if (txt[0] == '-') return NULL; // skip closing format + + if (!strncmp(txt, "+ ", 2)) + { + const char *tmp = &txt[2]; + + while (*tmp != '\0' && *tmp != '=') tmp++; + if (*tmp++ != '=') return NULL; + + ret = calloc(1, sizeof(Elm_Atspi_Text_Attribute)); + if (!ret) return NULL; + + ret->value = eina_stringshare_add(tmp); + int size = &txt[2] - tmp + 1; + ret->name = eina_stringshare_add_length(&txt[2], size > 0 ? size : -size); + } + + return ret; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_text_attribute_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur1, *cur2; + Eina_List *formats, *l; + Evas_Object_Textblock_Node_Format *format; + Elm_Atspi_Text_Attribute *attr; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return EINA_FALSE; + + cur1 = evas_object_textblock_cursor_new(txtblk); + if (!cur1) return EINA_FALSE; + + cur2 = evas_object_textblock_cursor_new(txtblk); + if (!cur2) + { + evas_textblock_cursor_free(cur1); + return EINA_FALSE; + } + + evas_textblock_cursor_pos_set(cur1, *start_offset); + evas_textblock_cursor_pos_set(cur2, *end_offset); + + formats = evas_textblock_cursor_range_formats_get(cur1, cur2); + + evas_textblock_cursor_free(cur1); + evas_textblock_cursor_free(cur2); + + if (!formats) return EINA_FALSE; + + EINA_LIST_FOREACH(formats, l , format) + { + attr = _textblock_node_format_to_atspi_text_attr(format); + if (!attr) continue; + if (!strcmp(attr->name, attr_name)) + { + *value = attr->value ? strdup(attr->value) : NULL; + elm_atspi_text_text_attribute_free(attr); + return EINA_TRUE; + } + elm_atspi_text_text_attribute_free(attr); + } + + return EINA_FALSE; +} + +EOLIAN static Eina_List* +_elm_entry_elm_interface_atspi_text_attributes_get(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int *start_offset, int *end_offset) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur1, *cur2; + Eina_List *formats, *ret = NULL, *l; + Evas_Object_Textblock_Node_Format *format; + Elm_Atspi_Text_Attribute *attr; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return NULL; + + cur1 = evas_object_textblock_cursor_new(txtblk); + if (!cur1) return NULL; + + cur2 = evas_object_textblock_cursor_new(txtblk); + if (!cur2) + { + evas_textblock_cursor_free(cur1); + return NULL; + } + + evas_textblock_cursor_pos_set(cur1, *start_offset); + evas_textblock_cursor_pos_set(cur2, *end_offset); + + formats = evas_textblock_cursor_range_formats_get(cur1, cur2); + + evas_textblock_cursor_free(cur1); + evas_textblock_cursor_free(cur2); + + if (!formats) return EINA_FALSE; + + EINA_LIST_FOREACH(formats, l , format) + { + attr = _textblock_node_format_to_atspi_text_attr(format); + if (!attr) continue; + ret = eina_list_append(ret, attr); + } + + return ret; +} + +EOLIAN static Eina_List* +_elm_entry_elm_interface_atspi_text_default_attributes_get(Eo *obj EINA_UNUSED, Elm_Entry_Data *_pd EINA_UNUSED) +{ + Evas_Object *txtblk; + Eina_List *ret = NULL; + const Evas_Object_Textblock_Node_Format *format; + Elm_Atspi_Text_Attribute *attr; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return NULL; + + format = evas_textblock_node_format_first_get(txtblk); + if (!format) return EINA_FALSE; + + do + { + attr = _textblock_node_format_to_atspi_text_attr(format); + if (!attr) continue; + ret = eina_list_append(ret, attr); + } + while ((format = evas_textblock_node_format_next_get(format)) != NULL); + + return ret; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_content_set(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *content) +{ + elm_entry_entry_set(obj, content); + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_insert(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, const char *string, int position) +{ + elm_entry_cursor_pos_set(obj, position); + elm_entry_entry_insert(obj, string); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_copy(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end) +{ + elm_entry_select_region_set(obj, start, end); + elm_entry_selection_copy(obj); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_delete(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start_offset, int end_offset) +{ + Evas_Object *txtblk; + Evas_Textblock_Cursor *cur1, *cur2; + + txtblk = elm_entry_textblock_get(obj); + if (!txtblk) return EINA_FALSE; + + cur1 = evas_object_textblock_cursor_new(txtblk); + if (!cur1) return EINA_FALSE; + + cur2 = evas_object_textblock_cursor_new(txtblk); + if (!cur2) + { + evas_textblock_cursor_free(cur1); + return EINA_FALSE; + } + + evas_textblock_cursor_pos_set(cur1, start_offset); + evas_textblock_cursor_pos_set(cur2, end_offset); + + evas_textblock_cursor_range_delete(cur1, cur2); + + evas_textblock_cursor_free(cur1); + evas_textblock_cursor_free(cur2); + + elm_entry_calc_force(obj); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_paste(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int position) +{ + elm_entry_cursor_pos_set(obj, position); + elm_entry_selection_paste(obj); + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_elm_entry_elm_interface_atspi_editable_text_cut(Eo *obj, Elm_Entry_Data *_pd EINA_UNUSED, int start, int end) +{ + elm_entry_select_region_set(obj, start, end); + elm_entry_selection_cut(obj); + return EINA_TRUE; +} #include "elm_entry.eo.c" diff --git a/legacy/elementary/src/lib/elm_entry.eo b/legacy/elementary/src/lib/elm_entry.eo index c2f65a69b5..1779003056 100644 --- a/legacy/elementary/src/lib/elm_entry.eo +++ b/legacy/elementary/src/lib/elm_entry.eo @@ -1,4 +1,5 @@ -class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface) +class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface, + Elm_Interface_Atspi_Text, Elm_Interface_Atspi_Editable_Text) { eo_prefix: elm_obj_entry; properties { @@ -1185,6 +1186,30 @@ class Elm_Entry (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interface) Elm_Layout::content_aliases::get; Elm_Interface_Scrollable::policy::set; Elm_Interface_Scrollable::bounce_allow::set; + Elm_Interface_Atspi_Text::text::get; + Elm_Interface_Atspi_Text::string::get; + Elm_Interface_Atspi_Text::attribute::get; + Elm_Interface_Atspi_Text::attributes::get; + Elm_Interface_Atspi_Text::default_attributes::get; + Elm_Interface_Atspi_Text::caret_offset::get; + Elm_Interface_Atspi_Text::caret_offset::set; + Elm_Interface_Atspi_Text::character::get; + Elm_Interface_Atspi_Text::character_extents::get; + Elm_Interface_Atspi_Text::character_count::get; + Elm_Interface_Atspi_Text::offset_at_point::get; + Elm_Interface_Atspi_Text::bounded_ranges::get; + Elm_Interface_Atspi_Text::range_extents::get; + Elm_Interface_Atspi_Text::selection::get; + Elm_Interface_Atspi_Text::selections_count::get; + Elm_Interface_Atspi_Text::selection_add; + Elm_Interface_Atspi_Text::selection_remove; + Elm_Interface_Atspi_Text::selection::set; + Elm_Interface_Atspi_Editable_Text::content::set; + Elm_Interface_Atspi_Editable_Text::insert; + Elm_Interface_Atspi_Editable_Text::copy; + Elm_Interface_Atspi_Editable_Text::cut; + Elm_Interface_Atspi_Editable_Text::delete; + Elm_Interface_Atspi_Editable_Text::paste; } events { language,changed; diff --git a/legacy/elementary/src/lib/elm_interface_atspi_editable_text.c b/legacy/elementary/src/lib/elm_interface_atspi_editable_text.c new file mode 100644 index 0000000000..8a0a9c9a82 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_editable_text.c @@ -0,0 +1,12 @@ +#ifdef HAVE_CONFIG_H + #include "elementary_config.h" +#endif + +#include +#include "elm_widget.h" +#include "elm_priv.h" + +#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED + +#include "elm_interface_atspi_editable_text.eo.h" +#include "elm_interface_atspi_editable_text.eo.c" diff --git a/legacy/elementary/src/lib/elm_interface_atspi_editable_text.eo b/legacy/elementary/src/lib/elm_interface_atspi_editable_text.eo new file mode 100644 index 0000000000..7df655abb4 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_editable_text.eo @@ -0,0 +1,60 @@ +interface Elm_Interface_Atspi_Editable_Text () +{ + legacy_prefix: null; + eo_prefix: elm_interface_atspi_editable_text; + data: null; + properties { + protected content { + set { + return Eina_Bool; + } + values { + const char *string; + } + } + } + methods { + protected insert { + params { + @in const char *string; + @in int position; + } + return Eina_Bool; + } + protected copy { + params { + @in int start; + @in int end; + } + return Eina_Bool; + } + protected cut { + params { + @in int start; + @in int end; + } + return Eina_Bool; + } + protected delete { + params { + @in int start; + @in int end; + } + return Eina_Bool; + } + protected paste { + params { + @in int position; + } + return Eina_Bool; + } + } + implements { + virtual::content::set; + virtual::insert; + virtual::copy; + virtual::cut; + virtual::delete; + virtual::paste; + } +} diff --git a/legacy/elementary/src/lib/elm_interface_atspi_text.c b/legacy/elementary/src/lib/elm_interface_atspi_text.c new file mode 100644 index 0000000000..afab4d5919 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_text.c @@ -0,0 +1,23 @@ +#ifdef HAVE_CONFIG_H + #include "elementary_config.h" +#endif + +#include +#include "elm_widget.h" +#include "elm_priv.h" + +#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED + +#include "elm_interface_atspi_text.h" +#include "elm_interface_atspi_text.eo.h" + +EAPI void +elm_atspi_text_text_attribute_free(Elm_Atspi_Text_Attribute *attr) +{ + if (!attr) return; + if (attr->name) eina_stringshare_del(attr->name); + if (attr->value) eina_stringshare_del(attr->value); + free(attr); +} + +#include "elm_interface_atspi_text.eo.c" diff --git a/legacy/elementary/src/lib/elm_interface_atspi_text.eo b/legacy/elementary/src/lib/elm_interface_atspi_text.eo new file mode 100644 index 0000000000..1181cacecb --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_text.eo @@ -0,0 +1,223 @@ +interface Elm_Interface_Atspi_Text () +{ + legacy_prefix: null; + eo_prefix: elm_interface_atspi_text; + data: null; + properties { + protected character { + get { + /*@ Gets single character present in accessible widget's text + at given offset. */ + } + keys { + int offset; /*@ Position in text. */ + } + values { + Eina_Unicode character; /*@ Character at offset. 0 when out-of + bounds offset has been given. + Codepoints between DC80 and DCFF indicates + that string includes invalid UTF8 chars. */ + } + } + protected string { + get { + /*@ Gets string, start and end offset in text according to + given initial offset and granulatity. */ + } + keys { + @in Elm_Atspi_Text_Granularity granularity; + @inout int *start_offset @nonull; /*@ Offset indicating start of string + according to given granularity. + -1 in case of error. */ + @out int *end_offset; /*@ Offset indicating end of string according + to given granularity. -1 in case of error. */ + } + values { + char *string; /*@ Newly allocated UTF-8 encoded string. + Must be free by a user. */ + } + } + protected text { + get { + /*@ Gets text of accessible widget. */ + } + keys { + int start_offset; /*@ Position in text. */ + int end_offset; /*@ End offset of text. */ + } + values { + char *text; /*@ UTF-8 encoded text. */ + } + } + protected caret_offset { + get { + /*@ Gets offset position of caret (cursor) */ + } + set { + return Eina_Bool; /*@ EINA_TRUE if caret was successfully moved, + EINA_FASLE otherwise. */ + } + values { + int offset; + } + } + protected attribute { + get { + /*@ Indicate if a text attribute with a given name is set */ + return Eina_Bool; + } + keys { + @in const char *name @nonull; /*@ text attribute name */ + @inout int *start_offset @nonull; /*@ Position in text from which + given attribute is set. */ + @out int *end_offset; /*@ Position in text to which given attribute + is set. */ + } + values { + char *value; /* Value of text attribute. Should be free() */ + } + } + protected attributes { + get { + /* Gets list of all text attributes. */ + } + keys { + @inout int *start_offset @nonull; + @out int *end_offset; + } + values { + @own Eina_List *attributes; + } + } + protected default_attributes { + get { + } + values { + @own Eina_List *attributes; + } + } + protected character_extents { + get { + return Eina_Bool; + } + keys { + int offset; + Eina_Bool screen_coords; + } + values { + Eina_Rectangle rect; + } + } + protected character_count { + get { + } + values { + int count; + } + } + protected offset_at_point { + get { + } + keys { + Eina_Bool screen_coords; + int x; + int y; + } + values { + int offset; + } + } + protected bounded_ranges { + get { + } + keys { + Eina_Bool screen_coords; + Eina_Rectangle rect; + Elm_Atspi_Text_Clip_Type xclip; + Elm_Atspi_Text_Clip_Type yclip; + } + values { + Eina_List *ranges; + } + } + protected range_extents { + get { + return Eina_Bool; + } + keys { + Eina_Bool screen_coords; /*@ If true x and y values will be relative + to screen origin, otherwise relative to + canvas */ + int start_offset; + int end_offset; + } + values { + Eina_Rectangle rect; + } + } + protected selections_count { + get { + } + values { + int count; + } + } + protected selection { + get { + } + set { + return Eina_Bool; + } + keys { + int selection_number; + } + values { + int start_offset; + int end_offset; + } + } + } + methods { + protected selection_add { + params { + @in int start_offset; + @in int end_offset; + } + return Eina_Bool; + } + protected selection_remove { + params { + @in int selection_number; + } + return Eina_Bool; + } + } + events { + access,text,bounds,changed; + access,text,attributes,changed; + access,text,caret,moved; + access,text,inserted; + access,text,removed; + access,text,selection,changed; + } + implements { + virtual::text::get; + virtual::string::get; + virtual::attribute::get; + virtual::attributes::get; + virtual::default_attributes::get; + virtual::caret_offset::get; + virtual::caret_offset::set; + virtual::character::get; + virtual::character_extents::get; + virtual::character_count::get; + virtual::offset_at_point::get; + virtual::bounded_ranges::get; + virtual::range_extents::get; + virtual::selection::get; + virtual::selections_count::get; + virtual::selection_add; + virtual::selection_remove; + virtual::selection::set; + } +} diff --git a/legacy/elementary/src/lib/elm_interface_atspi_text.h b/legacy/elementary/src/lib/elm_interface_atspi_text.h new file mode 100644 index 0000000000..7fef98f268 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_text.h @@ -0,0 +1,53 @@ + +typedef enum _Elm_Atspi_Text_Granulatity Elm_Atspi_Text_Granularity; + +enum _Elm_Atspi_Text_Granulatity +{ + ELM_ATSPI_TEXT_GRANULARITY_CHAR, + ELM_ATSPI_TEXT_GRANULARITY_WORD, + ELM_ATSPI_TEXT_GRANULARITY_SENTENCE, + ELM_ATSPI_TEXT_GRANULARITY_LINE, + ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH +}; + +typedef struct _Elm_Atspi_Text_Attribute Elm_Atspi_Text_Attribute; + +struct _Elm_Atspi_Text_Attribute +{ + const char *name; + const char *value; +}; + +typedef struct _Elm_Atspi_Text_Range Elm_Atspi_Text_Range; + +struct _Elm_Atspi_Text_Range +{ + int start_offset; + int end_offset; + char *content; +}; + +typedef enum _Elm_Atspi_Text_Clip_Type Elm_Atspi_Text_Clip_Type; + +enum _Elm_Atspi_Text_Clip_Type +{ + ELM_ATSPI_TEXT_CLIP_NONE, + ELM_ATSPI_TEXT_CLIP_MIN, + ELM_ATSPI_TEXT_CLIP_MAX, + ELM_ATSPI_TEXT_CLIP_BOTH +}; + +/** + * @brief Free Elm_Atspi_Text_Attribute structure + */ +void elm_atspi_text_text_attribute_free(Elm_Atspi_Text_Attribute *attr); + +typedef struct _Elm_Atspi_Text_Change_Info Elm_Atspi_Text_Change_Info; + +struct _Elm_Atspi_Text_Change_Info +{ + const char *content; + Eina_Bool inserted; + size_t pos; + size_t len; +}; diff --git a/legacy/elementary/src/tests/elm_test_entry.c b/legacy/elementary/src/tests/elm_test_entry.c index 70643aed21..3fdf31bf98 100644 --- a/legacy/elementary/src/tests/elm_test_entry.c +++ b/legacy/elementary/src/tests/elm_test_entry.c @@ -5,6 +5,10 @@ #include #include "elm_suite.h" +#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED +#include "elm_interface_atspi_text.h" +#include "elm_interface_atspi_text.eo.h" + START_TEST (elm_entry_del) { Evas_Object *win, *entry; @@ -19,7 +23,342 @@ START_TEST (elm_entry_del) } END_TEST +START_TEST (elm_entry_atspi_text_char_get) +{ + Evas_Object *win, *entry; + Eina_Unicode *expected; + Eina_Unicode val; + + const char *txt = "ĄA11Y Ł TEST"; + const char *mtxt = "ĄA11Y Ł</> TEST"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, mtxt); + + expected = eina_unicode_utf8_to_unicode(txt, NULL); + + eo_do(entry, val = elm_interface_atspi_text_character_get(-1)); + ck_assert(val == 0); + + eo_do(entry, val = elm_interface_atspi_text_character_get(0)); + ck_assert(val == expected[0]); + + eo_do(entry, val = elm_interface_atspi_text_character_get(1)); + ck_assert(val == expected[1]); + + eo_do(entry, val = elm_interface_atspi_text_character_get(2)); + ck_assert(val == expected[2]); + + eo_do(entry, val = elm_interface_atspi_text_character_get(6)); + ck_assert(val == expected[6]); + + eo_do(entry, val = elm_interface_atspi_text_character_get(26)); + ck_assert(val == 0); + + free(expected); + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_char_count) +{ + Evas_Object *win, *entry; + int val; + + const char *mtxt = "<b>AĄ11Y</b> <title>Ł</> TEST"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, mtxt); + + eo_do(entry, val = elm_interface_atspi_text_character_count_get()); + ck_assert(val == 12); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_string_get_char) +{ + Evas_Object *win, *entry; + char *val; + int start, end; + + const char *txt = "Lorem ipśum dolor sit amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + start = 1; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end)); + ck_assert_str_eq(val, "o"); + ck_assert(start == 1); + ck_assert(end == 2); + if (val) free(val); + + start = 8; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end)); + ck_assert_str_eq(val, "ś"); + ck_assert(start == 8); + ck_assert(end == 9); + if (val) free(val); + + start = 11; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end)); + ck_assert_str_eq(val, " "); + ck_assert(start == 11); + ck_assert(end == 12); + if (val) free(val); + + start = 111; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_CHAR, &start, &end)); + ck_assert(start == -1); + ck_assert(end == -1); + ck_assert(val == NULL); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_string_get_word) +{ + Evas_Object *win, *entry; + char *val; + int start, end; + + const char *txt = "Lorem ipśum dolor sit amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + start = 1; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end)); + ck_assert_str_eq(val, "Lorem"); + ck_assert(start == 0); + ck_assert(end == 5); + if (val) free(val); + + start = 6; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end)); + ck_assert_str_eq(val, "ipśum"); + ck_assert(start == 6); + ck_assert(end == 11); + if (val) free(val); + + start = 19; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end)); + ck_assert_str_eq(val, "dolor"); + ck_assert(start == 14); + ck_assert(end == 19); + if (val) free(val); + + start = 111; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end)); + ck_assert(start == -1); + ck_assert(end == -1); + ck_assert(val == NULL); + if (val) free(val); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_string_get_paragraph) +{ + Evas_Object *win, *entry; + char *val; + int start, end; + + const char *txt = "Lorem ipśum<br> dolor sit\n amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + start = 1; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end)); + ck_assert_str_eq(val, "Lorem ipśum"); + ck_assert(start == 0); + ck_assert(end == 11); + if (val) free(val); + + start = 22; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end)); + ck_assert_str_eq(val, " dolor sit"); + ck_assert(start == 11); + ck_assert(end == 22); + if (val) free(val); + + start = 27; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_PARAGRAPH, &start, &end)); + ck_assert_str_eq(val, " amęt"); + ck_assert(start == 23); + ck_assert(end == 27); + if (val) free(val); + + start = 111; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_WORD, &start, &end)); + ck_assert(start == -1); + ck_assert(end == -1); + ck_assert(val == NULL); + if (val) free(val); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_string_get_line) +{ + Evas_Object *win, *entry; + char *val; + int start, end; + + const char *txt = "Lorem ipśum<br> dolor sit\n amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + start = 1; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_LINE, &start, &end)); + ck_assert_str_eq(val, "Lorem ipśum"); + ck_assert(start == 0); + ck_assert(end == 11); + if (val) free(val); + + start = 13; + eo_do(entry, val = elm_interface_atspi_text_string_get(ELM_ATSPI_TEXT_GRANULARITY_LINE, &start, &end)); + ck_assert_str_eq(val, " dolor sit"); + ck_assert(start == 11); + ck_assert(end == 23); + if (val) free(val); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_text_get) +{ + Evas_Object *win, *entry; + char *val; + const char *txt = "Lorem ipśum<br> dolor sit\n amęt"; + const char *txtnom = "Lorem ipśum dolor sit\n amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + eo_do(entry, val = elm_interface_atspi_text_text_get(0, sizeof(txtnom)/sizeof(txtnom[0]))); + ck_assert_str_eq(val, txtnom); + + if (val) free(val); + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_selections) +{ + Evas_Object *win, *entry; + int val, start, end; + const char *str; + Eina_Bool ret; + const char *txt = "Lorem ipśum<br> dolor sit\n amęt"; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + eo_do(entry, val = elm_interface_atspi_text_selections_count_get()); + ck_assert(val == 0); + + elm_entry_select_region_set(entry, 2, 4); + eo_do(entry, val = elm_interface_atspi_text_selections_count_get()); + ck_assert(val == 1); + eo_do(entry, elm_interface_atspi_text_selection_get(0, &start, &end)); + ck_assert(start == 2); + ck_assert(end == 4); + + elm_entry_select_region_set(entry, 6, 10); + eo_do(entry, val = elm_interface_atspi_text_selections_count_get()); + ck_assert(val == 1); + eo_do(entry, elm_interface_atspi_text_selection_get(0, &start, &end)); + ck_assert(start == 6); + ck_assert(end == 10); + + elm_entry_select_none(entry); + eo_do(entry, ret = elm_interface_atspi_text_selection_add(2, 5)); + ck_assert(ret == EINA_TRUE); + str = elm_entry_selection_get(entry); + ck_assert_str_eq(str, "rem"); + + eo_do(entry, ret = elm_interface_atspi_text_selection_remove(0)); + ck_assert(ret == EINA_TRUE); + str = elm_entry_selection_get(entry); + ck_assert(str == NULL); + + elm_shutdown(); +} +END_TEST + +START_TEST (elm_entry_atspi_text_attributes) +{ + Evas_Object *win, *entry; + Eina_List *formats; + const char txt[] = "<font_weight=Bold>Lorem ipśum<br></> dolor sit\n amęt"; + int start = 0, end = sizeof(txt); + Elm_Atspi_Text_Attribute *attr; + + elm_init(1, NULL); + win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); + + entry = elm_entry_add(win); + elm_object_text_set(entry, txt); + + eo_do(entry, formats = elm_interface_atspi_text_attributes_get(&start, &end)); + EINA_LIST_FREE(formats, attr) + { + elm_atspi_text_text_attribute_free(attr); + } + + eo_do(entry, formats = elm_interface_atspi_text_default_attributes_get()); + EINA_LIST_FREE(formats, attr) + { + elm_atspi_text_text_attribute_free(attr); + } + + elm_shutdown(); +} +END_TEST + void elm_test_entry(TCase *tc) { tcase_add_test(tc, elm_entry_del); + tcase_add_test(tc, elm_entry_atspi_text_char_get); + tcase_add_test(tc, elm_entry_atspi_text_char_count); + tcase_add_test(tc, elm_entry_atspi_text_string_get_char); + tcase_add_test(tc, elm_entry_atspi_text_string_get_word); + tcase_add_test(tc, elm_entry_atspi_text_string_get_paragraph); + tcase_add_test(tc, elm_entry_atspi_text_string_get_line); + tcase_add_test(tc, elm_entry_atspi_text_text_get); + tcase_add_test(tc, elm_entry_atspi_text_selections); + tcase_add_test(tc, elm_entry_atspi_text_attributes); }