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 31LogStringCallbackFP g_LogStringCallback = NULL; 32 33/* 34 * returns formatted date and time 35 */ 36char *getTimeAndDate() { 37 static char datebuf[64]; 38 struct tm *newtime; 39 char am_pm[] = "AM"; 40 time_t long_time; 41 42 time( &long_time ); /* Get time as long integer. */ 43 newtime = localtime( &long_time ); /* Convert to local time. */ 44 45 if( newtime->tm_hour > 12 ) /* Set up extension. */ 46 strcpy( am_pm, "PM" ); 47 if( newtime->tm_hour > 12 ) /* Convert from 24-hour */ 48 newtime->tm_hour -= 12; /* to 12-hour clock. */ 49 if( newtime->tm_hour == 0 ) /*Set hour to 12 if midnight. */ 50 newtime->tm_hour = 12; 51 52 sprintf(datebuf, "%.19s %s\n", asctime( newtime ), am_pm ); 53 return (char *)datebuf; 54} 55 56 57/* 58 * displays a message in a dialog and writes the message to a logfile 59 */ 60void displayAndLog(HWND hDlg, int nIDDlgItem, FILE *logfile, char *msg, ...) { 61 62 if (hDlg == NULL || msg == NULL) { 63 return; 64 } 65 66 char tmpbuf[HUGE_BUFSIZE]; 67 va_list argprt; 68 69 va_start(argprt, msg); 70 vsprintf(tmpbuf, msg, argprt); 71 72 SetDlgItemText(hDlg, nIDDlgItem, tmpbuf); 73 74 fprintf(logfile, "\n****************************************\n"); 75 fprintf(logfile, "%s\n", getTimeAndDate()); 76 fprintf(logfile, "%s\n", tmpbuf); 77 fflush(logfile); 78 79 if ( NULL != g_LogStringCallback ) 80 { 81 g_LogStringCallback (tmpbuf); 82 } 83} 84 85/* 86 * writes a text string to a logfile 87 */ 88void logString(FILE *logfile, char *msg, ...) { 89 90 if (logfile == NULL || msg == NULL) { 91 return; 92 } 93 94 char tmpbuf[LINE_BUFSIZE]; 95 va_list argprt; 96 97 va_start(argprt, msg); 98 vsprintf(tmpbuf, msg, argprt); 99 100 fprintf(logfile, tmpbuf); 101 fprintf(logfile, "\n"); 102 fflush(logfile); 103} 104 105/* 106 * safely appends a message to a buffer 107 */ 108BOOL appendToBuffer(char *buf, size_t buflen, char *msg, ...) { 109 110 static char warning[] = 111 "\nNot enough buffer space; remaining information truncated.\n"; 112 size_t warningLength = strlen(warning) + 1; 113 114 if (buf == NULL || msg == NULL) { 115 return FALSE; 116 } 117 118 char tmpbuf[LARGE_BUFSIZE]; 119 va_list argprt; 120 121 va_start(argprt, msg); 122 vsprintf(tmpbuf, msg, argprt); 123 124 // verify there's enough space in the buffer 125 size_t spaceRemaining = buflen - strlen(buf) - 1; 126 if (spaceRemaining <= warningLength) { 127 strncat(buf, warning, spaceRemaining); 128 return FALSE; 129 } 130 strncat(buf, tmpbuf, spaceRemaining); 131 return TRUE; 132} 133 134/** 135 * returns accessibility information for an AccessibleContext 136 */ 137char *getAccessibleInfo(long vmID, AccessibleContext ac, char *buffer, 138 int bufsize) { 139 return getAccessibleInfo(vmID, ac, 0, 0, buffer, bufsize); 140} 141 142/** 143 * returns accessibility information at the specified coordinates in an 144 * AccessibleContext 145 */ 146char *getAccessibleInfo(long vmID, AccessibleContext ac, int x, int y, 147 char *buffer, int bufsize) { 148 149 wchar_t tmpBuf[LINE_BUFSIZE]; 150 wchar_t name[LINE_BUFSIZE]; 151 int i, j; 152 long start; 153 long end; 154 155 if (buffer == NULL || bufsize <= 0) { 156 return NULL; 157 } 158 buffer[0] = NULL; 159 160 /* ===== AccessBridge / J2SE version information ===== */ 161 162 AccessBridgeVersionInfo versionInfo; 163 BOOL result = GetVersionInfo(vmID, &versionInfo); 164 165 if (result == FALSE) { 166 appendToBuffer( buffer, bufsize, 167 "\r\nERROR: cannot get version information", bufsize ); 168 } else { 169 appendToBuffer(buffer, bufsize, "Version Information:"); 170 appendToBuffer( buffer, bufsize, 171 "\r\n Java virtual machine version: %ls", 172 versionInfo.VMversion ); 173 appendToBuffer( buffer, bufsize, 174 "\r\n Access Bridge Java class version: %ls", 175 versionInfo.bridgeJavaClassVersion ); 176 appendToBuffer( buffer, bufsize, 177 "\r\n Access Bridge Java DLL version: %ls", 178 versionInfo.bridgeJavaDLLVersion ); 179 appendToBuffer( buffer, bufsize, 180 "\r\n Access Bridge Windows DLL version: %ls", 181 versionInfo.bridgeWinDLLVersion ); 182 } 183 184 if (ac == (AccessibleContext) 0) { 185 return buffer; 186 } 187 188 189 /* ===== core AccessibleContext information ===== */ 190 191 AccessibleContextInfo info; 192 if (GetAccessibleContextInfo(vmID, ac, &info) == FALSE) { 193 appendToBuffer( buffer, bufsize, 194 "\r\nERROR: GetAccessibleContextInfo failed ", bufsize ); 195 } else { 196 appendToBuffer( buffer, bufsize, 197 "\r\n\r\nAccessibleContext information", bufsize ); 198 if (x >= 0 && y >= 0) { 199 appendToBuffer(buffer, bufsize, " at mouse point [%d, %d]:", x, y); 200 } else { 201 appendToBuffer(buffer, bufsize, ":", bufsize); 202 } 203 204 appendToBuffer(buffer, bufsize, "\r\n Name: %ls", info.name); 205 if ( getVirtualAccessibleName( vmID, ac, name, 206 (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { 207 appendToBuffer( buffer, bufsize, 208 "\r\n\r\nERROR: getVirtualAccessibleName", bufsize ); 209 } else { 210 appendToBuffer(buffer, bufsize, "\r\n Virtual Name: %ls", name); 211 } 212 appendToBuffer( buffer, bufsize, "\r\n Description: %ls", 213 info.description ); 214 appendToBuffer(buffer, bufsize, "\r\n Role: %ls", info.role); 215 appendToBuffer( buffer, bufsize, "\r\n Role in en_US locale: %ls", 216 info.role_en_US ); 217 appendToBuffer(buffer, bufsize, "\r\n States: %ls", info.states); 218 appendToBuffer( buffer, bufsize, "\r\n States in en_US locale: %ls", 219 info.states_en_US ); 220 appendToBuffer( buffer, bufsize, "\r\n Index in parent: %d", 221 info.indexInParent ); 222 appendToBuffer( buffer, bufsize, "\r\n Children count: %d", 223 info.childrenCount ); 224 appendToBuffer( buffer, bufsize, 225 "\r\n Bounding rectangle: [%d, %d, %d, %d]", 226 info.x, info.y, info.x + info.width, 227 info.y + info.height ); 228 229 /* top-level window info */ 230 AccessibleContext topAC = getTopLevelObject(vmID, ac); 231 if (topAC == NULL) { 232 appendToBuffer( buffer, bufsize, 233 "\r\nERROR: getTopLevelObject failed", bufsize ); 234 } else { 235 AccessibleContextInfo topInfo; 236 if (GetAccessibleContextInfo(vmID, topAC, &topInfo) == FALSE) { 237 appendToBuffer( 238 buffer, bufsize, 239 "\r\nERROR: GetAccessibleContextInfo failed for top-level window ", 240 bufsize ); 241 } else { 242 if (getVirtualAccessibleName(vmID, topAC, name, 243 (sizeof(name) / sizeof(wchar_t)) ) == FALSE) { 244 appendToBuffer( buffer, bufsize, 245 "\r\n\r\nERROR: getVirtualAccessibleName", 246 bufsize ); 247 } else { 248 appendToBuffer( buffer, bufsize, 249 "\r\n Top-level window name: %ls", 250 name ); 251 } 252 appendToBuffer( buffer, bufsize, 253 "\r\n Top-level window role: %ls", 254 topInfo.role ) ; 255 } 256 ReleaseJavaObject(vmID, topAC); 257 258 } 259 260 /* ===== AccessibleParent information ===== */ 261 262 AccessibleContext parentAC = GetAccessibleParentFromContext(vmID, ac); 263 if (parentAC == NULL) { 264 appendToBuffer(buffer, bufsize, "\r\n No parent", bufsize); 265 } else { 266 AccessibleContextInfo parentInfo; 267 if (GetAccessibleContextInfo(vmID, parentAC, &parentInfo) == FALSE) { 268 appendToBuffer( buffer, bufsize, 269 "\r\nERROR: GetAccessibleContextInfo failed for parent", 270 bufsize ); 271 } else { 272 appendToBuffer( buffer, bufsize, "\r\n Parent name: %ls", 273 parentInfo.name ); 274 if ( getVirtualAccessibleName( vmID, parentAC, name, 275 (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { 276 appendToBuffer( buffer, bufsize, 277 "\r\n\r\nERROR: getVirtualAccessibleName", 278 bufsize ); 279 } else { 280 appendToBuffer( buffer, bufsize, 281 "\r\n Parent virtual name: %ls", name ); 282 } 283 appendToBuffer( buffer, bufsize, "\r\n Parent role: %ls", 284 parentInfo.role ); 285 } 286 ReleaseJavaObject(vmID, parentAC); 287 } 288 289 290 /* ====== visible children ===== */ 291 int nChildren = getVisibleChildrenCount(vmID, ac); 292 if (nChildren == -1) { 293 appendToBuffer( buffer, bufsize, 294 "\r\nERROR: GetVisibleChildrenCount failed", 295 bufsize ); 296 } else { 297 appendToBuffer( buffer, bufsize, 298 "\r\n Visible descendents count: %d", 299 nChildren ); 300 } 301 302 if (nChildren > 0) { 303 VisibleChildrenInfo visibleChildrenInfo; 304 if (getVisibleChildren(vmID, ac, 0, &visibleChildrenInfo) == FALSE) { 305 appendToBuffer( buffer, bufsize, 306 "\r\nERROR: GetVisibleChildren failed", 307 bufsize ); 308 } else { 309 AccessibleContextInfo childACInfo; 310 for ( int child = 0; 311 child < visibleChildrenInfo.returnedChildrenCount; 312 child++ ) { 313 AccessibleContext childAC = 314 visibleChildrenInfo.children[child]; 315 if (GetAccessibleContextInfo(vmID, childAC, &childACInfo)) { 316 if ( getVirtualAccessibleName( vmID, childAC, name, 317 (sizeof(name) / sizeof(wchar_t))) == FALSE) { 318 appendToBuffer( buffer, bufsize, 319 "\r\n\r\nERROR: getVirtualAccessibleName", 320 bufsize ); 321 } else { 322 appendToBuffer( buffer, bufsize, 323 "\r\n Descendent %d name: %ls", child, 324 name ); 325 } 326 appendToBuffer( buffer, bufsize, 327 "\r\n Descendent %d role: %ls", 328 child, childACInfo.role ); 329 } 330 ReleaseJavaObject(vmID, childAC); 331 } 332 } 333 } 334 335 /* ===== AccessibleSelection ===== */ 336 337 if (info.accessibleSelection == TRUE) { 338 339 int selCount; 340 AccessibleContext selectedAC; 341 342 appendToBuffer( buffer, bufsize, 343 "\r\n\r\nAccessible Selection information:", 344 bufsize ); 345 346 if ((selCount = GetAccessibleSelectionCountFromContext(vmID, ac)) != -1) { 347 appendToBuffer( buffer, bufsize, "\r\n Selection count: %d", 348 selCount ); 349 350 for (i = 0; i < selCount; i++) { 351 if ( ( selectedAC = 352 GetAccessibleSelectionFromContext(vmID, ac, i) ) == NULL ) { 353 appendToBuffer( buffer, bufsize, 354 "\r\nERROR: GetAccessibleSelectionFromContext failed forselection %d", 355 i ); 356 } else { 357 if (GetAccessibleContextInfo(vmID, selectedAC, &info) == FALSE) { 358 appendToBuffer( buffer, bufsize, 359 "\r\nERROR: GetAccessibleContextInfo failed for selection %d", i); 360 } else { 361 if ( getVirtualAccessibleName( vmID, selectedAC, name, 362 (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { 363 appendToBuffer( buffer, bufsize, 364 "\r\n\r\nERROR: getVirtualAccessibleName", bufsize); 365 } else { 366 appendToBuffer( buffer, bufsize, 367 "\r\n Selection %d name: %ls", i, name ); 368 } 369 appendToBuffer( buffer, bufsize, 370 "\r\n Selection %d role: %ls", i, info.role); 371 appendToBuffer( buffer, bufsize, 372 "\r\n Index in parent of selection %d: %d", 373 i, info.indexInParent ); 374 } 375 ReleaseJavaObject(vmID, selectedAC); 376 } 377 } 378 } 379 } 380 381 // ====== Accessible KeyBindings, Icons and Actions ====== 382 383 AccessibleKeyBindings keyBindings; 384 if (getAccessibleKeyBindings(vmID, ac, &keyBindings) == TRUE && 385 keyBindings.keyBindingsCount > 0) { 386 387 appendToBuffer( buffer, bufsize, 388 "\r\n\r\nAccessibleKeyBinding info:", bufsize ); 389 appendToBuffer( buffer, bufsize, 390 "\r\n Number of key bindings: %d", 391 keyBindings.keyBindingsCount ); 392 393 for (j = 0; j < keyBindings.keyBindingsCount; j++) { 394 395 appendToBuffer( buffer, bufsize, 396 "\r\n Key binding %d character: %c", j, 397 keyBindings.keyBindingInfo[j].character ); 398 appendToBuffer( buffer, bufsize, 399 "\r\n Key binding %d modifiers: %d", j, 400 keyBindings.keyBindingInfo[j].modifiers ); 401 } 402 } 403 404 AccessibleIcons icons; 405 if (getAccessibleIcons(vmID, ac, &icons) == TRUE && 406 icons.iconsCount > 0) { 407 408 appendToBuffer( buffer, bufsize, 409 "\r\n\r\nAccessibleIcons info:", bufsize ); 410 appendToBuffer( buffer, bufsize, 411 "\r\n Number of icons: %d", icons.iconsCount ); 412 413 for (j = 0; j < icons.iconsCount; j++) { 414 415 appendToBuffer( buffer, bufsize, 416 "\r\n Icon %d description: %ls", j, 417 icons.iconInfo[j].description ); 418 appendToBuffer( buffer, bufsize, 419 "\r\n Icon %d height: %d", j, 420 icons.iconInfo[j].height ); 421 appendToBuffer( buffer, bufsize, 422 "\r\n Icon %d width: %d", j, 423 icons.iconInfo[j].width ); 424 } 425 } 426 427 AccessibleActions actions; 428 if (getAccessibleActions(vmID, ac, &actions) == TRUE && 429 actions.actionsCount > 0) { 430 431 appendToBuffer( buffer, bufsize, "\r\n\r\nAccessibleActions info:", 432 bufsize ); 433 appendToBuffer( buffer, bufsize, "\r\n Number of actions: %d", 434 actions.actionsCount ); 435 436 for (j = 0; j < actions.actionsCount; j++) { 437 appendToBuffer( buffer, bufsize, "\r\n Action %d name: %ls", 438 j, actions.actionInfo[j].name ); 439 } 440 } 441 442 /* ===== AccessibleRelationSet ===== */ 443 444 AccessibleRelationSetInfo relationSetInfo; 445 if (getAccessibleRelationSet(vmID, ac, &relationSetInfo) == FALSE) { 446 appendToBuffer( buffer, bufsize, 447 "\r\nGetAccessibleRelationSet failed.", bufsize ); 448 } else { 449 int i; 450 AccessibleContextInfo relInfo; 451 452 if (relationSetInfo.relationCount > 0) { 453 appendToBuffer( buffer, bufsize, 454 "\r\n\r\nAccessibleRelationSet information:", 455 bufsize ); 456 appendToBuffer( buffer, bufsize, 457 "\r\n Number of relations: %d", 458 relationSetInfo.relationCount ); 459 } 460 for (i = 0; i < relationSetInfo.relationCount; i++) { 461 AccessibleRelationInfo relationInfo = 462 relationSetInfo.relations[i]; 463 464 appendToBuffer( buffer, bufsize, 465 "\r\n Relation %d key: %ls", i, 466 relationInfo.key ); 467 appendToBuffer( buffer, bufsize, 468 "\r\n Relation %d target count: %d", i, 469 relationInfo.targetCount ); 470 for (j = 0; j < relationInfo.targetCount; j++) { 471 if (GetAccessibleContextInfo( 472 vmID, relationInfo.targets[j], &relInfo ) == FALSE) { 473 appendToBuffer( buffer, bufsize, 474 "\r\nERROR: GetAccessibleContextInfo failed.", 475 bufsize ); 476 } else { 477 // Core AccessibleContext information for relation target 478 if ( getVirtualAccessibleName( vmID, relationInfo.targets[j], 479 name, (sizeof(name) / sizeof(wchar_t)) ) == FALSE ) { 480 appendToBuffer( buffer, bufsize, 481 "\r\n\r\nERROR: getVirtualAccessibleName", bufsize ); 482 } else { 483 appendToBuffer( buffer, bufsize, 484 "\r\n Target %d name: %ls", 485 j, name ); 486 } 487 appendToBuffer( buffer, bufsize, 488 "\r\n Target %d role: %ls", j, 489 relInfo.role); 490 } 491 ReleaseJavaObject(vmID, relationInfo.targets[j]); 492 493 } 494 } 495 } 496 497 /* ===== AccessibleValue ===== */ 498 499 if (info.accessibleInterfaces & cAccessibleValueInterface) { 500 501 appendToBuffer( buffer, bufsize, 502 "\r\n\r\nAccessible Value information:", bufsize); 503 504 if ( GetCurrentAccessibleValueFromContext( vmID, ac, tmpBuf, 505 (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) { 506 appendToBuffer( buffer, bufsize, "\r\n Current Value: %ls", 507 tmpBuf ); 508 } 509 if ( GetMaximumAccessibleValueFromContext( vmID, ac, tmpBuf, 510 (sizeof(tmpBuf) / sizeof(wchar_t))) == TRUE ) { 511 appendToBuffer( buffer, bufsize, 512 "\r\n Maximum Value: %ls", tmpBuf ); 513 } 514 if ( GetMinimumAccessibleValueFromContext( vmID, ac, tmpBuf, 515 (sizeof(tmpBuf) / sizeof(wchar_t)) ) == TRUE ) { 516 appendToBuffer( buffer, bufsize, 517 "\r\n Minimum Value: %ls", tmpBuf ); 518 } 519 } 520 521 522 /* ===== AccessibleTable ===== */ 523 524 AccessibleTableInfo tableInfo; 525 526 if ( (info.accessibleInterfaces & cAccessibleTableInterface) == 527 cAccessibleTableInterface ) { 528 if (getAccessibleTableInfo(vmID, ac, &tableInfo) != TRUE) { 529 appendToBuffer( buffer, bufsize, 530 "\r\nERROR: getAccessibleTableInfo failed", 531 bufsize ); 532 } else { 533 appendToBuffer( buffer, bufsize, 534 "\r\n\r\nAccessibleTable info:", bufsize ); 535 536 int trow = getAccessibleTableRow( vmID, 537 tableInfo.accessibleTable, 3 ); 538 appendToBuffer( buffer, bufsize, 539 "\r\n getAccessibleTableRow: %d", trow); 540 541 int tcol = 542 getAccessibleTableColumn(vmID, tableInfo.accessibleTable, 2); 543 appendToBuffer( buffer, bufsize, 544 "\r\n getAccessibleTableColumn: %d", tcol ); 545 546 int tindex = getAccessibleTableIndex( vmID, 547 tableInfo.accessibleTable, 548 2, 3 ); 549 appendToBuffer( buffer, bufsize, 550 "\r\n getAccessibleTableIndex: %d", 551 tindex ); 552 553 // Core info 554 appendToBuffer( buffer, bufsize, 555 "\r\n table row count: %d", 556 tableInfo.rowCount ); 557 appendToBuffer( buffer, bufsize, 558 "\r\n table column count: %d", 559 tableInfo.columnCount ); 560 561 AccessibleTableCellInfo tableCellInfo; 562 for (int i = 0; i < tableInfo.rowCount; i++) { 563 for (int j = 0; j < tableInfo.columnCount; j++) { 564 565 if ( !getAccessibleTableCellInfo( vmID, 566 tableInfo.accessibleTable, 567 i, j, 568 &tableCellInfo ) ) { 569 570 appendToBuffer( 571 buffer, bufsize, 572 "\r\nERROR: GetAccessibleTableCellInfo failed.", 573 bufsize ); 574 } else { 575 appendToBuffer( buffer, bufsize, 576 "\r\n\r\n AccessibleTable cell[%d,%d] info:", 577 i, j ); 578 appendToBuffer( buffer, bufsize, 579 "\r\n Index: %ld", tableCellInfo.index ); 580 appendToBuffer( buffer, bufsize, 581 "\r\n Row extent: %ld", 582 tableCellInfo.rowExtent ); 583 appendToBuffer( buffer, bufsize, 584 "\r\n Column extent: %ld", 585 tableCellInfo.columnExtent ); 586 appendToBuffer( buffer, bufsize, 587 "\r\n Is selected?: %ld", 588 tableCellInfo.isSelected ); 589 590 AccessibleContextInfo cellACInfo; 591 if ( !GetAccessibleContextInfo( 592 vmID, 593 tableCellInfo.accessibleContext, 594 &cellACInfo ) ) { 595 appendToBuffer( buffer, bufsize, 596 "\r\nERROR: GetAccessibleContextInfo failed for table cell [%d,%d].", 597 i, j ); 598 } else { 599 if ( !getVirtualAccessibleName( vmID, 600 tableCellInfo.accessibleContext, name, 601 (sizeof(name) / sizeof(wchar_t)) ) ) { 602 appendToBuffer( buffer, bufsize, 603 "\r\n\r\nERROR: getVirtualAccessibleName", 604 bufsize ); 605 } else { 606 appendToBuffer( buffer, bufsize, 607 "\r\n Name: %ls", name ); 608 } 609 appendToBuffer( buffer, bufsize, 610 "\r\n Role: %ls", 611 cellACInfo.role ); 612 } 613 ReleaseJavaObject( vmID, 614 tableCellInfo.accessibleContext ); 615 } 616 } 617 } 618 619 // Get the column headers 620 AccessibleTableInfo columnInfo; 621 if ( !getAccessibleTableColumnHeader(vmID, ac, &columnInfo)) { 622 appendToBuffer( buffer, bufsize, 623 "\r\nERROR: getAccessibleTableColumnHeader failed.", 624 bufsize ); 625 } else { 626 appendToBuffer( buffer, bufsize, 627 "\r\n\r\nAccessibleTable column header info:", bufsize ); 628 629 // Core info 630 appendToBuffer( buffer, bufsize, 631 "\r\n Column header row count: %d", 632 columnInfo.rowCount ); 633 appendToBuffer( buffer, bufsize, 634 "\r\n Column header column count: %d", 635 columnInfo.columnCount ); 636 637 } 638 639 // Get the selected rows 640 int numSelections = 641 getAccessibleTableRowSelectionCount( vmID, 642 tableInfo.accessibleTable ); 643 appendToBuffer( buffer, bufsize, 644 "\r\n\r\nRow selection count: %d", 645 numSelections ); 646 jint *selections = new jint[numSelections]; 647 648 if ( !getAccessibleTableRowSelections( vmID, 649 tableInfo.accessibleTable, 650 numSelections, 651 selections ) ) { 652 appendToBuffer( buffer, bufsize, 653 "\r\nERROR: getAccessibleTableRowSelections failed.", 654 bufsize ); 655 } else { 656 appendToBuffer(buffer, bufsize, " \r\n Row selections: "); 657 for (int j = 0; j < numSelections; j++) { 658 appendToBuffer(buffer, bufsize, " %d", selections[j]); 659 } 660 } 661 662 // Get column header info 663 for (int i = 0; i < columnInfo.columnCount; i++) { 664 if ( !getAccessibleTableCellInfo( vmID, 665 columnInfo.accessibleTable, 666 0, i, &tableCellInfo ) ) { 667 668 appendToBuffer( buffer, bufsize, 669 "\r\nERROR: GetAccessibleTableCellInfo failed.", 670 bufsize ); 671 } else { 672 appendToBuffer( buffer, bufsize, 673 "\r\n\r\nColumn header [0,%d] cell info.", i ); 674 appendToBuffer( buffer, bufsize, 675 "\r\n Index: %ld", tableCellInfo.index ); 676 appendToBuffer( buffer, bufsize, 677 "\r\n Row extent: %ld", 678 tableCellInfo.rowExtent ); 679 appendToBuffer( buffer, bufsize, 680 "\r\n Column extent: %ld", 681 tableCellInfo.columnExtent ); 682 appendToBuffer( buffer, bufsize, 683 "\r\n Is selected: %ld", 684 tableCellInfo.isSelected ); 685 686 AccessibleContextInfo cellACInfo; 687 if ( !GetAccessibleContextInfo( vmID, 688 tableCellInfo.accessibleContext, &cellACInfo ) ) { 689 appendToBuffer( buffer, bufsize, 690 "\r\nERROR: GetAccessibleContextInfo failed.", 691 bufsize ); 692 } else { 693 if ( !getVirtualAccessibleName( vmID, 694 tableCellInfo.accessibleContext, name, 695 (sizeof(name) / sizeof(wchar_t)) ) ) { 696 appendToBuffer( buffer, bufsize, 697 "\r\n\r\nERROR: getVirtualAccessibleName", 698 bufsize ); 699 } else { 700 appendToBuffer( buffer, bufsize, 701 "\r\n Name: %ls", name ); 702 } 703 appendToBuffer( buffer, bufsize, 704 "\r\n Role: %ls", cellACInfo.role ); 705 } 706 ReleaseJavaObject(vmID, tableCellInfo.accessibleContext); 707 } 708 } 709 } 710 } 711 712 /* ===== AccessibleText ===== */ 713 714 if (info.accessibleText == TRUE) { 715 AccessibleTextInfo textInfo; 716 AccessibleTextItemsInfo textItems; 717 AccessibleTextSelectionInfo textSelection; 718 AccessibleTextRectInfo rectInfo; 719 AccessibleTextAttributesInfo attributeInfo; 720 721 appendToBuffer( buffer, bufsize, 722 "\r\n\r\nAccessible Text information:", bufsize); 723 724 if (GetAccessibleTextInfo(vmID, ac, &textInfo, x, y) == TRUE) { 725 appendToBuffer( buffer, bufsize, 726 "\r\n Mouse point at text index: %d", 727 textInfo.indexAtPoint ); 728 appendToBuffer( buffer, bufsize, 729 "\r\n Caret at text index: %d", 730 textInfo.caretIndex ); 731 appendToBuffer( buffer, bufsize, 732 "\r\n Char count: %d", 733 textInfo.charCount ); 734 } 735 if ( GetAccessibleTextSelectionInfo(vmID, ac, &textSelection) ) { 736 737 appendToBuffer( buffer, bufsize, 738 "\r\n Selection start index: %d", 739 textSelection.selectionStartIndex ); 740 appendToBuffer( buffer, bufsize, 741 "\r\n Selection end index: %d", 742 textSelection.selectionEndIndex ); 743 appendToBuffer( buffer, bufsize, 744 "\r\n Selected text: %ls", 745 textSelection.selectedText ); 746 } 747 748 /* ===== AccessibleText information at the mouse point ===== */ 749 750 appendToBuffer( buffer, bufsize, 751 "\r\n\r\n At mouse point index: %d", textInfo.indexAtPoint); 752 753 if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.indexAtPoint)) { 754 755 appendToBuffer( buffer, bufsize, 756 "\r\n Character bounding rectangle: [%d, %d, %d, %d]", 757 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); 758 } 759 760 if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.indexAtPoint, 761 &start, &end ) ) { 762 if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf, 763 (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) { 764 appendToBuffer( buffer, bufsize, 765 "\r\n Line bounds: [%d, %d]", start, end); 766 } 767 } 768 if ( GetAccessibleTextItems( vmID, ac, &textItems, 769 textInfo.indexAtPoint ) ) { 770 771 appendToBuffer( buffer, bufsize, 772 "\r\n Character: %lc", textItems.letter ); 773 appendToBuffer( buffer, bufsize, 774 "\r\n Word: %ls", textItems.word ); 775 appendToBuffer( buffer, bufsize, 776 "\r\n Sentence: %ls", textItems.sentence ); 777 } 778 779 /* ===== AccessibleText attributes ===== */ 780 781 if (GetAccessibleTextAttributes(vmID, ac, 782 textInfo.indexAtPoint, 783 &attributeInfo)) { 784 785 appendToBuffer( buffer, bufsize, "\r\n Core attributes: %s", 786 attributeInfo.bold ? "bold" : "not bold" ); 787 appendToBuffer( buffer, bufsize, ", %s", 788 attributeInfo.italic ? "italic" : "not italic" ); 789 appendToBuffer( buffer, bufsize, ", %s", 790 attributeInfo.underline ? "underline" : "not underline" ); 791 appendToBuffer( buffer, bufsize, ", %s", 792 attributeInfo.strikethrough ? "strikethrough" : 793 "not strikethrough" ); 794 appendToBuffer( buffer, bufsize, ", %s", 795 attributeInfo.superscript ? "superscript" : 796 "not superscript" ); 797 appendToBuffer( buffer, bufsize, ", %s", 798 attributeInfo.subscript ? "subscript" : "not subscript" ); 799 800 appendToBuffer( buffer, bufsize, 801 "\r\n Background color: %ls", 802 attributeInfo.backgroundColor ); 803 appendToBuffer( buffer, bufsize, 804 "\r\n Foreground color: %ls", 805 attributeInfo.foregroundColor ); 806 appendToBuffer( buffer, bufsize, 807 "\r\n Font family: %ls", 808 attributeInfo.fontFamily ); 809 appendToBuffer( buffer, bufsize, 810 "\r\n Font size: %d", 811 attributeInfo.fontSize ); 812 813 appendToBuffer( buffer, bufsize, 814 "\r\n First line indent: %f", 815 attributeInfo.firstLineIndent ); 816 appendToBuffer( buffer, bufsize, 817 "\r\n Left indent: %f", 818 attributeInfo.leftIndent ); 819 appendToBuffer( buffer, bufsize, 820 "\r\n Right indent: %f", 821 attributeInfo.rightIndent ); 822 appendToBuffer( buffer, bufsize, 823 "\r\n Line spacing: %f", 824 attributeInfo.lineSpacing ); 825 appendToBuffer( buffer, bufsize, 826 "\r\n Space above: %f", 827 attributeInfo.spaceAbove ); 828 appendToBuffer( buffer, bufsize, 829 "\r\n Space below: %f", 830 attributeInfo.spaceBelow ); 831 832 appendToBuffer( buffer, bufsize, 833 "\r\n Full attribute string: %ls", 834 attributeInfo.fullAttributesString ); 835 836 // get the attribute run length 837 short runLength = -1; 838 if ( getTextAttributesInRange( vmID, ac, textInfo.indexAtPoint, 839 textInfo.indexAtPoint + 100, 840 &attributeInfo, &runLength ) ) { 841 appendToBuffer( buffer, bufsize, 842 "\r\n Attribute run: %d", runLength ); 843 } else { 844 appendToBuffer( buffer, bufsize, 845 "\r\n getTextAttributesInRangeFailed" ); 846 } 847 } 848 849 /* ===== AccessibleText information at the caret index ===== */ 850 851 appendToBuffer( buffer, bufsize, 852 "\r\n\r\n At caret index: %d", textInfo.caretIndex); 853 854 if (getCaretLocation(vmID, ac, &rectInfo, textInfo.caretIndex)) { 855 appendToBuffer( buffer, bufsize, 856 "\r\n Caret bounding rectangle: [%d, %d, %d, %d]", 857 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); 858 } 859 860 if (GetAccessibleTextRect(vmID, ac, &rectInfo, textInfo.caretIndex)) { 861 862 appendToBuffer( buffer, bufsize, 863 "\r\n Character bounding rectangle: [%d, %d, %d, %d]", 864 rectInfo.x, rectInfo.y, rectInfo.width, rectInfo.height ); 865 } 866 867 if ( GetAccessibleTextLineBounds( vmID, ac, textInfo.caretIndex, 868 &start, &end ) ) { 869 if ( GetAccessibleTextRange( vmID, ac, start, end, tmpBuf, 870 (sizeof(tmpBuf) / sizeof(wchar_t)) ) ) { 871 872 appendToBuffer( buffer, bufsize, 873 "\r\n Line bounds: [%d, %d]", start, end); 874 } 875 } 876 if (GetAccessibleTextItems(vmID, ac, &textItems, textInfo.caretIndex)) { 877 878 appendToBuffer( buffer, bufsize, 879 "\r\n Character: %lc", textItems.letter ); 880 appendToBuffer( buffer, bufsize, 881 "\r\n Word: %ls", textItems.word ); 882 appendToBuffer( buffer, bufsize, 883 "\r\n Sentence: %ls", textItems.sentence ); 884 } 885 886 /* ===== AccessibleText attributes ===== */ 887 888 if (GetAccessibleTextAttributes(vmID, ac, textInfo.caretIndex, &attributeInfo)) { 889 890 appendToBuffer( buffer, bufsize, "\r\n Core attributes: %s", 891 attributeInfo.bold ? "bold" : "not bold" ); 892 appendToBuffer( buffer, bufsize, ", %s", 893 attributeInfo.italic ? "italic" : "not italic" ); 894 appendToBuffer( buffer, bufsize, ", %s", 895 attributeInfo.underline ? "underline" : "not underline" ); 896 appendToBuffer( buffer, bufsize, ", %s", 897 attributeInfo.strikethrough ? "strikethrough" : 898 "not strikethrough" ); 899 appendToBuffer( buffer, bufsize, ", %s", 900 attributeInfo.superscript ? "superscript" : 901 "not superscript" ); 902 appendToBuffer( buffer, bufsize, ", %s", 903 attributeInfo.subscript ? "subscript" : "not subscript"); 904 905 appendToBuffer( buffer, bufsize, 906 "\r\n Background color: %ls", 907 attributeInfo.backgroundColor ); 908 appendToBuffer( buffer, bufsize, 909 "\r\n Foreground color: %ls", 910 attributeInfo.foregroundColor ); 911 appendToBuffer( buffer, bufsize, 912 "\r\n Font family: %ls", attributeInfo.fontFamily ); 913 appendToBuffer( buffer, bufsize, 914 "\r\n Font size: %d", attributeInfo.fontSize); 915 916 917 appendToBuffer( buffer, bufsize, 918 "\r\n First line indent: %f", 919 attributeInfo.firstLineIndent ); 920 appendToBuffer( buffer, bufsize, 921 "\r\n Left indent: %f", attributeInfo.leftIndent ); 922 appendToBuffer( buffer, bufsize, 923 "\r\n Right indent: %f", attributeInfo.rightIndent ); 924 appendToBuffer( buffer, bufsize, 925 "\r\n Line spacing: %f", attributeInfo.lineSpacing ); 926 appendToBuffer( buffer, bufsize, 927 "\r\n Space above: %f", attributeInfo.spaceAbove ); 928 appendToBuffer( buffer, bufsize, 929 "\r\n Space below: %f", attributeInfo.spaceBelow ); 930 appendToBuffer( buffer, bufsize, 931 "\r\n Full attribute string: %ls", 932 attributeInfo.fullAttributesString ); 933 // get the attribute run length 934 short runLength = -1; 935 if ( getTextAttributesInRange( vmID, ac, textInfo.caretIndex, 936 textInfo.caretIndex + 100, 937 &attributeInfo, &runLength ) ) { 938 appendToBuffer( buffer, bufsize, 939 "\r\n Attribute run: %d", runLength); 940 } else { 941 appendToBuffer( buffer, bufsize, 942 "\r\n getTextAttributesInRangeFailed" ); 943 } 944 } 945 } 946 } 947 return buffer; 948} 949