1 /* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "AccessBridgeCalls.h" 27 #include "AccessInfo.h" 28 #include <stdio.h> 29 #include <time.h> 30 31 /* 32 * returns formatted date and time 33 */ 34 char *getTimeAndDate() { 35 static char datebuf[64]; 36 struct tm *newtime; 37 char am_pm[] = "AM"; 38 time_t long_time; 39 40 time( &long_time ); /* Get time as long integer. */ 41 newtime = localtime( &long_time ); /* Convert to local time. */ 42 43 if( newtime->tm_hour > 12 ) /* Set up extension. */ 44 strcpy( am_pm, "PM" ); 45 if( newtime->tm_hour > 12 ) /* Convert from 24-hour */ 46 newtime->tm_hour -= 12; /* to 12-hour clock. */ 47 if( newtime->tm_hour == 0 ) /*Set hour to 12 if midnight. */ 48 newtime->tm_hour = 12; 49 50 sprintf(datebuf, "%.19s %s\n", asctime( newtime ), am_pm ); 51 return (char *)datebuf; 52 } 53 54 55 /* 56 * displays a message in a dialog and writes the message to a logfile 57 */ 58 void displayAndLog(HWND hDlg, int nIDDlgItem, FILE *logfile, char *msg, ...) { 59 60 if (hDlg == NULL || msg == NULL) { 61 return; 62 } 63 64 char tmpbuf[HUGE_BUFSIZE]; 65 va_list argprt; 66 67 va_start(argprt, msg); 68 vsprintf(tmpbuf, msg, argprt); 69 70 SetDlgItemText(hDlg, nIDDlgItem, tmpbuf); 71 72 fprintf(logfile, "\n****************************************\n"); 73 fprintf(logfile, "%s\n", getTimeAndDate()); 74 fprintf(logfile, "%s\n", tmpbuf); 75 fflush(logfile); 76 } 77 78 /* 79 * writes a text string to a logfile 80 */ 81 void logString(FILE *logfile, char *msg, ...) { 82 83 if (logfile == NULL || msg == NULL) { 84 return; 85 } 86 87 char tmpbuf[LINE_BUFSIZE]; 88 va_list argprt; 89 90 va_start(argprt, msg); 91 vsprintf(tmpbuf, msg, argprt); 92 93 fprintf(logfile, tmpbuf); 94 fprintf(logfile, "\n"); 95 fflush(logfile); 96 } 97 98 /* 99 * safely appends a message to a buffer 100 */ 101 BOOL appendToBuffer(char *buf, size_t buflen, char *msg, ...) { 102 103 static char warning[] = 104 "\nNot enough buffer space; remaining information truncated.\n"; 105 int warningLength = (int)strlen(warning) + 1; 106 107 if (buf == NULL || msg == NULL) { 108 return FALSE; 109 } 110 111 char tmpbuf[LARGE_BUFSIZE]; 112 va_list argprt; 113 114 va_start(argprt, msg); 115 vsprintf(tmpbuf, msg, argprt); 116 117 // verify there's enough space in the buffer 118 int spaceRemaining = buflen - (int)strlen(buf) - 1; 119 if (spaceRemaining <= warningLength) { 120 strncat(buf, warning, spaceRemaining); 121 return FALSE; 122 } 123 strncat(buf, tmpbuf, spaceRemaining); 124 return TRUE; 125 } 126 127 /** 128 * returns accessibility information for an AccessibleContext 129 */ 130 char *getAccessibleInfo(long vmID, AccessibleContext ac, char *buffer, 131 int bufsize) { 132 return getAccessibleInfo(vmID, ac, 0, 0, buffer, bufsize); 133 } 134 135 /** 136 * returns accessibility information at the specified coordinates in an 137 * AccessibleContext 138 */ 139 char *getAccessibleInfo(long vmID, AccessibleContext ac, int x, int y, 140 char *buffer, int bufsize) { 141 142 wchar_t tmpBuf[LINE_BUFSIZE]; 143 wchar_t name[LINE_BUFSIZE]; 144 int i, j; 145 long start; 146 long end; 147 148 if (buffer == NULL || bufsize <= 0) { 149 return NULL; 150 } 151 buffer[0] = NULL; 152 153 /* ===== AccessBridge / J2SE version information ===== */ 154 155 AccessBridgeVersionInfo versionInfo; 156 BOOL result = GetVersionInfo(vmID, &versionInfo); 157 158 if (result == FALSE) { 159 appendToBuffer(buffer, bufsize, "\r\nERROR: cannot get version information", bufsize); 160 } else { 161 appendToBuffer(buffer, bufsize, "Version Information:"); 162 appendToBuffer(buffer, bufsize, "\r\n Java virtual machine version: %ls", 163 versionInfo.VMversion); 164 appendToBuffer(buffer, bufsize, "\r\n Access Bridge Java class version: %ls", 165 versionInfo.bridgeJavaClassVersion); 166 appendToBuffer(buffer, bufsize, "\r\n Access Bridge Java DLL version: %ls", 167 versionInfo.bridgeJavaDLLVersion); 168 appendToBuffer(buffer, bufsize, "\r\n Access Bridge Windows DLL version: %ls", 169 versionInfo.bridgeWinDLLVersion); 170 } 171 172 if (ac == (AccessibleContext) 0) { 173 return buffer; 174 } 175 176 177 /* ===== core AccessibleContext information ===== */ 178 179 AccessibleContextInfo info; 180 if (GetAccessibleContextInfo(vmID, ac, &info) == FALSE) { 181 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed ", bufsize); 182 } else { 183 184 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleContext information", bufsize); 185 if (x >= 0 && y >= 0) { 186 appendToBuffer(buffer, bufsize, " at mouse point [%d, %d]:", x, y); 187 } else { 188 appendToBuffer(buffer, bufsize, ":", bufsize); 189 } 190 191 if (getVirtualAccessibleName(vmID, ac, name, sizeof(name)) == FALSE) { 192 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 193 } else { 194 appendToBuffer(buffer, bufsize, "\r\n Name: %ls", name); 195 } 196 appendToBuffer(buffer, bufsize, "\r\n Description: %ls", info.description); 197 appendToBuffer(buffer, bufsize, "\r\n Role: %ls", info.role); 198 appendToBuffer(buffer, bufsize, "\r\n Role in en_US locale: %ls", info.role_en_US); 199 appendToBuffer(buffer, bufsize, "\r\n States: %ls", info.states); 200 appendToBuffer(buffer, bufsize, "\r\n States in en_US locale: %ls", info.states_en_US); 201 appendToBuffer(buffer, bufsize, "\r\n Index in parent: %d", info.indexInParent); 202 appendToBuffer(buffer, bufsize, "\r\n Children count: %d", info.childrenCount); 203 appendToBuffer(buffer, bufsize, "\r\n Bounding rectangle: [%d, %d, %d, %d]", 204 info.x, info.y, info.x + info.width, info.y + info.height); 205 206 /* top-level window info */ 207 AccessibleContext topAC = getTopLevelObject(vmID, ac); 208 if (topAC == NULL) { 209 appendToBuffer(buffer, bufsize, "\r\nERROR: getTopLevelObject failed", bufsize); 210 } else { 211 AccessibleContextInfo topInfo; 212 if (GetAccessibleContextInfo(vmID, topAC, &topInfo) == FALSE) { 213 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed for top-level window ", bufsize); 214 } else { 215 if (getVirtualAccessibleName(vmID, topAC, name, sizeof(name)) == FALSE) { 216 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 217 } else { 218 appendToBuffer(buffer, bufsize, "\r\n Top-level window name: %ls", name); 219 } 220 appendToBuffer(buffer, bufsize, "\r\n Top-level window role: %ls", topInfo.role); 221 } 222 ReleaseJavaObject(vmID, topAC); 223 224 } 225 226 /* ===== AccessibleParent information ===== */ 227 228 AccessibleContext parentAC = GetAccessibleParentFromContext(vmID, ac); 229 if (parentAC == NULL) { 230 appendToBuffer(buffer, bufsize, "\r\n No parent", bufsize); 231 } else { 232 AccessibleContextInfo parentInfo; 233 if (GetAccessibleContextInfo(vmID, parentAC, &parentInfo) == FALSE) { 234 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed for parent", bufsize); 235 } else { 236 if (getVirtualAccessibleName(vmID, parentAC, name, sizeof(name)) == FALSE) { 237 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 238 } else { 239 appendToBuffer(buffer, bufsize, "\r\n Parent name: %ls", name); 240 } 241 appendToBuffer(buffer, bufsize, "\r\n Parent role: %ls", parentInfo.role); 242 } 243 ReleaseJavaObject(vmID, parentAC); 244 } 245 246 247 /* ====== visible children ===== */ 248 int nChildren = getVisibleChildrenCount(vmID, ac); 249 if (nChildren == -1) { 250 appendToBuffer(buffer, bufsize, "\r\nERROR: GetVisibleChildrenCount failed", bufsize); 251 } else { 252 appendToBuffer(buffer, bufsize, "\r\n Visible descendents count: %d", nChildren); 253 } 254 255 if (nChildren > 0) { 256 VisibleChildrenInfo visibleChildrenInfo; 257 if (getVisibleChildren(vmID, ac, 0, &visibleChildrenInfo) == FALSE) { 258 appendToBuffer(buffer, bufsize, "\r\nERROR: GetVisibleChildren failed", bufsize); 259 } else { 260 AccessibleContextInfo childACInfo; 261 for (int child = 0; child < visibleChildrenInfo.returnedChildrenCount; child++) { 262 AccessibleContext childAC = visibleChildrenInfo.children[child]; 263 if (GetAccessibleContextInfo(vmID, childAC, &childACInfo) == TRUE) { 264 if (getVirtualAccessibleName(vmID, childAC, name, sizeof(name)) == FALSE) { 265 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 266 } else { 267 appendToBuffer(buffer, bufsize, "\r\n Descendent %d name: %ls", child, name); 268 } 269 appendToBuffer(buffer, bufsize, "\r\n Descendent %d role: %ls", child, childACInfo.role); 270 } 271 ReleaseJavaObject(vmID, childAC); 272 } 273 } 274 } 275 276 /* ===== AccessibleSelection ===== */ 277 278 if (info.accessibleSelection == TRUE) { 279 280 int selCount; 281 AccessibleContext selectedAC; 282 283 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessible Selection information:", bufsize); 284 285 if ((selCount = GetAccessibleSelectionCountFromContext(vmID, ac)) != -1) { 286 appendToBuffer(buffer, bufsize, "\r\n Selection count: %d", selCount); 287 288 for (i = 0; i < selCount; i++) { 289 if ((selectedAC = GetAccessibleSelectionFromContext(vmID, ac, i)) == NULL) { 290 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleSelectionFromContext failed forselection %d", i); 291 } else { 292 if (GetAccessibleContextInfo(vmID, selectedAC, &info) == FALSE) { 293 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed for selection %d", i); 294 } else { 295 if (getVirtualAccessibleName(vmID, selectedAC, name, sizeof(name)) == FALSE) { 296 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 297 } else { 298 appendToBuffer(buffer, bufsize, "\r\n Selection %d name: %ls", i, name); 299 } 300 appendToBuffer(buffer, bufsize, "\r\n Selection %d role: %ls", i, info.role); 301 appendToBuffer(buffer, bufsize, "\r\n Index in parent of selection %d: %d", i, info.indexInParent); 302 } 303 ReleaseJavaObject(vmID, selectedAC); 304 } 305 } 306 } 307 } 308 309 // ====== Accessible KeyBindings, Icons and Actions ====== 310 311 AccessibleKeyBindings keyBindings; 312 if (getAccessibleKeyBindings(vmID, ac, &keyBindings) == TRUE && 313 keyBindings.keyBindingsCount > 0) { 314 315 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleKeyBinding info:", bufsize); 316 appendToBuffer(buffer, bufsize, "\r\n Number of key bindings: %d", keyBindings.keyBindingsCount); 317 318 for (j = 0; j < keyBindings.keyBindingsCount; j++) { 319 320 appendToBuffer(buffer, bufsize, "\r\n Key binding %d character: %c", j, keyBindings.keyBindingInfo[j].character); 321 appendToBuffer(buffer, bufsize, "\r\n Key binding %d modifiers: %d", j, keyBindings.keyBindingInfo[j].modifiers); 322 } 323 } 324 325 AccessibleIcons icons; 326 if (getAccessibleIcons(vmID, ac, &icons) == TRUE && 327 icons.iconsCount > 0) { 328 329 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleIcons info:", bufsize); 330 appendToBuffer(buffer, bufsize, "\r\n Number of icons: %d", icons.iconsCount); 331 332 for (j = 0; j < icons.iconsCount; j++) { 333 334 appendToBuffer(buffer, bufsize, "\r\n Icon %d description: %ls", j, icons.iconInfo[j].description); 335 appendToBuffer(buffer, bufsize, "\r\n Icon %d height: %d", j, icons.iconInfo[j].height); 336 appendToBuffer(buffer, bufsize, "\r\n Icon %d width: %d", j, icons.iconInfo[j].width); 337 } 338 } 339 340 AccessibleActions actions; 341 if (getAccessibleActions(vmID, ac, &actions) == TRUE && 342 actions.actionsCount > 0) { 343 344 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleActions info:", bufsize); 345 appendToBuffer(buffer, bufsize, "\r\n Number of actions: %d", actions.actionsCount); 346 347 for (j = 0; j < actions.actionsCount; j++) { 348 349 appendToBuffer(buffer, bufsize, "\r\n Action %d name: %ls", j, actions.actionInfo[j].name); 350 } 351 } 352 353 /* ===== AccessibleRelationSet ===== */ 354 355 AccessibleRelationSetInfo relationSetInfo; 356 if (getAccessibleRelationSet(vmID, ac, &relationSetInfo) == FALSE) { 357 appendToBuffer(buffer, bufsize, "\r\nGetAccessibleRelationSet failed.", bufsize); 358 } else { 359 int i; 360 AccessibleContextInfo relInfo; 361 362 if (relationSetInfo.relationCount > 0) { 363 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleRelationSet information:", bufsize); 364 appendToBuffer(buffer, bufsize, "\r\n Number of relations: %d", relationSetInfo.relationCount); 365 } 366 for (i = 0; i < relationSetInfo.relationCount; i++) { 367 AccessibleRelationInfo relationInfo = relationSetInfo.relations[i]; 368 369 appendToBuffer(buffer, bufsize, "\r\n Relation %d key: %ls", i, relationInfo.key); 370 appendToBuffer(buffer, bufsize, "\r\n Relation %d target count: %d", i, relationInfo.targetCount); 371 for (j = 0; j < relationInfo.targetCount; j++) { 372 if (GetAccessibleContextInfo(vmID, (AccessibleContext)relationInfo.targets[j], &relInfo) == FALSE) { 373 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed.", bufsize); 374 } else { 375 376 // Core AccessibleContext information for relation target 377 if (getVirtualAccessibleName(vmID, (AccessibleContext)relationInfo.targets[j], name, 378 sizeof(name)) == FALSE) { 379 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 380 } else { 381 appendToBuffer(buffer, bufsize, "\r\n Target %d name: %ls", j, name); 382 } 383 appendToBuffer(buffer, bufsize, "\r\n Target %d role: %ls", j, relInfo.role); 384 } 385 ReleaseJavaObject(vmID, (Java_Object)relationInfo.targets[j]); 386 387 } 388 } 389 } 390 391 /* ===== AccessibleValue ===== */ 392 393 if (info.accessibleInterfaces & cAccessibleValueInterface) { 394 395 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessible Value information:", bufsize); 396 397 if (GetCurrentAccessibleValueFromContext(vmID, ac, tmpBuf, (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE) { 398 appendToBuffer(buffer, bufsize, "\r\n Current Value: %ls", tmpBuf); 399 } 400 if (GetMaximumAccessibleValueFromContext(vmID, ac, tmpBuf, (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE) { 401 appendToBuffer(buffer, bufsize, "\r\n Maximum Value: %ls", tmpBuf); 402 } 403 if (GetMinimumAccessibleValueFromContext(vmID, ac, tmpBuf, (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE) { 404 appendToBuffer(buffer, bufsize, "\r\n Minimum Value: %ls", tmpBuf); 405 } 406 } 407 408 409 /* ===== AccessibleTable ===== */ 410 411 AccessibleTableInfo tableInfo; 412 413 if ((info.accessibleInterfaces & cAccessibleTableInterface) == cAccessibleTableInterface) { 414 if (getAccessibleTableInfo(vmID, ac, &tableInfo) != TRUE) { 415 appendToBuffer(buffer, bufsize, "\r\nERROR: getAccessibleTableInfo failed", bufsize); 416 } else { 417 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleTable info:", bufsize); 418 419 int trow = getAccessibleTableRow(vmID, tableInfo.accessibleTable, 3); 420 appendToBuffer(buffer, bufsize, "\r\n getAccessibleTableRow: %d", trow); 421 422 int tcol = getAccessibleTableColumn(vmID, tableInfo.accessibleTable, 2); 423 appendToBuffer(buffer, bufsize, "\r\n getAccessibleTableColumn: %d", tcol); 424 425 int tindex = getAccessibleTableIndex(vmID, tableInfo.accessibleTable, 2, 3); 426 appendToBuffer(buffer, bufsize, "\r\n getAccessibleTableIndex: %d", tindex); 427 428 // Core info 429 appendToBuffer(buffer, bufsize, "\r\n table row count: %d", tableInfo.rowCount); 430 appendToBuffer(buffer, bufsize, "\r\n table column count: %d", tableInfo.columnCount); 431 432 AccessibleTableCellInfo tableCellInfo; 433 for (int i = 0; i < tableInfo.rowCount; i++) { 434 for (int j = 0; j < tableInfo.columnCount; j++) { 435 436 if (getAccessibleTableCellInfo(vmID, tableInfo.accessibleTable, i, j, 437 &tableCellInfo) == FALSE) { 438 439 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleTableCellInfo failed.", bufsize); 440 } else { 441 442 appendToBuffer(buffer, bufsize, "\r\n\r\n AccessibleTable cell[%d,%d] info:", i, j); 443 appendToBuffer(buffer, bufsize, "\r\n Index: %ld", tableCellInfo.index); 444 appendToBuffer(buffer, bufsize, "\r\n Row extent: %ld", tableCellInfo.rowExtent); 445 appendToBuffer(buffer, bufsize, "\r\n Column extent: %ld", tableCellInfo.columnExtent); 446 appendToBuffer(buffer, bufsize, "\r\n Is selected?: %ld", tableCellInfo.isSelected); 447 448 AccessibleContextInfo cellACInfo; 449 if (GetAccessibleContextInfo(vmID, tableCellInfo.accessibleContext, &cellACInfo) == FALSE) { 450 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed for table cell [%d,%d].", 451 i, j); 452 } else { 453 if (getVirtualAccessibleName(vmID, tableCellInfo.accessibleContext, name, 454 sizeof(name)) == FALSE) { 455 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 456 } else { 457 appendToBuffer(buffer, bufsize, "\r\n Name: %ls", name); 458 } 459 appendToBuffer(buffer, bufsize, "\r\n Role: %ls", cellACInfo.role); 460 } 461 ReleaseJavaObject(vmID, tableCellInfo.accessibleContext); 462 } 463 } 464 } 465 466 // Get the column headers 467 AccessibleTableInfo columnInfo; 468 if (getAccessibleTableColumnHeader(vmID, ac, &columnInfo) == FALSE) { 469 appendToBuffer(buffer, bufsize, "\r\nERROR: getAccessibleTableColumnHeader failed.", bufsize); 470 } else { 471 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessibleTable column header info:", bufsize); 472 473 // Core info 474 appendToBuffer(buffer, bufsize, "\r\n Column header row count: %d", columnInfo.rowCount); 475 appendToBuffer(buffer, bufsize, "\r\n Column header column count: %d", columnInfo.columnCount); 476 477 } 478 479 // Get the selected rows 480 int numSelections = getAccessibleTableRowSelectionCount(vmID, 481 tableInfo.accessibleTable); 482 appendToBuffer(buffer, bufsize, "\r\n\r\nRow selection count: %d", numSelections); 483 jint *selections = new jint[numSelections]; 484 485 if (getAccessibleTableRowSelections(vmID, tableInfo.accessibleTable, 486 numSelections, selections) == FALSE) { 487 appendToBuffer(buffer, bufsize, "\r\nERROR: getAccessibleTableRowSelections failed.", 488 bufsize); 489 } else { 490 appendToBuffer(buffer, bufsize, " \r\n Row selections: "); 491 for (int j = 0; j < numSelections; j++) { 492 appendToBuffer(buffer, bufsize, " %d", selections[j]); 493 } 494 } 495 496 // Get column header info 497 for (int i = 0; i < columnInfo.columnCount; i++) { 498 if (getAccessibleTableCellInfo(vmID, columnInfo.accessibleTable, 0, i, 499 &tableCellInfo) == FALSE) { 500 501 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleTableCellInfo failed.", bufsize); 502 } else { 503 appendToBuffer(buffer, bufsize, "\r\n\r\nColumn header [0,%d] cell info.", i); 504 appendToBuffer(buffer, bufsize, "\r\n Index: %ld", tableCellInfo.index); 505 appendToBuffer(buffer, bufsize, "\r\n Row extent: %ld", tableCellInfo.rowExtent); 506 appendToBuffer(buffer, bufsize, "\r\n Column extent: %ld", tableCellInfo.columnExtent); 507 appendToBuffer(buffer, bufsize, "\r\n Is selected: %ld", tableCellInfo.isSelected); 508 509 AccessibleContextInfo cellACInfo; 510 if (GetAccessibleContextInfo(vmID, tableCellInfo.accessibleContext, &cellACInfo) == FALSE) { 511 appendToBuffer(buffer, bufsize, "\r\nERROR: GetAccessibleContextInfo failed.", bufsize); 512 } else { 513 if (getVirtualAccessibleName(vmID, tableCellInfo.accessibleContext, name, 514 sizeof(name)) == FALSE) { 515 appendToBuffer(buffer, bufsize, "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 516 } else { 517 appendToBuffer(buffer, bufsize, "\r\n Name: %ls", name); 518 } 519 appendToBuffer(buffer, bufsize, "\r\n Role: %ls", cellACInfo.role); 520 } 521 ReleaseJavaObject(vmID, tableCellInfo.accessibleContext); 522 } 523 } 524 } 525 } 526 527 /* ===== AccessibleText ===== */ 528 529 if (info.accessibleText == TRUE && x >= 0 && y >= 0) { 530 531 AccessibleTextInfo textInfo; 532 AccessibleTextItemsInfo textItems; 533 AccessibleTextSelectionInfo textSelection; 534 AccessibleTextRectInfo rectInfo; 535 AccessibleTextAttributesInfo attributeInfo; 536 537 appendToBuffer(buffer, bufsize, "\r\n\r\nAccessible Text information:", bufsize); 538 539 if (GetAccessibleTextInfo(vmID, ac, &textInfo, x, y) == TRUE) { 540 541 appendToBuffer(buffer, bufsize, "\r\n Mouse point at text index: %d", textInfo.indexAtPoint); 542 appendToBuffer(buffer, bufsize, "\r\n Caret at text index: %d", textInfo.caretIndex); 543 appendToBuffer(buffer, bufsize, "\r\n Char count: %d", textInfo.charCount); 544 } 545 if (GetAccessibleTextSelectionInfo(vmID, ac, &textSelection) == TRUE) { 546 547 appendToBuffer(buffer, bufsize, "\r\n Selection start index: %d", textSelection.selectionStartIndex); 548 appendToBuffer(buffer, bufsize, "\r\n Selection end index: %d", textSelection.selectionEndIndex); 549 appendToBuffer(buffer, bufsize, "\r\n Selected text: %ls", textSelection.selectedText); 550 } 551 552 /* ===== AccessibleText information at the mouse point ===== */ 553 554 appendToBuffer(buffer, bufsize, "\r\n\r\n At mouse point index: %d", textInfo.indexAtPoint); 555 556 if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.indexAtPoint) == TRUE) { 557 558 appendToBuffer(buffer, bufsize, "\r\n Character bounding rectangle: [%d, %d, %d, %d]", 559 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height); 560 } 561 562 if (GetAccessibleTextLineBounds(vmID, ac, textInfo.indexAtPoint, &start, &end) == TRUE) { 563 if (GetAccessibleTextRange(vmID, ac, start, end, tmpBuf, (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE) { 564 565 appendToBuffer(buffer, bufsize, "\r\n Line bounds: [%d, %d]", start, end); 566 } 567 } 568 if (GetAccessibleTextItems(vmID, ac, &textItems, textInfo.indexAtPoint) == TRUE) { 569 570 appendToBuffer(buffer, bufsize, "\r\n Character: %lc", textItems.letter); 571 appendToBuffer(buffer, bufsize, "\r\n Word: %ls", textItems.word); 572 appendToBuffer(buffer, bufsize, "\r\n Sentence: %ls", textItems.sentence); 573 } 574 575 /* ===== AccessibleText attributes ===== */ 576 577 if (GetAccessibleTextAttributes(vmID, ac, 578 textInfo.indexAtPoint, 579 &attributeInfo)) { 580 581 appendToBuffer(buffer, bufsize, "\r\n Core attributes: %s", 582 attributeInfo.bold == TRUE ? "bold" : "not bold"); 583 appendToBuffer(buffer, bufsize, ", %s", 584 attributeInfo.italic == TRUE ? "italic" : "not italic"); 585 appendToBuffer(buffer, bufsize, ", %s", 586 attributeInfo.underline == TRUE ? "underline" : "not underline"); 587 appendToBuffer(buffer, bufsize, ", %s", 588 attributeInfo.strikethrough == TRUE ? "strikethrough" : "not strikethrough"); 589 appendToBuffer(buffer, bufsize, ", %s", 590 attributeInfo.superscript == TRUE ? "superscript" : "not superscript"); 591 appendToBuffer(buffer, bufsize, ", %s", 592 attributeInfo.subscript == TRUE ? "subscript" : "not subscript"); 593 594 appendToBuffer(buffer, bufsize, "\r\n Background color: %ls", attributeInfo.backgroundColor); 595 appendToBuffer(buffer, bufsize, "\r\n Foreground color: %ls", attributeInfo.foregroundColor); 596 appendToBuffer(buffer, bufsize, "\r\n Font family: %ls", attributeInfo.fontFamily); 597 appendToBuffer(buffer, bufsize, "\r\n Font size: %d", attributeInfo.fontSize); 598 599 appendToBuffer(buffer, bufsize, "\r\n First line indent: %f", attributeInfo.firstLineIndent); 600 appendToBuffer(buffer, bufsize, "\r\n Left indent: %f", attributeInfo.leftIndent); 601 appendToBuffer(buffer, bufsize, "\r\n Right indent: %f", attributeInfo.rightIndent); 602 appendToBuffer(buffer, bufsize, "\r\n Line spacing: %f", attributeInfo.lineSpacing); 603 appendToBuffer(buffer, bufsize, "\r\n Space above: %f", attributeInfo.spaceAbove); 604 appendToBuffer(buffer, bufsize, "\r\n Space below: %f", attributeInfo.spaceBelow); 605 606 appendToBuffer(buffer, bufsize, "\r\n Full attribute string: %ls", attributeInfo.fullAttributesString); 607 608 // get the attribute run length 609 short runLength = -1; 610 if (getTextAttributesInRange(vmID, ac, textInfo.indexAtPoint, textInfo.indexAtPoint + 100, 611 &attributeInfo, &runLength)) { 612 appendToBuffer(buffer, bufsize, "\r\n Attribute run: %d", runLength); 613 } else { 614 appendToBuffer(buffer, bufsize, "\r\n getTextAttributesInRangeFailed"); 615 } 616 } 617 618 /* ===== AccessibleText information at the caret index ===== */ 619 620 appendToBuffer(buffer, bufsize, "\r\n\r\n At caret index: %d", textInfo.caretIndex); 621 622 if (getCaretLocation(vmID, ac, &rectInfo, textInfo.caretIndex) == TRUE) { 623 624 appendToBuffer(buffer, bufsize, "\r\n Caret bounding rectangle: [%d, %d, %d, %d]", 625 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height); 626 } 627 628 if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.caretIndex) == TRUE) { 629 630 appendToBuffer(buffer, bufsize, "\r\n Character bounding rectangle: [%d, %d, %d, %d]", 631 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height); 632 } 633 634 if (GetAccessibleTextLineBounds(vmID, ac, textInfo.caretIndex, &start, &end) == TRUE) { 635 if (GetAccessibleTextRange(vmID, ac, start, end, tmpBuf, (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE) { 636 637 appendToBuffer(buffer, bufsize, "\r\n Line bounds: [%d, %d]", start, end); 638 } 639 } 640 if (GetAccessibleTextItems(vmID, ac, &textItems, textInfo.caretIndex) == TRUE) { 641 642 appendToBuffer(buffer, bufsize, "\r\n Character: %lc", textItems.letter); 643 appendToBuffer(buffer, bufsize, "\r\n Word: %ls", textItems.word); 644 appendToBuffer(buffer, bufsize, "\r\n Sentence: %ls", textItems.sentence); 645 } 646 647 /* ===== AccessibleText attributes ===== */ 648 649 if (GetAccessibleTextAttributes(vmID, ac, textInfo.caretIndex, &attributeInfo)) { 650 651 appendToBuffer(buffer, bufsize, "\r\n Core attributes: %s", 652 attributeInfo.bold == TRUE ? "bold" : "not bold"); 653 appendToBuffer(buffer, bufsize, ", %s", 654 attributeInfo.italic == TRUE ? "italic" : "not italic"); 655 appendToBuffer(buffer, bufsize, ", %s", 656 attributeInfo.underline == TRUE ? "underline" : "not underline"); 657 appendToBuffer(buffer, bufsize, ", %s", 658 attributeInfo.strikethrough == TRUE ? "strikethrough" : "not strikethrough"); 659 appendToBuffer(buffer, bufsize, ", %s", 660 attributeInfo.superscript == TRUE ? "superscript" : "not superscript"); 661 appendToBuffer(buffer, bufsize, ", %s", 662 attributeInfo.subscript == TRUE ? "subscript" : "not subscript"); 663 664 appendToBuffer(buffer, bufsize, "\r\n Background color: %ls", attributeInfo.backgroundColor); 665 appendToBuffer(buffer, bufsize, "\r\n Foreground color: %ls", attributeInfo.foregroundColor); 666 appendToBuffer(buffer, bufsize, "\r\n Font family: %ls", attributeInfo.fontFamily); 667 appendToBuffer(buffer, bufsize, "\r\n Font size: %d", attributeInfo.fontSize); 668 669 670 appendToBuffer(buffer, bufsize, "\r\n First line indent: %f", attributeInfo.firstLineIndent); 671 appendToBuffer(buffer, bufsize, "\r\n Left indent: %f", attributeInfo.leftIndent); 672 appendToBuffer(buffer, bufsize, "\r\n Right indent: %f", attributeInfo.rightIndent); 673 appendToBuffer(buffer, bufsize, "\r\n Line spacing: %f", attributeInfo.lineSpacing); 674 appendToBuffer(buffer, bufsize, "\r\n Space above: %f", attributeInfo.spaceAbove); 675 appendToBuffer(buffer, bufsize, "\r\n Space below: %f", attributeInfo.spaceBelow); 676 677 appendToBuffer(buffer, bufsize, "\r\n Full attribute string: %ls", attributeInfo.fullAttributesString); 678 // get the attribute run length 679 short runLength = -1; 680 if (getTextAttributesInRange(vmID, ac, textInfo.caretIndex, textInfo.caretIndex + 100, 681 &attributeInfo, &runLength)) { 682 appendToBuffer(buffer, bufsize, "\r\n Attribute run: %d", runLength); 683 } else { 684 appendToBuffer(buffer, bufsize, "\r\n getTextAttributesInRangeFailed"); 685 } 686 } 687 } 688 } 689 return buffer; 690 }