[pkg-java] r6754 - in trunk/java-access-bridge: . bridge bridge/org bridge/org/GNOME bridge/org/GNOME/Accessibility debian
twerner at alioth.debian.org
twerner at alioth.debian.org
Sat Jul 26 16:41:30 UTC 2008
Author: twerner
Date: 2008-07-26 16:41:29 +0000 (Sat, 26 Jul 2008)
New Revision: 6754
Added:
trunk/java-access-bridge/bridge/
trunk/java-access-bridge/bridge/org/
trunk/java-access-bridge/bridge/org/GNOME/
trunk/java-access-bridge/bridge/org/GNOME/Accessibility/
trunk/java-access-bridge/bridge/org/GNOME/Accessibility/JavaBridge.java
Modified:
trunk/java-access-bridge/debian/changelog
trunk/java-access-bridge/debian/control
Log:
* Apply openjdk-java-access-bridge-tck, taken from Fedora.
* New upstream version.
Added: trunk/java-access-bridge/bridge/org/GNOME/Accessibility/JavaBridge.java
===================================================================
--- trunk/java-access-bridge/bridge/org/GNOME/Accessibility/JavaBridge.java (rev 0)
+++ trunk/java-access-bridge/bridge/org/GNOME/Accessibility/JavaBridge.java 2008-07-26 16:41:29 UTC (rev 6754)
@@ -0,0 +1,1240 @@
+/*
+ * java-access-bridge for GNOME
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+package org.GNOME.Accessibility;
+
+import org.omg.CORBA.*;
+import org.omg.PortableServer.*;
+import java.io.*;
+import java.util.*;
+import java.awt.event.*;
+import java.awt.EventQueue;
+import java.awt.AWTEvent;
+import org.GNOME.Bonobo.*;
+import org.GNOME.Accessibility.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleText;
+import javax.accessibility.AccessibleEditableText;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+
+
+public class JavaBridge {
+
+ static java.beans.PropertyChangeListener globalPropertyChangeListener = null;
+ static java.awt.event.FocusListener focusListener = null;
+ static AccessibleFactory accessibleObjectFactory = null;
+ static java.util.Hashtable accessibleObjectTable = new java.util.Hashtable();
+ static EventQueue accessQueue = null;
+ static AccessibleContext oldFocusSource = null;
+ static String oldFocusText = "";
+ static int oldFocusSelectStart = 0;
+ static int oldFocusSelectEnd = 0;
+ static AccessibleContext oldFocusCtx = null;
+ static AccessibleContext savedFocusSource = null;
+ static java.lang.Object oldEventSource = null;
+ static String oldEventName = null;
+ static int oldDetail1 = -1;
+ static boolean debugFlag = false;
+ static Application the_app;
+
+ javax.accessibility.Accessible appAccessible;
+
+ static {
+ accessibleObjectFactory = new AccessibleFactory();
+ }
+
+ static {
+ globalPropertyChangeListener = new java.beans.PropertyChangeListener() {
+ public void propertyChange (java.beans.PropertyChangeEvent e) {
+ String propertyName = e.getPropertyName();
+// System.out.println ("Prop Change Event: " + e.getSource()+" "+e.getPropertyName());
+ if (propertyName == AccessibleContext.ACCESSIBLE_CARET_PROPERTY)
+ dispatchCaretProperty(e);
+ else if (propertyName == AccessibleContext.ACCESSIBLE_TEXT_PROPERTY)
+ dispatchTextProperty(e);
+ else if (propertyName == AccessibleContext.ACCESSIBLE_CHILD_PROPERTY)
+ dispatchChildProperty(e);
+ else if (propertyName == AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) {
+ java.lang.Object source = e.getSource();
+ java.lang.Object descendant = e.getNewValue();
+ org.omg.CORBA.Any any;
+ AccessibleContext ac = null;
+ int detail1 = -1;
+
+ any = AccessUtil.getORB().create_any ();
+
+ if (descendant != null) {
+ if (descendant instanceof AccessibleContext)
+ ac = (AccessibleContext) descendant;
+ else if (descendant instanceof javax.accessibility.Accessible)
+ ac = ((javax.accessibility.Accessible) descendant).getAccessibleContext();
+ }
+ if (ac != null) {
+ org.GNOME.Accessibility.Accessible accessible = getAccessibleObjectFactory().getAccessible(ac);
+
+ EventDetails ed = new EventDetails();
+ ed.host_application = the_app;
+ ed.source_role = accessible.getRole();
+ ed.source_name = accessible.name();
+ ed.any_data = AccessUtil.getORB().create_any ();
+ AccessibleHelper.insert(ed.any_data, accessible);
+ EventDetailsHelper.insert (any, ed);
+
+ detail1 = ac.getAccessibleIndexInParent ();
+ }
+ dispatchEvent(source,
+ "object:active-descendant-changed",
+ detail1, 0, any);
+ }
+ else if (propertyName == AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) {
+ boolean textEvent = false;
+ java.lang.Object source = e.getSource();
+ javax.accessibility.AccessibleRole role = null;
+ if (source instanceof AccessibleContext ) {
+ role = ((AccessibleContext) source).getAccessibleRole();
+ if ( (role == javax.accessibility.AccessibleRole.TEXT)
+ || role.toDisplayString(java.util.Locale.US).equalsIgnoreCase("paragraph"))
+ textEvent = true;
+ else if ( role == javax.accessibility.AccessibleRole.MENU_BAR )
+ dispatchFocusEvent (source);
+ else if ( role == javax.accessibility.AccessibleRole.PAGE_TAB_LIST ) {
+ // Generate a focus event for the tab selected.
+ // Because TABs are not actually components in Java
+ // they don't generate focus, so we need to simulate.
+ javax.accessibility.AccessibleSelection aSelection =
+ ((AccessibleContext) source).getAccessibleSelection();
+ if ( aSelection != null &&
+ aSelection.getAccessibleSelectionCount() > 0 ) {
+ java.lang.Object child = aSelection.getAccessibleSelection(0);
+ dispatchFocusEvent (child);
+ }
+ }
+ }
+ if ( textEvent ) {
+ int selection_start = 0, selection_end = 0;
+ int selection_change_start = 0, selection_change_end = 0;
+ org.omg.CORBA.Any any = AccessUtil.getORB().create_any ();
+ AccessibleContext ac = null;
+ if (source instanceof AccessibleContext)
+ ac = (AccessibleContext) source;
+ // if this is the currently focussed object, return the delta
+ // otherwise return the whole thing
+ AccessibleText text = ac.getAccessibleText ();
+ boolean new_selection = true;
+ if (text != null) {
+ selection_start = text.getSelectionStart ();
+ selection_end = text.getSelectionEnd ();
+ }
+ if ((ac != null) && (ac == oldFocusSource)) {
+ if ((selection_start != oldFocusSelectStart) ||
+ (selection_end != oldFocusSelectEnd)) {
+ if (selection_start != oldFocusSelectStart) {
+ selection_change_start = selection_start;
+ if (oldFocusSelectEnd != oldFocusSelectStart)
+ selection_change_end = oldFocusSelectStart;
+ else
+ selection_change_end = selection_end;
+ }
+ if (selection_end != oldFocusSelectEnd) {
+ selection_change_end = selection_end;
+ if (oldFocusSelectStart != oldFocusSelectEnd)
+ selection_change_start = oldFocusSelectEnd;
+ else
+ selection_change_start = selection_start;
+ }
+ oldFocusSelectStart = selection_start;
+ oldFocusSelectEnd = selection_end;
+ }
+ else {
+ new_selection = false;
+ }
+ }
+ else {
+ selection_change_start = selection_start;
+ selection_change_end = selection_end;
+ }
+ if (new_selection) {
+ org.GNOME.Accessibility.Accessible accessible = getAccessibleObjectFactory().getAccessible(ac);
+ EventDetails ed = new EventDetails();
+ ed.host_application = the_app;
+ ed.source_role = accessible.getRole();
+ ed.source_name = accessible.name();
+ ed.any_data = AccessUtil.getORB().create_any();
+ ed.any_data.insert_string (oldFocusText.substring (
+ Math.min (selection_change_start,
+ selection_change_end),
+ Math.max (selection_change_start,
+ selection_change_end)));
+ EventDetailsHelper.insert (any, ed);
+ dispatchEvent(source,
+ "object:text-selection-changed",
+ selection_start, selection_end, any);
+ }
+ }
+ else {
+ dispatchEvent(source,
+ "object:selection-changed",
+ 0, 0);
+ }
+ }
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY)
+ ;
+ //dispatchEvent(e.getSource(),
+ // "object:visible-data-changed",
+ // 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_ACTION_PROPERTY)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-actions",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_VALUE_PROPERTY)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-value",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-description",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_NAME_PROPERTY)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-name",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_HYPERTEXT_OFFSET)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-hypertext-offset",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:model-changed",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_CAPTION_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-caption",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_SUMMARY_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-summary",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_COLUMN_HEADER_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-column-header",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-column-description",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_ROW_HEADER_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-row-header",
+ 0, 0);
+ else if (propertyName ==
+ AccessibleContext.ACCESSIBLE_TABLE_ROW_DESCRIPTION_CHANGED)
+ dispatchEvent(e.getSource(),
+ "object:property-change:accessible-table-row-description",
+ 0, 0);
+ else if (propertyName == AccessibleContext.ACCESSIBLE_STATE_PROPERTY) {
+ java.lang.Object value = e.getNewValue();
+ java.lang.Object source = e.getSource();
+ if (value == javax.accessibility.AccessibleState.ARMED ) {
+ javax.accessibility.AccessibleRole role = null;
+ javax.accessibility.Accessible parent = null;
+ javax.accessibility.AccessibleRole parent_role = null;
+
+ if (source instanceof AccessibleContext ) {
+ parent = ((AccessibleContext) source).getAccessibleParent();
+ if ( parent != null )
+ parent_role = parent.getAccessibleContext().getAccessibleRole();
+ role = ((AccessibleContext) source).getAccessibleRole();
+ }
+ else if (source instanceof javax.accessibility.Accessible) {
+ parent = ((javax.accessibility.Accessible) source).
+ getAccessibleContext().getAccessibleParent();
+ if ( parent != null )
+ parent_role = parent.getAccessibleContext().getAccessibleRole();
+ role = ((javax.accessibility.Accessible) source).
+ getAccessibleContext().getAccessibleRole();
+ }
+
+// if ( parent_role != null )
+// System.err.println ("State changed source parent_role " + parent_role );
+// else
+// System.err.println ("State changed source parent_role null");
+// if ( role != null )
+// System.err.println ("State changed source role " + role );
+// else
+// System.err.println ("State changed source role null");
+
+ if ( role != null ) {
+ if ( role == javax.accessibility.AccessibleRole.MENU_ITEM ||
+ role == javax.accessibility.AccessibleRole.MENU ) {
+
+ dispatchFocusEvent (source);
+ }
+ else if ( parent_role != null &&
+ ( parent_role == javax.accessibility.AccessibleRole.MENU &&
+ ( role == javax.accessibility.AccessibleRole.CHECK_BOX ||
+ role == javax.accessibility.AccessibleRole.RADIO_BUTTON )
+ ) ) {
+ dispatchFocusEvent (source);
+ }
+ }
+ } else if (value == javax.accessibility.AccessibleState.SELECTED
+ && source instanceof AccessibleContext ) {
+ javax.accessibility.AccessibleRole role = null;
+ role = ((AccessibleContext) source).getAccessibleRole ();
+ if ( role == javax.accessibility.AccessibleRole.MENU ) {
+ dispatchFocusEvent (source);
+ }
+ } else if (value == javax.accessibility.AccessibleState.FOCUSED) {
+ dispatchFocusEvent (source);
+ }
+
+ // System.err.println ("State changed: " + source + ": new value : " + value);
+
+ dispatchStateProperty(e);
+ }
+ }
+ };
+
+ focusListener = new java.awt.event.FocusListener() {
+ public void focusGained(FocusEvent e) {
+ dispatchFocusEvent(e.getSource());
+ }
+ public void focusLost(FocusEvent e) {
+ ;
+ }
+ };
+ }
+
+ public static void main(String args[]) {
+
+ new JavaBridge();
+
+ }
+
+ public JavaBridge() {
+
+ setDebug();
+
+ if (debugFlag)
+ System.err.println ("Java Accessibility Bridge for GNOME loaded.\n");
+
+ // Not sure what kind of arguments should be sent to ORB
+ String vm_rev = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public java.lang.Object run() {
+ return System.getProperty("java.version");
+ }
+ });
+
+ if (vm_rev.compareTo("1.4.0") < 0) {
+ System.err.println("WARNING: Java Accessibility Bridge " +
+ "for GNOME requires JVM version 1.4.0 or greater.");
+ } else {
+ registerApplication();
+ }
+ }
+
+ public JavaBridge(String[] args) {
+
+ System.err.println(args);
+ new JavaBridge();
+ }
+
+ public static POA getRootPOA () {
+ return AccessUtil.getRootPOA ();
+ }
+
+ public static AccessibleFactory getAccessibleObjectFactory () {
+ return accessibleObjectFactory;
+ }
+
+ public static java.util.Hashtable getAccessibleObjectTable () {
+ return accessibleObjectTable;
+ }
+
+ public static java.beans.PropertyChangeListener getGlobalPropertyChangeListener() {
+ return globalPropertyChangeListener;
+ }
+
+ public static java.awt.event.FocusListener getFocusListener() {
+ return focusListener;
+ }
+
+ public static AccessibleContext getFocusContext() {
+ return oldFocusSource;
+ }
+
+ public static void dispatchWindowEvent(java.lang.Object source, String eventName) {
+ try {
+ if (source instanceof javax.accessibility.Accessible) {
+ dispatchEvent (((javax.accessibility.Accessible)
+ source).getAccessibleContext(),
+ eventName,
+ 0,
+ 0);
+ }
+ } catch (Exception ex) {
+ System.err.println(ex+" caught.");
+ ex.printStackTrace();
+ }
+ }
+
+ public static void dispatchEvent(java.lang.Object eventSource,
+ String eventName,
+ int detail1,
+ int detail2,
+ org.omg.CORBA.Any any) {
+ AccessibleImpl source;
+ // System.out.println ("dispatching event with ANY type " + any.type ());
+ try {
+ AccessibleContext ac = null;
+ if (eventSource instanceof AccessibleContext)
+ ac = (AccessibleContext) eventSource;
+ else if (eventSource instanceof
+ javax.accessibility.Accessible)
+ ac =
+ ((javax.accessibility.Accessible) eventSource)
+ .getAccessibleContext();
+ else {
+// System.out.println ("Event source inaccessible! : " +
+// eventSource.toString() );
+ return;
+ }
+
+ org.GNOME.Accessibility.Accessible accessible =
+ getAccessibleObjectFactory().
+ getAccessible(ac);
+
+ if (!any.type().equivalent(EventDetailsHelper.type())) {
+ EventDetails ed = new EventDetails();
+ ed.host_application = the_app;
+ ed.source_role = accessible.getRole();
+ ed.source_name = accessible.name();
+ ed.any_data = AccessUtil.getORB().create_any();
+ EventDetailsHelper.insert (any, ed);
+ }
+
+ org.GNOME.Accessibility.Event event =
+ new org.GNOME.Accessibility.Event (eventName,
+ accessible,
+ detail1,
+ detail2,
+ any);
+// System.out.println(eventName + " " +
+// detail1 + "," + detail2 + " from " +
+// eventSource.toString() );
+ accessible.ref();
+ AccessUtil.getRegistryObject().notifyEvent(event);
+ } catch (Exception ex) {
+ if (debugFlag)
+ System.out.println ("Error dispatching event "+eventName+":"+eventSource+"; "+ex);
+ }
+ }
+
+ public static void dispatchEvent(java.lang.Object eventSource,
+ String eventName,
+ int detail1,
+ int detail2) {
+ AccessibleImpl source;
+ org.omg.CORBA.Any any = AccessUtil.getORB().create_any ();
+ dispatchEvent (eventSource, eventName, detail1, detail2, any);
+ }
+
+ public static boolean dispatchDeviceEvent (DeviceEvent de) {
+ try {
+ if (de == null) return false;
+ else return AccessUtil.getRegistryObject().
+ getDeviceEventController().notifyListenersSync(de);
+ }
+ catch (Exception e)
+ {
+ if (debugFlag)
+ System.out.println("Exception in dispatchDeviceEvent " + e);
+ return false;
+ }
+ }
+
+ public static void dispatchFocusEvent(java.lang.Object eventSource) {
+ AccessibleContext ctx;
+
+ // System.err.println ("dispatchFocusEvent: " + eventSource);
+ if (eventSource == null) {
+ oldFocusSource = null;
+ return;
+ }
+
+ try {
+ if (eventSource instanceof javax.accessibility.AccessibleContext) {
+ ctx = (AccessibleContext) eventSource;
+ }
+ else if (eventSource instanceof javax.accessibility.Accessible) {
+ ctx = ((javax.accessibility.Accessible)
+ eventSource).getAccessibleContext();
+ }
+ else {
+// System.out.println ("Focus Event source inaccessible! : " +
+// eventSource.toString());
+ return;
+ }
+
+ // If the currently focused object is the eventSource
+ // we do not another focus event.
+ //
+ if (ctx == oldFocusSource)
+ return;
+ else {
+ // System.err.println ("oldFocusSource " + oldFocusSource);
+ // System.err.println ("oldFocusCtx " + oldFocusCtx);
+ // System.err.println ("ctx " + ctx);
+ if (oldFocusSource != null) {
+ javax.accessibility.AccessibleRole role = oldFocusSource.getAccessibleRole ();
+ // Focus event when menu is selected focus
+ // it if window loses and regains focus.
+ // System.err.println (oldFocusSource + " " + role);
+ if (role == javax.accessibility.AccessibleRole.MENU ||
+ role == javax.accessibility.AccessibleRole.MENU_ITEM) {
+ String jrootpane = "javax.swing.JRootPane$AccessibleJRootPane";
+ String name = ctx.getClass().getName();
+
+ // Do not report focus if next focus
+ // object is a JRootPane. Bug #125691.
+ if (name.compareTo (jrootpane) == 0) {
+ oldFocusCtx = ctx;
+ return;
+ }
+ }
+ savedFocusSource = ctx;
+ } else if (oldFocusCtx == ctx) {
+ ctx = savedFocusSource;
+ } else {
+ savedFocusSource = ctx;
+ }
+ oldFocusSource = ctx;
+ if ((ctx != null) && (ctx.getAccessibleText () != null)) {
+ AccessibleText axt = ctx.getAccessibleText ();
+ oldFocusText = getTextRange (axt, 0,
+ axt.getCharCount ());
+ oldFocusSelectStart = axt.getSelectionStart ();
+ oldFocusSelectEnd = axt.getSelectionEnd ();
+ }
+ else oldFocusText = "";
+ }
+
+ //
+ // Handle PAGE_TAB be sending focus-events for PAGE_TAB_LIST
+ // on focused child instead.
+ //
+ javax.accessibility.AccessibleRole role = null;
+ role = ctx.getAccessibleRole();
+ if ( role == javax.accessibility.AccessibleRole.PAGE_TAB_LIST ) {
+ // Ensure listeners are attached to page-tab-list still...
+ org.GNOME.Accessibility.Accessible accessible =
+ JavaBridge.getAccessibleObjectFactory().getAccessible(ctx);
+ javax.accessibility.AccessibleSelection aSelection =
+ ctx.getAccessibleSelection();
+ if ( aSelection != null &&
+ aSelection.getAccessibleSelectionCount() > 0 ) {
+ java.lang.Object child = aSelection.getAccessibleSelection(0);
+ if (child instanceof javax.accessibility.AccessibleContext) {
+ ctx = (AccessibleContext) child;
+ }
+ else if (child instanceof javax.accessibility.Accessible) {
+ ctx = ((javax.accessibility.Accessible)
+ child).getAccessibleContext();
+ }
+ else
+ return;
+ }
+ }
+ org.GNOME.Accessibility.Accessible accessible =
+ JavaBridge.getAccessibleObjectFactory().getAccessible(ctx);
+
+ org.omg.CORBA.Any any = AccessUtil.getORB().create_any ();
+ EventDetails ed = new EventDetails();
+ ed.host_application = the_app;
+ ed.source_role = accessible.getRole();
+ ed.source_name = accessible.name();
+ ed.any_data = AccessUtil.getORB().create_any ();
+ EventDetailsHelper.insert (any, ed);
+ org.GNOME.Accessibility.Event event = new org.GNOME.Accessibility.Event
+ ("focus:", accessible, 0, 0, any);
+ // System.out.println("focus: " + ctx);
+ accessible.ref();
+ AccessUtil.getRegistryObject().notifyEvent(event);
+ } catch (Exception ex) {
+ if (debugFlag)
+ System.out.println ("Error dispatching focus event "+":"+eventSource+":"+ex);
+ }
+ }
+
+ public static void dispatchCaretProperty(java.beans.PropertyChangeEvent e) {
+ int oldCaretPosition = Integer.parseInt(e.getOldValue().toString());
+ int newCaretPosition = Integer.parseInt(e.getNewValue().toString());
+// System.err.println("Carent EVENT : " + newCaretPosition + ", " +
+// oldCaretPosition );
+ // check selection, to see if it has changed
+ AccessibleText text = null;
+ if ((e.getSource() instanceof AccessibleContext) && (e.getSource() == oldFocusSource)) {
+ text = ((AccessibleContext )e.getSource()).getAccessibleText ();
+ int selection_start = text.getSelectionStart ();
+ int selection_end = text.getSelectionEnd ();
+ if ((selection_start != oldFocusSelectStart) ||
+ (selection_end != oldFocusSelectEnd)) {
+ org.omg.CORBA.Any selection_any = AccessUtil.getORB().create_any ();
+ int selection_change_start = 0;
+ int selection_change_end = 0;
+ if (selection_start != oldFocusSelectStart) {
+ selection_change_start = selection_start;
+ if (oldFocusSelectEnd != oldFocusSelectStart)
+ selection_change_end = oldFocusSelectStart;
+ else
+ selection_change_end = selection_end;
+ }
+ if (selection_end != oldFocusSelectEnd) {
+ selection_change_end = selection_end;
+ if (oldFocusSelectStart != oldFocusSelectEnd)
+ selection_change_start = oldFocusSelectEnd;
+ else
+ selection_change_start = selection_start;
+ }
+ oldFocusSelectStart = selection_start;
+ oldFocusSelectEnd = selection_end;
+ if (selection_change_start != selection_change_end) {
+ selection_any.insert_string (oldFocusText.substring (
+ Math.min (selection_change_start, selection_change_end),
+ Math.max (selection_change_start, selection_change_end)));
+ dispatchEvent (e.getSource(),
+ "object:text-selection-changed",
+ selection_start, selection_end,
+ selection_any);
+ }
+ }
+ }
+ dispatchEvent(e.getSource(),
+ "object:text-caret-moved",
+ newCaretPosition,
+ oldCaretPosition);
+ }
+
+ private static HashMap lastTextSizes = new HashMap();
+
+ public static void setInitialTextSize( AccessibleContext ac, int size ) {
+ lastTextSizes.put(ac, new Integer(size));
+ }
+
+
+ // cut-and-pasted from TextImpl.java
+ private static String getTextRange ( AccessibleText accText, int startOffset, int endOffset) {
+ String text = "";
+ int offset = startOffset;
+ String word = accText.getAtIndex (
+ javax.accessibility.AccessibleText.WORD,
+ startOffset);
+ // go char-by-char until word changes,
+ while (offset < endOffset && word.equals (accText.getAtIndex (
+ javax.accessibility.AccessibleText.WORD, offset) ) ) {
+ String character = accText.getAtIndex (
+ javax.accessibility.AccessibleText.CHARACTER,
+ offset);
+ ++offset;
+ if (character != null)
+ text += character;
+ // TODO: charbuff would be faster here
+ }
+ // then word by word until offset crosses
+ while (offset < endOffset) {
+ word = accText.getAtIndex (
+ javax.accessibility.AccessibleText.WORD,
+ offset);
+ offset += word.length();
+ if (offset > endOffset)
+ text += word.substring (0,
+ word.length() - (offset - endOffset));
+ else
+ text += word;
+ } // TODO: sentence-by-sentence for even longer spans.
+
+ return text;
+ }
+
+ //
+ // In order to overcome some deficiencies in the JAA a private interface
+ // was agreed with SO/OOo to handle more detailed information about text
+ // events that occur.
+ // The main thing was the ability to tell if the change event was an
+ // insert/delete or replace operation. This is determined from the values
+ // of old and new:
+ //
+ // OLD NEW RESULT
+ // --- --- ------
+ // NULL NON-NULL Insert event
+ // NON-NULL NULL Remove event
+ // NON-NULL NON-NULL Replace/Update event
+ // NULL NULL Undetermined - signal general change
+ //
+ // Another addition is the ability to pass a range for old and new values
+ // rather than a single object. This allows us to be able to pass the
+ // appropriate information to GNOME as required. We only support an array
+ // which as 2 Integer class values in it - a start and end point.
+ //
+ // Standard Java is to pass only a single Integer newValue at present, so
+ // this behaviour remains unchanged.
+ //
+ public static void dispatchTextProperty(java.beans.PropertyChangeEvent e) {
+ try {
+ java.lang.Object newValueObject = e.getNewValue();
+ java.lang.Object oldValueObject = e.getOldValue();
+ // Initialize to "All Changed" values.
+ int newValue = 0;
+ int oldValue = -1;
+ String eventString = "object:text-changed";
+ org.omg.CORBA.Any any = AccessUtil.getORB().create_any ();
+
+ if ( newValueObject instanceof Integer ) {
+ AccessibleContext ac = null;
+ java.lang.Object eventSource = e.getSource();
+ if (eventSource instanceof AccessibleContext)
+ ac = (AccessibleContext) eventSource;
+ else if (eventSource instanceof
+ javax.accessibility.Accessible) ac =
+ ((javax.accessibility.Accessible) eventSource)
+ .getAccessibleContext();
+
+ AccessibleText aText = ac.getAccessibleText();
+ AccessibleEditableText aeText = ac.getAccessibleEditableText();
+
+ int charCount = aText.getCharCount();
+ Integer prevCount = (Integer)lastTextSizes.put(ac, new Integer(charCount));
+ int prevCharCount;
+ if ( prevCount == null )
+ prevCharCount = 0;
+ else
+ prevCharCount = prevCount.intValue();
+
+ if (charCount > prevCharCount) {
+ eventString += ":insert";
+ oldValue = charCount - prevCharCount;
+ if (aeText != null) {
+ any.insert_string (aeText.getTextRange (((Integer)newValueObject).intValue(),
+ ((Integer)newValueObject).intValue() + oldValue));
+ if (ac == oldFocusSource)
+ oldFocusText = aeText.getTextRange (0, charCount);
+ }
+ else if ((ac != null) && (ac == oldFocusSource)) {
+ any.insert_string (oldFocusText.substring (
+ ((Integer)newValueObject).intValue(),
+ ((Integer)newValueObject).intValue() +
+ oldValue));
+ oldFocusText = getTextRange (aText, 0, charCount);
+ }
+ }
+ else if ( charCount < prevCharCount ) {
+ eventString += ":delete";
+ oldValue = prevCharCount - charCount;
+
+ if ((ac != null) && (ac == oldFocusSource) && (oldFocusText != "")) {
+ int substart = ((Integer)newValueObject).intValue();
+ int subend = substart + oldValue;
+ if (oldFocusText.length() < subend)
+ System.err.println ("WARNING: subend " + subend + " > len : " + oldFocusText + " - substart = " + substart);
+
+ any.insert_string (oldFocusText.substring (
+ ((Integer)newValueObject).intValue(),
+ ((Integer)newValueObject).intValue() +
+ oldValue));
+ }
+ // otherwise, can't retrieve the lost contents
+ oldFocusText = getTextRange (aText, 0, charCount);
+ }
+ else {
+ eventString += ":replace";
+ if (aeText != null) {
+ String replacedString = aeText.getTextRange (0, charCount);
+ any.insert_string (replacedString);
+ if (ac == oldFocusSource)
+ oldFocusText = replacedString;
+ }
+ else if (ac == oldFocusSource)
+ oldFocusText = getTextRange (aText, 0, charCount);
+ }
+ newValue = ((Integer)newValueObject).intValue();
+ }
+ /*
+ * Old text change protocol for Oo
+ */
+ else if ( newValueObject instanceof Integer[] ||
+ oldValueObject instanceof Integer[] ) {
+ Integer[] newInts = (Integer[])newValueObject;
+ Integer[] oldInts = (Integer[])oldValueObject;
+ if ( (newInts != null && newInts.length != 2) ||
+ (oldInts != null && oldInts.length != 2) ) {
+ System.err.println("TEXT_CHANGED EVENT: Unexpected length of new/old values");
+ }
+ if ( newValueObject != null && oldValueObject == null ) {
+ // Insert
+ eventString += ":insert";
+ newValue = newInts[0].intValue();
+ oldValue = newInts[1].intValue();
+ }
+ else if ( oldValueObject != null && newValueObject == null ) {
+ // Delete
+ eventString += ":delete";
+ newValue = oldInts[0].intValue();
+ oldValue = oldInts[1].intValue();
+ }
+ else if ( newValueObject != null && oldValueObject != null ) {
+ // Replace (or Update)
+ // TODO - At present GNOME appears to send two seperate
+ // events for this, so generate them... It's hoped that
+ // this will change in the future.
+
+ // Send a delete event
+ newValue = oldInts[0].intValue();
+ oldValue = oldInts[1].intValue();
+ dispatchEvent(e.getSource(), eventString + ":delete",
+ newValue, oldValue, any);
+
+ // Now setup so that an insert will be sent below.
+ eventString += ":insert";
+ newValue = newInts[0].intValue();
+ oldValue = newInts[1].intValue();
+ }
+ }
+ /*
+ * New text change protocol for Oo
+ */
+ else if ( newValueObject instanceof java.lang.Object[] ||
+ oldValueObject instanceof java.lang.Object[] ) {
+ java.lang.Object[] newObjs = (java.lang.Object[])newValueObject;
+ java.lang.Object[] oldObjs = (java.lang.Object[])oldValueObject;
+ String text;
+ Integer[] newInts;
+ Integer[] oldInts;
+
+ if ( (newObjs != null && newObjs.length != 3) ||
+ (oldObjs != null && oldObjs.length != 3) ) {
+ System.err.println("TEXT_CHANGED EVENT: Unexpected length of new/old values");
+ }
+ newInts = new Integer[2];
+ oldInts = new Integer[2];
+ text = null;
+ if (newValueObject != null) {
+ newInts[0] = (Integer)newObjs [0];
+ newInts[1] = (Integer)newObjs [1];
+ }
+ if (oldValueObject != null) {
+ oldInts[0] = (Integer)oldObjs [0];
+ oldInts[1] = (Integer)oldObjs [1];
+ }
+ if ( newValueObject != null && oldValueObject == null ) {
+ // Insert
+ eventString += ":insert";
+ newValue = newInts[0].intValue();
+ oldValue = newInts[1].intValue();
+ text = (String)newObjs[2];
+ }
+ else if ( oldValueObject != null && newValueObject == null ) {
+ // Delete
+ eventString += ":delete";
+ newValue = oldInts[0].intValue();
+ oldValue = oldInts[1].intValue() - oldInts[0].intValue();
+ text = (String)oldObjs[2];
+ }
+ else if ( newValueObject != null && oldValueObject != null ) {
+ // Replace (or Update)
+ // TODO - At present GNOME appears to send two seperate
+ // events for this, so generate them... It's hoped that
+ // this will change in the future.
+
+ // Send a delete event
+ newValue = oldInts[0].intValue();
+ oldValue = oldInts[1].intValue();
+ text = (String)oldObjs[2];
+ org.omg.CORBA.Any any_replace = AccessUtil.getORB().create_any ();
+ if (text != null) {
+ any_replace.insert_string (text);
+ }
+ dispatchEvent(e.getSource(), eventString + ":delete",
+ newValue, oldValue, any_replace);
+
+ // Now setup so that an insert will be sent below.
+ eventString += ":insert";
+ newValue = newInts[0].intValue();
+ oldValue = newInts[1].intValue();
+ text = (String)newObjs[2];
+ }
+ if (text != null) {
+ any.insert_string (text);
+ }
+ }
+ else if ( newValueObject == null && oldValueObject == null ) {
+ // Report all-changed. Nothing to do programatically
+ // because it's the default behaviour...
+ }
+ else {
+ System.err.println("UNHANDLED TEXT_CHANGED EVENT NewValue CLASS: "
+ + newValueObject.getClass().getName() );
+ }
+
+ // Dispatch the Event now.
+ dispatchEvent(e.getSource(), eventString, newValue, oldValue, any);
+ } catch (Exception ex) {
+ System.out.println("caught "+ex);
+ ex.printStackTrace();
+ }
+ }
+
+ public static void dispatchChildProperty(java.beans.PropertyChangeEvent e) {
+ boolean add_event;
+ String eventName;
+
+ add_event = false;
+ eventName = "object:children-changed";
+ if ( e.getNewValue() != null && e.getOldValue() == null ) {
+ eventName += ":add";
+ add_event = true;
+ }
+ else if ( e.getOldValue() != null && e.getNewValue() == null ) {
+ eventName += ":remove";
+ add_event = false;
+ }
+ else {
+ add_event = false;
+ }
+ if ( add_event && e.getSource() instanceof javax.accessibility.AccessibleContext ) {
+ AccessibleRole ar = ((AccessibleContext)e.getSource()).getAccessibleRole();
+ if ( ar != null ) {
+ // System.err.println("ChildEvent to a " + ar.toString() );
+ if ( ar == javax.accessibility.AccessibleRole.MENU_BAR ||
+ ar == javax.accessibility.AccessibleRole.POPUP_MENU ||
+ ar == javax.accessibility.AccessibleRole.MENU ||
+ ar == javax.accessibility.AccessibleRole.MENU_ITEM ) {
+ traverseMenus( (AccessibleContext)e.getSource() );
+ }
+ }
+ }
+ //System.err.println ("dispatching child event: "+ eventName);
+ dispatchEvent(e.getSource(),
+ eventName,
+ 0,
+ 0);
+ }
+
+ public static void dispatchStateProperty(java.beans.PropertyChangeEvent e) {
+ java.lang.Object oldValue = e.getOldValue();
+ java.lang.Object newValue = e.getNewValue();
+ java.lang.Object object = e.getSource();
+ StateTypeAdapter stateType;
+ int detail1;
+
+ // System.err.println("StateProp: new = " +
+ // ((newValue == null)?("null"):(newValue.toString()))
+ // + " ; old = " +
+ // ((oldValue == null)?("null"):(oldValue.toString())) );
+ if (newValue != null) {
+ stateType = new StateTypeAdapter((javax.accessibility.AccessibleState)newValue);
+ detail1 = 1;
+ } else {
+ stateType = new StateTypeAdapter((javax.accessibility.AccessibleState)oldValue);
+ detail1 = 0;
+ }
+ // State COLLAPSED has been deprecated in AT-SPI, should now be using
+ // the state EXPANDED wit the value of 0 instead.
+ if ( stateType.value() == StateType._STATE_COLLAPSED ) {
+ stateType =
+ new StateTypeAdapter(javax.accessibility.AccessibleState.EXPANDED);
+ detail1 = 0;
+ }
+
+ String eventName = "object:state-changed:" + stateType.getName();
+
+ //System.out.println ("dispatching state event: " + eventName);
+
+ if (object == oldEventSource &&
+ eventName.compareTo(oldEventName) == 0 &&
+ detail1 == oldDetail1)
+ return;
+
+ oldEventSource = object;
+ oldEventName = eventName;
+ oldDetail1 = detail1;
+
+ dispatchEvent(e.getSource(), eventName, detail1, /*detail2*/ 0 );
+ }
+
+ static private class AttachListenerRunnable implements Runnable {
+ private org.GNOME.Accessibility.Accessible accessible;
+
+ public AttachListenerRunnable( org.GNOME.Accessibility.Accessible _accessible ) {
+ accessible = _accessible;
+ }
+
+ public void run() {
+ try {
+ JavaBridge.attachListenerRecurse(accessible);
+ }
+ catch ( Exception e ) {
+ // System.err.println("AttachListener: exception caught " + e.toString() );
+ if (debugFlag)
+ e.printStackTrace();
+ }
+ }
+ }
+
+ static private void startAttachListener( org.GNOME.Accessibility.Accessible acc ) {
+ SwingUtilities.invokeLater( new AttachListenerRunnable( acc ) );
+ // ( new Thread( new AttachListenerRunnable( acc ) ) ).start();
+
+ }
+
+ static private final int max_recurse_depth = 10;
+ static private final int max_children_block = 200;
+
+ static private void attachListenerRecurse( org.GNOME.Accessibility.Accessible accessible ) {
+ org.GNOME.Accessibility.Accessible a;
+
+ if ( accessible == null )
+ return;
+
+ int count = accessible.childCount();
+ // System.err.println("ChildCount = " + count );
+
+ // XXX - Try to handle case where very large count of children
+ if ( count < max_children_block ) {
+ for ( int i =0; i < count; i++ ) {
+ attachListenerRecurse( accessible.getChildAtIndex(i) );
+ }
+ }
+ else {
+ // System.err.println("Num Children > " + max_children_block + " : returning...");
+ return;
+ }
+ }
+
+ static public boolean traverseMenus( AccessibleContext ac ) {
+ return traverseMenus( ac, 0 );
+ }
+
+ static public boolean traverseMenus( AccessibleContext ac, int depth ) {
+ boolean rVal = false;
+
+ if ( ac != null && depth < max_recurse_depth ) {
+ // Recursively descend hierarchy until we find menus
+ // System.err.println("traverseMenus( depth = " + depth + " )" );
+ AccessibleRole ar = ac.getAccessibleRole();
+ if ( ar != null ) {
+ if ( ar == javax.accessibility.AccessibleRole.MENU_BAR ||
+ ar == javax.accessibility.AccessibleRole.POPUP_MENU ||
+ ar == javax.accessibility.AccessibleRole.MENU ||
+ ar == javax.accessibility.AccessibleRole.MENU_ITEM ) {
+ //attach listeners
+ // System.err.println("Found Menus!!!! depth = " +depth);
+ org.GNOME.Accessibility.Accessible accessible =
+ getAccessibleObjectFactory().
+ getAccessible(ac);
+
+ startAttachListener( accessible );
+ rVal = true;
+ }
+ else {
+ // iterate children until get true or handled all
+ for ( int i = 0; i < ac.getAccessibleChildrenCount(); i++) {
+ javax.accessibility.Accessible a = ac.getAccessibleChild( i );
+ if ( a != null ) {
+ getAccessibleObjectFactory()
+ .getAccessible(a.getAccessibleContext());
+ rVal = traverseMenus( a.getAccessibleContext(), depth + 1 );
+ if ( rVal ) // Found a menu, we can go now...
+ break;
+ }
+ }
+ }
+ }
+ }
+ return rVal;
+ }
+
+ public boolean registerApplication() {
+ try {
+ Process p = Runtime.getRuntime().exec ("gconftool-2 -g /desktop/gnome/interface/accessibility");
+ BufferedReader b = new BufferedReader (
+ new InputStreamReader (p.getInputStream ()));
+ String result = b.readLine();
+ if (result == null ||
+ !result.equals ("true")) {
+ return false;
+ }
+
+ if (AccessUtil.getRegistryObject() == null)
+ return false;
+
+ if (debugFlag)
+ System.err.println ("Registering Application.");
+ appAccessible = new ApplicationAccessible ();
+
+ Application aref = getAccessibleObjectFactory().
+ getApplication(appAccessible.getAccessibleContext());
+ the_app = aref;
+
+ if (debugFlag)
+ System.err.println(aref);
+
+ AccessUtil.getRegistryObject().registerApplication(aref);
+
+ if (debugFlag) {
+ System.err.println(aref.name() + ":" + aref.id());
+ System.err.println("Just registered Application");
+ }
+ return true;
+
+ } catch (Exception e) {
+ if (debugFlag)
+ System.out.println("Error registering application, exception is: "+ e);
+ return false;
+ }
+ }
+
+ public static EventQueue getEventQueue () {
+ if (accessQueue == null)
+ accessQueue = new AccessQueue ();
+ return accessQueue;
+ }
+
+ public static class AccessQueue extends EventQueue {
+
+ static KeyEvent pendingKeyPress = null;
+
+ public AccessQueue () {
+ super ();
+ }
+
+ public void dispatchEvent (AWTEvent e) {
+ if (e instanceof KeyEvent)
+ filterKeyEvent ((KeyEvent) e);
+ else
+ super.dispatchEvent (e);
+ }
+
+ private static boolean isModifierKey( KeyEvent e ) {
+ switch ( e.getKeyCode() ) {
+ case KeyEvent.VK_SHIFT:
+ case KeyEvent.VK_CONTROL:
+ case KeyEvent.VK_META:
+ case KeyEvent.VK_ALT:
+ case KeyEvent.VK_ALT_GRAPH:
+ return true;
+ }
+ return false;
+ }
+
+
+ public void filterKeyEvent (KeyEvent e) {
+ boolean isConsumed = false;
+ DeviceEvent de = null;
+ //System.err.println ("key event " + e.getKeyChar ());
+ if (e.getID () == KeyEvent.KEY_PRESSED) {
+ // If this is a KEY_PRESSED event that's not an action,
+ // hold it and wait for KEY_TYPED
+ if (e.isActionKey () || isModifierKey( e ) ) {
+ de = KeyEventAdapter.deviceEventFromKeyEvent (e);
+ isConsumed =
+ JavaBridge.dispatchDeviceEvent (de);
+ pendingKeyPress = null;
+ } else {
+ pendingKeyPress = e;
+ isConsumed = true;
+ }
+ } else if (e.getID () == KeyEvent.KEY_TYPED) {
+ if (pendingKeyPress != null) {
+ de = KeyEventAdapter.coalescePressAndTyped (
+ pendingKeyPress, e);
+ if (de == null) { // coalesce unsuccessful!
+ //System.out.println ("Key coalesce attempt failure!");
+ de = KeyEventAdapter.deviceEventFromKeyEvent ( pendingKeyPress);
+ isConsumed = JavaBridge.dispatchDeviceEvent (de);
+ if (! isConsumed)
+ super.dispatchEvent (
+ pendingKeyPress);
+ pendingKeyPress = null;
+ de =
+ KeyEventAdapter.deviceEventFromKeyEvent (e);
+ }
+ } else {
+ de = KeyEventAdapter.deviceEventFromKeyEvent (e);
+ }
+ isConsumed = JavaBridge.dispatchDeviceEvent (de);
+ if ( isConsumed ) pendingKeyPress = null;
+ } else if (e.getID () == KeyEvent.KEY_RELEASED) {
+ if (pendingKeyPress != null)
+ super.dispatchEvent (pendingKeyPress);
+ de = KeyEventAdapter.deviceEventFromKeyEvent (e);
+ isConsumed = JavaBridge.dispatchDeviceEvent (de);
+ pendingKeyPress = null;
+ }
+ if (! isConsumed) {
+ if (pendingKeyPress != null) {
+ super.dispatchEvent (pendingKeyPress);
+ pendingKeyPress = null;
+ }
+ super.dispatchEvent (e);
+ }
+ }
+ }
+
+ public static void exit() {
+
+ }
+
+ private void setDebug() {
+ try {
+ Process p = Runtime.getRuntime().exec ("env");
+ BufferedReader b = new BufferedReader (
+ new InputStreamReader (p.getInputStream ()));
+
+ String result = b.readLine();
+ if (result == null)
+ return;
+
+ String str;
+ while ((str = b.readLine()) != null) {
+ if (str.indexOf ("GNOME_ACCESSIBILITY") >= 0) {
+ debugFlag = true;
+ return;
+ }
+ }
+ }
+ catch (Exception e) {
+ }
+ }
+}
Modified: trunk/java-access-bridge/debian/changelog
===================================================================
--- trunk/java-access-bridge/debian/changelog 2008-07-26 16:06:24 UTC (rev 6753)
+++ trunk/java-access-bridge/debian/changelog 2008-07-26 16:41:29 UTC (rev 6754)
@@ -1,3 +1,15 @@
+java-access-bridge (1.23.0-2) unstable; urgency=low
+
+ * Apply openjdk-java-access-bridge-tck, taken from Fedora.
+
+ -- Matthias Klose <doko at debian.org> Thu, 24 Jul 2008 14:14:03 +0200
+
+java-access-bridge (1.23.0-1) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Matthias Klose <doko at debian.org> Fri, 11 Jul 2008 18:35:08 +0000
+
java-access-bridge (1.22.0-1) unstable; urgency=low
* first upload to Debian (Closes: #346599)
Modified: trunk/java-access-bridge/debian/control
===================================================================
--- trunk/java-access-bridge/debian/control 2008-07-26 16:06:24 UTC (rev 6753)
+++ trunk/java-access-bridge/debian/control 2008-07-26 16:41:29 UTC (rev 6754)
@@ -13,7 +13,7 @@
Package: libaccess-bridge-java
Architecture: all
-Depends: openjdk-6-jre | icedtea-java7-jre | java5-runtime-headless
+Depends: openjdk-6-jre | cacao-oj6-jre | java5-runtime-headless
Description: Java Access Bridge for GNOME
This module contains the Java Access Bridge for GNOME,
which connects the built-in accessibility support in
More information about the pkg-java-commits
mailing list