package dasherJava.core.output; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.PointerType; import com.sun.jna.Structure; import com.sun.jna.Structure.FieldOrder; import com.sun.jna.Union; @SuppressWarnings({"unused", "UnusedReturnValue"}) //all fields of structures must be declared for type mapping, //even unused ones public interface ATSPILibrary extends Library { //load libatspi.so on Linux LazyLibraryLoader INSTANCE = new LazyLibraryLoader<>("atspi", ATSPILibrary.class); //AT-SPI 2.0 documentation: https://docs.gtk.org/atspi2/index.html NativeLong NATIVE_LONG_ZERO = new NativeLong(0L); //constant zero, for easier access //X11 keysym values from /usr/include/X11/keysym.h NativeLong KEYSYM_BACKSPACE = new NativeLong(0xFF08L); //AtspiKeySynthType enum values int ATSPI_KEY_SYM = 3; int ATSPI_KEY_STRING = 4; //AtspiTextGranularity enum values int ATSPI_TEXT_GRANULARITY_CHAR = 0; int ATSPI_TEXT_GRANULARITY_WORD = 1; int ATSPI_TEXT_GRANULARITY_SENTENCE = 2; int ATSPI_TEXT_GRANULARITY_LINE = 3; int ATSPI_TEXT_GRANULARITY_PARAGRAPH = 4; //AtspiTextBoundaryType enum values int ATSPI_TEXT_BOUNDARY_CHAR = 0; int ATSPI_TEXT_BOUNDARY_WORD_START = 1; int ATSPI_TEXT_BOUNDARY_WORD_END = 2; int ATSPI_TEXT_BOUNDARY_SENTENCE_START = 3; int ATSPI_TEXT_BOUNDARY_SENTENCE_END = 4; int ATSPI_TEXT_BOUNDARY_LINE_START = 5; int ATSPI_TEXT_BOUNDARY_LINE_END = 6; static ATSPILibrary get() throws UnsatisfiedLinkError { //shorthand method to make code more readable return INSTANCE.getLibrary(); } static String getString(Pointer p) { //small utility method return p==null ? "null" : p.getString(0, "UTF-8"); } //gboolean atspi_generate_keyboard_event(glong keyval, const gchar* keystring, AtspiKeySynthType synth_type, // GError** error) int atspi_generate_keyboard_event(NativeLong keyval, String keystring, int synth_type, Pointer error); //int atspi_init(void); int atspi_init(); //int atspi_exit(void); int atspi_exit(); //void atspi_event_main(void); void atspi_event_main(); //void atspi_event_quit(void); void atspi_event_quit(); //AtspiEventListener* atspi_event_listener_new(AtspiEventListenerCB callback, gpointer user_data, // GDestroyNotify callback_destroyed) ATSPIEventListener atspi_event_listener_new(ATSPIEventListenerCallback callback, Pointer user_data, GDestroyNotifyCallback callback_destroyed); //gboolean atspi_event_listener_register(AtspiEventListener* listener, const gchar* event_type, GError** error) int atspi_event_listener_register(ATSPIEventListener listener, String event_type, Pointer error); //gboolean atspi_event_listener_deregister(AtspiEventListener* listener, const gchar* event_type, GError** error) int atspi_event_listener_deregister(ATSPIEventListener listener, String event_type, Pointer error); //AtspiText* atspi_accessible_get_text_iface(AtspiAccessible* obj) ATSPIText atspi_accessible_get_text_iface(ATSPIAccessible obj); //AtspiEditableText* atspi_accessible_get_editable_text_iface(AtspiAccessible* obj) ATSPIEditableText atspi_accessible_get_editable_text_iface(ATSPIAccessible obj); //AtspiAction* atspi_accessible_get_action_iface(AtspiAccessible* obj) ATSPIAction atspi_accessible_get_action_iface(ATSPIAccessible obj); //AtspiTextRange* atspi_text_get_text_before_offset(AtspiText* obj, gint offset, AtspiTextBoundaryType type, // GError** error) ATSPITextRange atspi_text_get_text_before_offset(ATSPIText obj, int offset, int type, Pointer error); //AtspiTextRange* atspi_text_get_text_after_offset(AtspiText* obj, gint offset, AtspiTextBoundaryType type, // GError** error) ATSPITextRange atspi_text_get_text_after_offset(ATSPIText obj, int offset, int type, Pointer error); //AtspiTextRange* atspi_text_get_string_at_offset(AtspiText* obj, gint offset, AtspiTextGranularity granularity, // GError** error) ATSPITextRange atspi_text_get_string_at_offset(ATSPIText obj, int offset, int granularity, Pointer error); //gint atspi_text_get_character_count(AtspiText* obj, GError** error) int atspi_text_get_character_count(ATSPIText obj, Pointer error); //gint atspi_text_get_caret_offset(AtspiText* obj, GError** error) int atspi_text_get_caret_offset(ATSPIText obj, Pointer error); //gboolean atspi_text_set_caret_offset(AtspiText* obj, gint new_offset, GError** error) int atspi_text_set_caret_offset(ATSPIText obj, int new_offset, Pointer error); //gboolean atspi_editable_text_delete_text(AtspiEditableText* obj, gint start_pos, gint end_pos, GError** error) int atspi_editable_text_delete_text(ATSPIEditableText obj, int start_pos, int end_pos, Pointer error); //gboolean atspi_action_do_action(AtspiAction* obj, gint i, GError** error) int atspi_action_do_action(ATSPIAction obj, int i, Pointer error); //gchar* atspi_action_get_action_name(AtspiAction* obj, gint i, GError** error) Pointer atspi_action_get_action_name(ATSPIAction obj, int i, Pointer error); //gint atspi_action_get_n_actions(AtspiAction* obj, GError** error) int atspi_action_get_n_actions(ATSPIAction obj, Pointer error); //class Atspi.Accessible : Atspi.Object // implements Atspi.Action, Atspi.Collection, Atspi.Component, Atspi.Document, Atspi.EditableText, // Atspi.Hypertext, Atspi.Image, Atspi.Selection, Atspi.Table, Atspi.TableCell, Atspi.Text, Atspi.Value { // accessible_parent: AtspiAccessible*, // children: GPtrArray*, // role: AtspiRole, // interfaces: gint, // name: char*, // description: char*, // states: AtspiStateSet*, // attributes: GHashTable*, // cached_properties: guint, // priv: AtspiAccessiblePrivate* //} @FieldOrder({"accessible_parent", "children", "role", "interfaces", "name", "description", "states", "attributes", "cached_properties", "priv"}) class ATSPIAccessible extends Structure { public volatile Pointer accessible_parent; //declaring this as an ATSPIAccessible.ByReference causes //crashes in native code for whatever reason, so we just declare //it as an untyped pointer since we don't need it anyway public volatile Pointer children; public volatile int role; public volatile int interfaces; public volatile Pointer name; public volatile Pointer description; public volatile Pointer states; public volatile Pointer attributes; public volatile int cached_properties; public volatile Pointer priv; public static class ByReference extends ATSPIAccessible implements Structure.ByReference {} } //interface Atspi.Text : GObject.Object class ATSPIText extends PointerType { //empty, just an interface } //interface Atspi.EditableText : GObject.Object class ATSPIEditableText extends PointerType { //empty, just an interface } //struct AtspiTextRange { // gint start_offset; // gint end_offset; // gchar* content; //} @FieldOrder({"start_offset", "end_offset", "content"}) class ATSPITextRange extends Structure { public volatile int start_offset; public volatile int end_offset; public volatile Pointer content; } //interface Atspi.Action : GObject.Object class ATSPIAction extends PointerType { //empty, just an interface } //struct AtspiEvent { // gchar* type; // AtspiAccessible* source; // gint detail1; // gint detail2; // GValue any_data; // AtspiAccessible* sender; //} @FieldOrder({"type", "source", "detail1", "detail2", "any_data", "sender"}) class ATSPIEvent extends Structure { public volatile Pointer type; public volatile ATSPIAccessible.ByReference source; public volatile int detail1; public volatile int detail2; public volatile GValue any_data; public volatile ATSPIAccessible.ByReference sender; } //class Atspi.EventListener : GObject.Object { // callback: AtspiEventListenerCB, // user_data: void*, // cb_destroyed: GDestroyNotify //} @FieldOrder({"callback", "user_data", "cb_destroyed"}) class ATSPIEventListener extends Structure { public volatile ATSPIEventListenerCallback callback; public volatile Pointer user_data; public volatile GDestroyNotifyCallback cb_destroyed; } interface ATSPIEventListenerCallback extends Callback { void invoke(ATSPIEvent event, Pointer user_data); } interface GDestroyNotifyCallback extends Callback { void invoke(Pointer data); } @FieldOrder({"g_type", "data"}) class GValue extends Structure { public volatile int g_type; //native GType (gsize / unsigned int) public volatile GValueData[] data = new GValueData[2]; } class GValueData extends Union { public volatile int v_int; public volatile long v_long; public volatile long v_int64; public volatile float v_float; public volatile double v_double; public volatile Pointer v_pointer; } }