DasherJava / src / dasherJava / core / output / ATSPILibrary.java
ATSPILibrary.java
Raw
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<ATSPILibrary> 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;
	}
}