| /* |
| * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "AccessBridgeCalls.h" |
| #include "AccessInfo.h" |
| #include <stdio.h> |
| #include <time.h> |
| |
| LogStringCallbackFP g_LogStringCallback = NULL; |
| |
| /* |
| * returns formatted date and time |
| */ |
| char *getTimeAndDate() { |
| static char datebuf[64]; |
| struct tm *newtime; |
| char am_pm[] = "AM"; |
| time_t long_time; |
| |
| time( &long_time ); /* Get time as long integer. */ |
| newtime = localtime( &long_time ); /* Convert to local time. */ |
| |
| if( newtime->tm_hour > 12 ) /* Set up extension. */ |
| strcpy( am_pm, "PM" ); |
| if( newtime->tm_hour > 12 ) /* Convert from 24-hour */ |
| newtime->tm_hour -= 12; /* to 12-hour clock. */ |
| if( newtime->tm_hour == 0 ) /*Set hour to 12 if midnight. */ |
| newtime->tm_hour = 12; |
| |
| sprintf(datebuf, "%.19s %s\n", asctime( newtime ), am_pm ); |
| return (char *)datebuf; |
| } |
| |
| |
| /* |
| * displays a message in a dialog and writes the message to a logfile |
| */ |
| void displayAndLog(HWND hDlg, int nIDDlgItem, FILE *logfile, char *msg, ...) { |
| |
| if (hDlg == NULL || msg == NULL) { |
| return; |
| } |
| |
| char tmpbuf[HUGE_BUFSIZE]; |
| va_list argprt; |
| |
| va_start(argprt, msg); |
| vsprintf(tmpbuf, msg, argprt); |
| |
| SetDlgItemText(hDlg, nIDDlgItem, tmpbuf); |
| |
| fprintf(logfile, "\n****************************************\n"); |
| fprintf(logfile, "%s\n", getTimeAndDate()); |
| fprintf(logfile, "%s\n", tmpbuf); |
| fflush(logfile); |
| |
| if ( NULL != g_LogStringCallback ) |
| { |
| g_LogStringCallback (tmpbuf); |
| } |
| } |
| |
| /* |
| * writes a text string to a logfile |
| */ |
| void logString(FILE *logfile, char *msg, ...) { |
| |
| if (logfile == NULL || msg == NULL) { |
| return; |
| } |
| |
| char tmpbuf[LINE_BUFSIZE]; |
| va_list argprt; |
| |
| va_start(argprt, msg); |
| vsprintf(tmpbuf, msg, argprt); |
| |
| fprintf(logfile, tmpbuf); |
| fprintf(logfile, "\n"); |
| fflush(logfile); |
| } |
| |
| /* |
| * safely appends a message to a buffer |
| */ |
| BOOL appendToBuffer(char *buf, size_t buflen, char *msg, ...) { |
| |
| static char warning[] = |
| "\nNot enough buffer space; remaining information truncated.\n"; |
| size_t warningLength = strlen(warning) + 1; |
| |
| if (buf == NULL || msg == NULL) { |
| return FALSE; |
| } |
| |
| char tmpbuf[LARGE_BUFSIZE]; |
| va_list argprt; |
| |
| va_start(argprt, msg); |
| vsprintf(tmpbuf, msg, argprt); |
| |
| // verify there's enough space in the buffer |
| size_t spaceRemaining = buflen - strlen(buf) - 1; |
| if (spaceRemaining <= warningLength) { |
| strncat(buf, warning, spaceRemaining); |
| return FALSE; |
| } |
| strncat(buf, tmpbuf, spaceRemaining); |
| return TRUE; |
| } |
| |
| /** |
| * returns accessibility information for an AccessibleContext |
| */ |
| char *getAccessibleInfo(long vmID, AccessibleContext ac, char *buffer, |
| int bufsize) { |
| return getAccessibleInfo(vmID, ac, 0, 0, buffer, bufsize); |
| } |
| |
| /** |
| * returns accessibility information at the specified coordinates in an |
| * AccessibleContext |
| */ |
| char *getAccessibleInfo(long vmID, AccessibleContext ac, int x, int y, |
| char *buffer, int bufsize) { |
| |
| wchar_t tmpBuf[LINE_BUFSIZE]; |
| wchar_t name[LINE_BUFSIZE]; |
| int i, j; |
| long start; |
| long end; |
| |
| if (buffer == NULL || bufsize <= 0) { |
| return NULL; |
| } |
| buffer[0] = NULL; |
| |
| /* ===== AccessBridge / J2SE version information ===== */ |
| |
| AccessBridgeVersionInfo versionInfo; |
| BOOL result = GetVersionInfo(vmID, &versionInfo); |
| |
| if (result == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: cannot get version information", bufsize ); |
| } else { |
| appendToBuffer(buffer, bufsize, "Version Information:"); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Java virtual machine version: %ls", |
| versionInfo.VMversion ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Access Bridge Java class version: %ls", |
| versionInfo.bridgeJavaClassVersion ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Access Bridge Java DLL version: %ls", |
| versionInfo.bridgeJavaDLLVersion ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Access Bridge Windows DLL version: %ls", |
| versionInfo.bridgeWinDLLVersion ); |
| } |
| |
| if (ac == (AccessibleContext) 0) { |
| return buffer; |
| } |
| |
| |
| /* ===== core AccessibleContext information ===== */ |
| |
| AccessibleContextInfo info; |
| if (GetAccessibleContextInfo(vmID, ac, &info) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed ", bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleContext information", bufsize ); |
| if (x >= 0 && y >= 0) { |
| appendToBuffer(buffer, bufsize, " at mouse point [%d, %d]:", x, y); |
| } else { |
| appendToBuffer(buffer, bufsize, ":", bufsize); |
| } |
| |
| appendToBuffer(buffer, bufsize, "\r\n Name: %ls", info.name); |
| if ( getVirtualAccessibleName( vmID, ac, name, |
| (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", bufsize ); |
| } else { |
| appendToBuffer(buffer, bufsize, "\r\n Virtual Name: %ls", name); |
| } |
| appendToBuffer( buffer, bufsize, "\r\n Description: %ls", |
| info.description ); |
| appendToBuffer(buffer, bufsize, "\r\n Role: %ls", info.role); |
| appendToBuffer( buffer, bufsize, "\r\n Role in en_US locale: %ls", |
| info.role_en_US ); |
| appendToBuffer(buffer, bufsize, "\r\n States: %ls", info.states); |
| appendToBuffer( buffer, bufsize, "\r\n States in en_US locale: %ls", |
| info.states_en_US ); |
| appendToBuffer( buffer, bufsize, "\r\n Index in parent: %d", |
| info.indexInParent ); |
| appendToBuffer( buffer, bufsize, "\r\n Children count: %d", |
| info.childrenCount ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Bounding rectangle: [%d, %d, %d, %d]", |
| info.x, info.y, info.x + info.width, |
| info.y + info.height ); |
| |
| /* top-level window info */ |
| AccessibleContext topAC = getTopLevelObject(vmID, ac); |
| if (topAC == NULL) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: getTopLevelObject failed", bufsize ); |
| } else { |
| AccessibleContextInfo topInfo; |
| if (GetAccessibleContextInfo(vmID, topAC, &topInfo) == FALSE) { |
| appendToBuffer( |
| buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed for top-level window ", |
| bufsize ); |
| } else { |
| if (getVirtualAccessibleName(vmID, topAC, name, |
| (sizeof(name) / sizeof(wchar_t)) ) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Top-level window name: %ls", |
| name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Top-level window role: %ls", |
| topInfo.role ) ; |
| } |
| ReleaseJavaObject(vmID, topAC); |
| |
| } |
| |
| /* ===== AccessibleParent information ===== */ |
| |
| AccessibleContext parentAC = GetAccessibleParentFromContext(vmID, ac); |
| if (parentAC == NULL) { |
| appendToBuffer(buffer, bufsize, "\r\n No parent", bufsize); |
| } else { |
| AccessibleContextInfo parentInfo; |
| if (GetAccessibleContextInfo(vmID, parentAC, &parentInfo) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed for parent", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, "\r\n Parent name: %ls", |
| parentInfo.name ); |
| if ( getVirtualAccessibleName( vmID, parentAC, name, |
| (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Parent virtual name: %ls", name ); |
| } |
| appendToBuffer( buffer, bufsize, "\r\n Parent role: %ls", |
| parentInfo.role ); |
| } |
| ReleaseJavaObject(vmID, parentAC); |
| } |
| |
| |
| /* ====== visible children ===== */ |
| int nChildren = getVisibleChildrenCount(vmID, ac); |
| if (nChildren == -1) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetVisibleChildrenCount failed", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Visible descendents count: %d", |
| nChildren ); |
| } |
| |
| if (nChildren > 0) { |
| VisibleChildrenInfo visibleChildrenInfo; |
| if (getVisibleChildren(vmID, ac, 0, &visibleChildrenInfo) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetVisibleChildren failed", |
| bufsize ); |
| } else { |
| AccessibleContextInfo childACInfo; |
| for ( int child = 0; |
| child < visibleChildrenInfo.returnedChildrenCount; |
| child++ ) { |
| AccessibleContext childAC = |
| visibleChildrenInfo.children[child]; |
| if (GetAccessibleContextInfo(vmID, childAC, &childACInfo)) { |
| if ( getVirtualAccessibleName( vmID, childAC, name, |
| (sizeof(name) / sizeof(wchar_t))) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Descendent %d name: %ls", child, |
| name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Descendent %d role: %ls", |
| child, childACInfo.role ); |
| } |
| ReleaseJavaObject(vmID, childAC); |
| } |
| } |
| } |
| |
| /* ===== AccessibleSelection ===== */ |
| |
| if (info.accessibleSelection == TRUE) { |
| |
| int selCount; |
| AccessibleContext selectedAC; |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessible Selection information:", |
| bufsize ); |
| |
| if ((selCount = GetAccessibleSelectionCountFromContext(vmID, ac)) != -1) { |
| appendToBuffer( buffer, bufsize, "\r\n Selection count: %d", |
| selCount ); |
| |
| for (i = 0; i < selCount; i++) { |
| if ( ( selectedAC = |
| GetAccessibleSelectionFromContext(vmID, ac, i) ) == NULL ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleSelectionFromContext failed forselection %d", |
| i ); |
| } else { |
| if (GetAccessibleContextInfo(vmID, selectedAC, &info) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed for selection %d", i); |
| } else { |
| if ( getVirtualAccessibleName( vmID, selectedAC, name, |
| (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Selection %d name: %ls", i, name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Selection %d role: %ls", i, info.role); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Index in parent of selection %d: %d", |
| i, info.indexInParent ); |
| } |
| ReleaseJavaObject(vmID, selectedAC); |
| } |
| } |
| } |
| } |
| |
| // ====== Accessible KeyBindings, Icons and Actions ====== |
| |
| AccessibleKeyBindings keyBindings; |
| if (getAccessibleKeyBindings(vmID, ac, &keyBindings) == TRUE && |
| keyBindings.keyBindingsCount > 0) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleKeyBinding info:", bufsize ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Number of key bindings: %d", |
| keyBindings.keyBindingsCount ); |
| |
| for (j = 0; j < keyBindings.keyBindingsCount; j++) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Key binding %d character: %c", j, |
| keyBindings.keyBindingInfo[j].character ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Key binding %d modifiers: %d", j, |
| keyBindings.keyBindingInfo[j].modifiers ); |
| } |
| } |
| |
| AccessibleIcons icons; |
| if (getAccessibleIcons(vmID, ac, &icons) == TRUE && |
| icons.iconsCount > 0) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleIcons info:", bufsize ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Number of icons: %d", icons.iconsCount ); |
| |
| for (j = 0; j < icons.iconsCount; j++) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Icon %d description: %ls", j, |
| icons.iconInfo[j].description ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Icon %d height: %d", j, |
| icons.iconInfo[j].height ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Icon %d width: %d", j, |
| icons.iconInfo[j].width ); |
| } |
| } |
| |
| AccessibleActions actions; |
| if (getAccessibleActions(vmID, ac, &actions) == TRUE && |
| actions.actionsCount > 0) { |
| |
| appendToBuffer( buffer, bufsize, "\r\n\r\nAccessibleActions info:", |
| bufsize ); |
| appendToBuffer( buffer, bufsize, "\r\n Number of actions: %d", |
| actions.actionsCount ); |
| |
| for (j = 0; j < actions.actionsCount; j++) { |
| appendToBuffer( buffer, bufsize, "\r\n Action %d name: %ls", |
| j, actions.actionInfo[j].name ); |
| } |
| } |
| |
| /* ===== AccessibleRelationSet ===== */ |
| |
| AccessibleRelationSetInfo relationSetInfo; |
| if (getAccessibleRelationSet(vmID, ac, &relationSetInfo) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nGetAccessibleRelationSet failed.", bufsize ); |
| } else { |
| int i; |
| AccessibleContextInfo relInfo; |
| |
| if (relationSetInfo.relationCount > 0) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleRelationSet information:", |
| bufsize ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Number of relations: %d", |
| relationSetInfo.relationCount ); |
| } |
| for (i = 0; i < relationSetInfo.relationCount; i++) { |
| AccessibleRelationInfo relationInfo = |
| relationSetInfo.relations[i]; |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Relation %d key: %ls", i, |
| relationInfo.key ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Relation %d target count: %d", i, |
| relationInfo.targetCount ); |
| for (j = 0; j < relationInfo.targetCount; j++) { |
| if (GetAccessibleContextInfo( |
| vmID, relationInfo.targets[j], &relInfo ) == FALSE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed.", |
| bufsize ); |
| } else { |
| // Core AccessibleContext information for relation target |
| if ( getVirtualAccessibleName( vmID, relationInfo.targets[j], |
| name, (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Target %d name: %ls", |
| j, name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Target %d role: %ls", j, |
| relInfo.role); |
| } |
| ReleaseJavaObject(vmID, relationInfo.targets[j]); |
| |
| } |
| } |
| } |
| |
| /* ===== AccessibleValue ===== */ |
| |
| if (info.accessibleInterfaces & cAccessibleValueInterface) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessible Value information:", bufsize); |
| |
| if ( GetCurrentAccessibleValueFromContext( vmID, ac, tmpBuf, |
| (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) { |
| appendToBuffer( buffer, bufsize, "\r\n Current Value: %ls", |
| tmpBuf ); |
| } |
| if ( GetMaximumAccessibleValueFromContext( vmID, ac, tmpBuf, |
| (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Maximum Value: %ls", tmpBuf ); |
| } |
| if ( GetMinimumAccessibleValueFromContext( vmID, ac, tmpBuf, |
| (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Minimum Value: %ls", tmpBuf ); |
| } |
| } |
| |
| |
| /* ===== AccessibleTable ===== */ |
| |
| AccessibleTableInfo tableInfo; |
| |
| if ( (info.accessibleInterfaces & cAccessibleTableInterface) == |
| cAccessibleTableInterface ) { |
| if (getAccessibleTableInfo(vmID, ac, &tableInfo) != TRUE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: getAccessibleTableInfo failed", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleTable info:", bufsize ); |
| |
| int trow = getAccessibleTableRow( vmID, |
| tableInfo.accessibleTable, 3 ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n getAccessibleTableRow: %d", trow); |
| |
| int tcol = |
| getAccessibleTableColumn(vmID, tableInfo.accessibleTable, 2); |
| appendToBuffer( buffer, bufsize, |
| "\r\n getAccessibleTableColumn: %d", tcol ); |
| |
| int tindex = getAccessibleTableIndex( vmID, |
| tableInfo.accessibleTable, |
| 2, 3 ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n getAccessibleTableIndex: %d", |
| tindex ); |
| |
| // Core info |
| appendToBuffer( buffer, bufsize, |
| "\r\n table row count: %d", |
| tableInfo.rowCount ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n table column count: %d", |
| tableInfo.columnCount ); |
| |
| AccessibleTableCellInfo tableCellInfo; |
| for (int i = 0; i < tableInfo.rowCount; i++) { |
| for (int j = 0; j < tableInfo.columnCount; j++) { |
| |
| if ( !getAccessibleTableCellInfo( vmID, |
| tableInfo.accessibleTable, |
| i, j, |
| &tableCellInfo ) ) { |
| |
| appendToBuffer( |
| buffer, bufsize, |
| "\r\nERROR: GetAccessibleTableCellInfo failed.", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\n AccessibleTable cell[%d,%d] info:", |
| i, j ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Index: %ld", tableCellInfo.index ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Row extent: %ld", |
| tableCellInfo.rowExtent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Column extent: %ld", |
| tableCellInfo.columnExtent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Is selected?: %ld", |
| tableCellInfo.isSelected ); |
| |
| AccessibleContextInfo cellACInfo; |
| if ( !GetAccessibleContextInfo( |
| vmID, |
| tableCellInfo.accessibleContext, |
| &cellACInfo ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed for table cell [%d,%d].", |
| i, j ); |
| } else { |
| if ( !getVirtualAccessibleName( vmID, |
| tableCellInfo.accessibleContext, name, |
| (sizeof(name) / sizeof(wchar_t)) ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Name: %ls", name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Role: %ls", |
| cellACInfo.role ); |
| } |
| ReleaseJavaObject( vmID, |
| tableCellInfo.accessibleContext ); |
| } |
| } |
| } |
| |
| // Get the column headers |
| AccessibleTableInfo columnInfo; |
| if ( !getAccessibleTableColumnHeader(vmID, ac, &columnInfo)) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: getAccessibleTableColumnHeader failed.", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessibleTable column header info:", bufsize ); |
| |
| // Core info |
| appendToBuffer( buffer, bufsize, |
| "\r\n Column header row count: %d", |
| columnInfo.rowCount ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Column header column count: %d", |
| columnInfo.columnCount ); |
| |
| } |
| |
| // Get the selected rows |
| int numSelections = |
| getAccessibleTableRowSelectionCount( vmID, |
| tableInfo.accessibleTable ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nRow selection count: %d", |
| numSelections ); |
| jint *selections = new jint[numSelections]; |
| |
| if ( !getAccessibleTableRowSelections( vmID, |
| tableInfo.accessibleTable, |
| numSelections, |
| selections ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: getAccessibleTableRowSelections failed.", |
| bufsize ); |
| } else { |
| appendToBuffer(buffer, bufsize, " \r\n Row selections: "); |
| for (int j = 0; j < numSelections; j++) { |
| appendToBuffer(buffer, bufsize, " %d", selections[j]); |
| } |
| } |
| |
| // Get column header info |
| for (int i = 0; i < columnInfo.columnCount; i++) { |
| if ( !getAccessibleTableCellInfo( vmID, |
| columnInfo.accessibleTable, |
| 0, i, &tableCellInfo ) ) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleTableCellInfo failed.", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nColumn header [0,%d] cell info.", i ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Index: %ld", tableCellInfo.index ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Row extent: %ld", |
| tableCellInfo.rowExtent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Column extent: %ld", |
| tableCellInfo.columnExtent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Is selected: %ld", |
| tableCellInfo.isSelected ); |
| |
| AccessibleContextInfo cellACInfo; |
| if ( !GetAccessibleContextInfo( vmID, |
| tableCellInfo.accessibleContext, &cellACInfo ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\nERROR: GetAccessibleContextInfo failed.", |
| bufsize ); |
| } else { |
| if ( !getVirtualAccessibleName( vmID, |
| tableCellInfo.accessibleContext, name, |
| (sizeof(name) / sizeof(wchar_t)) ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nERROR: getVirtualAccessibleName", |
| bufsize ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Name: %ls", name ); |
| } |
| appendToBuffer( buffer, bufsize, |
| "\r\n Role: %ls", cellACInfo.role ); |
| } |
| ReleaseJavaObject(vmID, tableCellInfo.accessibleContext); |
| } |
| } |
| } |
| } |
| |
| /* ===== AccessibleText ===== */ |
| |
| if (info.accessibleText == TRUE) { |
| AccessibleTextInfo textInfo; |
| AccessibleTextItemsInfo textItems; |
| AccessibleTextSelectionInfo textSelection; |
| AccessibleTextRectInfo rectInfo; |
| AccessibleTextAttributesInfo attributeInfo; |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\nAccessible Text information:", bufsize); |
| |
| if (GetAccessibleTextInfo(vmID, ac, &textInfo, x, y) == TRUE) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Mouse point at text index: %d", |
| textInfo.indexAtPoint ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Caret at text index: %d", |
| textInfo.caretIndex ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Char count: %d", |
| textInfo.charCount ); |
| } |
| if ( GetAccessibleTextSelectionInfo(vmID, ac, &textSelection) ) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Selection start index: %d", |
| textSelection.selectionStartIndex ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Selection end index: %d", |
| textSelection.selectionEndIndex ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Selected text: %ls", |
| textSelection.selectedText ); |
| } |
| |
| /* ===== AccessibleText information at the mouse point ===== */ |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\n At mouse point index: %d", textInfo.indexAtPoint); |
| |
| if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.indexAtPoint)) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Character bounding rectangle: [%d, %d, %d, %d]", |
| rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); |
| } |
| |
| if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.indexAtPoint, |
| &start, &end ) ) { |
| if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf, |
| (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Line bounds: [%d, %d]", start, end); |
| } |
| } |
| if ( GetAccessibleTextItems( vmID, ac, &textItems, |
| textInfo.indexAtPoint ) ) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Character: %lc", textItems.letter ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Word: %ls", textItems.word ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Sentence: %ls", textItems.sentence ); |
| } |
| |
| /* ===== AccessibleText attributes ===== */ |
| |
| if (GetAccessibleTextAttributes(vmID, ac, |
| textInfo.indexAtPoint, |
| &attributeInfo)) { |
| |
| appendToBuffer( buffer, bufsize, "\r\n Core attributes: %s", |
| attributeInfo.bold ? "bold" : "not bold" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.italic ? "italic" : "not italic" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.underline ? "underline" : "not underline" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.strikethrough ? "strikethrough" : |
| "not strikethrough" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.superscript ? "superscript" : |
| "not superscript" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.subscript ? "subscript" : "not subscript" ); |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Background color: %ls", |
| attributeInfo.backgroundColor ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Foreground color: %ls", |
| attributeInfo.foregroundColor ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Font family: %ls", |
| attributeInfo.fontFamily ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Font size: %d", |
| attributeInfo.fontSize ); |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n First line indent: %f", |
| attributeInfo.firstLineIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Left indent: %f", |
| attributeInfo.leftIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Right indent: %f", |
| attributeInfo.rightIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Line spacing: %f", |
| attributeInfo.lineSpacing ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Space above: %f", |
| attributeInfo.spaceAbove ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Space below: %f", |
| attributeInfo.spaceBelow ); |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Full attribute string: %ls", |
| attributeInfo.fullAttributesString ); |
| |
| // get the attribute run length |
| short runLength = -1; |
| if ( getTextAttributesInRange( vmID, ac, textInfo.indexAtPoint, |
| textInfo.indexAtPoint + 100, |
| &attributeInfo, &runLength ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Attribute run: %d", runLength ); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n getTextAttributesInRangeFailed" ); |
| } |
| } |
| |
| /* ===== AccessibleText information at the caret index ===== */ |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n\r\n At caret index: %d", textInfo.caretIndex); |
| |
| if (getCaretLocation(vmID, ac, &rectInfo, textInfo.caretIndex)) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Caret bounding rectangle: [%d, %d, %d, %d]", |
| rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); |
| } |
| |
| if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.caretIndex)) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Character bounding rectangle: [%d, %d, %d, %d]", |
| rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); |
| } |
| |
| if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.caretIndex, |
| &start, &end ) ) { |
| if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf, |
| (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Line bounds: [%d, %d]", start, end); |
| } |
| } |
| if (GetAccessibleTextItems(vmID, ac, &textItems, textInfo.caretIndex)) { |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Character: %lc", textItems.letter ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Word: %ls", textItems.word ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Sentence: %ls", textItems.sentence ); |
| } |
| |
| /* ===== AccessibleText attributes ===== */ |
| |
| if (GetAccessibleTextAttributes(vmID, ac, textInfo.caretIndex, &attributeInfo)) { |
| |
| appendToBuffer( buffer, bufsize, "\r\n Core attributes: %s", |
| attributeInfo.bold ? "bold" : "not bold" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.italic ? "italic" : "not italic" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.underline ? "underline" : "not underline" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.strikethrough ? "strikethrough" : |
| "not strikethrough" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.superscript ? "superscript" : |
| "not superscript" ); |
| appendToBuffer( buffer, bufsize, ", %s", |
| attributeInfo.subscript ? "subscript" : "not subscript"); |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n Background color: %ls", |
| attributeInfo.backgroundColor ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Foreground color: %ls", |
| attributeInfo.foregroundColor ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Font family: %ls", attributeInfo.fontFamily ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Font size: %d", attributeInfo.fontSize); |
| |
| |
| appendToBuffer( buffer, bufsize, |
| "\r\n First line indent: %f", |
| attributeInfo.firstLineIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Left indent: %f", attributeInfo.leftIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Right indent: %f", attributeInfo.rightIndent ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Line spacing: %f", attributeInfo.lineSpacing ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Space above: %f", attributeInfo.spaceAbove ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Space below: %f", attributeInfo.spaceBelow ); |
| appendToBuffer( buffer, bufsize, |
| "\r\n Full attribute string: %ls", |
| attributeInfo.fullAttributesString ); |
| // get the attribute run length |
| short runLength = -1; |
| if ( getTextAttributesInRange( vmID, ac, textInfo.caretIndex, |
| textInfo.caretIndex + 100, |
| &attributeInfo, &runLength ) ) { |
| appendToBuffer( buffer, bufsize, |
| "\r\n Attribute run: %d", runLength); |
| } else { |
| appendToBuffer( buffer, bufsize, |
| "\r\n getTextAttributesInRangeFailed" ); |
| } |
| } |
| } |
| } |
| return buffer; |
| } |