Changeset 22412 in vbox
- Timestamp:
- Aug 24, 2009 1:02:40 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 51391
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxVideo.h
r22247 r22412 33 33 #include <iprt/cdefs.h> 34 34 #include <iprt/types.h> 35 36 #ifdef VBOX_WITH_HGSMI 37 #include <VBox/VMMDev.h> 38 #endif /* VBOX_WITH_HGSMI */ 35 39 36 40 /* … … 521 525 522 526 523 #define VBOXVHWA_OFFSET64_VOID (~0 L)527 #define VBOXVHWA_OFFSET64_VOID (~0ULL) 524 528 525 529 typedef struct _VBOXVHWA_VERSION … … 831 835 } VBVACONF32; 832 836 833 typedef struct _VBVAINFOVIEW837 typedef struct VBVAINFOVIEW 834 838 { 835 839 /* Index of the screen, assigned by the guest. */ … … 866 870 #define VBVA_SCREEN_F_ACTIVE 0x0001 867 871 868 typedef struct _VBVAINFOSCREEN872 typedef struct VBVAINFOSCREEN 869 873 { 870 874 /* Which view contains the screen. */ … … 876 880 /* Physical Y origin relative to the primary screen. */ 877 881 int32_t i32OriginY; 882 883 /* Offset of visible framebuffer relative to the framebuffer start. */ 884 uint32_t u32StartOffset; 878 885 879 886 /* The scan line size in bytes. */ -
trunk/include/VBox/pdmifs.h
r21226 r22412 422 422 423 423 typedef struct _VBOXVHWACMD *PVBOXVHWACMD; /**< @todo r=bird: _VBOXVHWACMD -> VBOXVHWACMD; avoid using 1 or 2 leading underscores. Also, a line what it is to make doxygen happy. */ 424 #ifdef VBOX_WITH_HGSMI 425 typedef struct VBVACMDHDR *PVBVACMDHDR; 426 typedef struct VBVAINFOSCREEN *PVBVAINFOSCREEN; 427 typedef struct VBVAINFOVIEW *PVBVAINFOVIEW; 428 #endif /* VBOX_WITH_HGSMI */ 424 429 425 430 /** Pointer to a display connector interface. */ … … 531 536 */ 532 537 DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd)); 538 539 #ifdef VBOX_WITH_HGSMI 540 /** 541 * The specified screen enters VBVA mode. 542 * 543 * @param pInterface Pointer to this interface. 544 * @param uScreenId The screen updates are for. 545 * @thread The emulation thread. 546 */ 547 DECLR3CALLBACKMEMBER(int, pfnVBVAEnable,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId)); 548 549 /** 550 * The specified screen leaves VBVA mode. 551 * 552 * @param pInterface Pointer to this interface. 553 * @param uScreenId The screen updates are for. 554 * @thread The emulation thread. 555 */ 556 DECLR3CALLBACKMEMBER(void, pfnVBVADisable,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId)); 557 558 /** 559 * A sequence of pfnVBVAUpdateProcess calls begins. 560 * 561 * @param pInterface Pointer to this interface. 562 * @param uScreenId The screen updates are for. 563 * @thread The emulation thread. 564 */ 565 DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateBegin,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId)); 566 567 /** 568 * Process the guest VBVA command. 569 * 570 * @param pInterface Pointer to this interface. 571 * @param pCmd Video HW Acceleration Command to be processed. 572 * @thread The emulation thread. 573 */ 574 DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateProcess,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, const PVBVACMDHDR pCmd, size_t cbCmd)); 575 576 /** 577 * A sequence of pfnVBVAUpdateProcess calls ends. 578 * 579 * @param pInterface Pointer to this interface. 580 * @param uScreenId The screen updates are for. 581 * @param x The upper left corner x coordinate of the combined rectangle of all VBVA updates. 582 * @param y The upper left corner y coordinate of the rectangle. 583 * @param cx The width of the rectangle. 584 * @param cy The height of the rectangle. 585 * @thread The emulation thread. 586 */ 587 DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateEnd,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)); 588 589 /** 590 * Resize the display. 591 * This is called when the resolution changes. This usually happens on 592 * request from the guest os, but may also happen as the result of a reset. 593 * If the callback returns VINF_VGA_RESIZE_IN_PROGRESS, the caller (VGA device) 594 * must not access the connector and return. 595 * 596 * @todo Merge with pfnResize. 597 * 598 * @returns VINF_SUCCESS if the framebuffer resize was completed, 599 * VINF_VGA_RESIZE_IN_PROGRESS if resize takes time and not yet finished. 600 * @param pInterface Pointer to this interface. 601 * @param pView The description of VRAM block for this screen. 602 * @param pScreen The data of screen being resized. 603 * @param pvVRAM Address of the guest VRAM. 604 * @thread The emulation thread. 605 */ 606 DECLR3CALLBACKMEMBER(int, pfnVBVAResize,(PPDMIDISPLAYCONNECTOR pInterface, const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM)); 607 608 /** 609 * Update the pointer shape. 610 * This is called when the mouse pointer shape changes. The new shape 611 * is passed as a caller allocated buffer that will be freed after returning 612 * 613 * @param pInterface Pointer to this interface. 614 * @param fVisible Visibility indicator (if false, the other parameters are undefined). 615 * @param fAlpha Flag whether alpha channel is being passed. 616 * @param xHot Pointer hot spot x coordinate. 617 * @param yHot Pointer hot spot y coordinate. 618 * @param x Pointer new x coordinate on screen. 619 * @param y Pointer new y coordinate on screen. 620 * @param cx Pointer width in pixels. 621 * @param cy Pointer height in pixels. 622 * @param cbScanline Size of one scanline in bytes. 623 * @param pvShape New shape buffer. 624 * @thread The emulation thread. 625 */ 626 DECLR3CALLBACKMEMBER(int, pfnVBVAMousePointerShape,(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha, 627 uint32_t xHot, uint32_t yHot, 628 uint32_t cx, uint32_t cy, 629 const void *pvShape)); 630 #endif /* VBOX_WITH_HGSMI */ 533 631 534 632 /** Read-only attributes. -
trunk/src/VBox/Additions/WINNT/Graphics/Display/enable.c
r20653 r22412 558 558 vDisablePalette((PPDEV) dhpdev); 559 559 560 /* Free the driver's VBVA resources. */561 vboxVbvaDisable ((PPDEV) dhpdev);562 563 560 EngFreeMem(dhpdev); 564 561 } … … 867 864 vboxVHWADisable(ppdev); 868 865 #endif 866 867 #ifdef VBOX_WITH_HGSMI 868 /* Free the driver's VBVA resources. */ 869 vboxVbvaDisable ((PPDEV) dhpdev); 870 #endif 869 871 vDisableSURF(ppdev); 870 872 } … … 959 961 vboxVHWADisable(ppdev); 960 962 #endif 963 964 #ifdef VBOX_WITH_HGSMI 965 /* Free the driver's VBVA resources. */ 966 vboxVbvaDisable ((PPDEV) dhpdev); 967 #endif 968 961 969 // 962 970 // We must give up the display. -
trunk/src/VBox/Additions/WINNT/Graphics/Display/pointer.c
r21227 r22412 164 164 DWORD returnedDataLength; 165 165 166 DISPDBG((0, "DISP bSetHardwarePointerShape SPS_ALPHA = %d\n", fl & SPS_ALPHA));166 DISPDBG((0, "DISP[%d] bSetHardwarePointerShape SPS_ALPHA = %d\n", ppdev->iDevice, fl & SPS_ALPHA)); 167 167 168 168 // We don't use the exclusion rectangle because we only support -
trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c
r22136 r22412 245 245 (uint8_t *)ppdev->pjScreen + ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS), 246 246 ppdev->layout.cbDisplayInformation - sizeof (HGSMIHOSTFLAGS), 247 ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS)); 247 info.areaDisplay.offBase + ppdev->layout.offDisplayInformation + sizeof (HGSMIHOSTFLAGS)); 248 249 DISPDBG((0, "VBoxDISP::vboxInitVBoxVideo: offBase 0x%x\n", 250 info.areaDisplay.offBase)); 248 251 249 252 if (RT_FAILURE (rc)) -
trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c
r22408 r22412 345 345 HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&ppdev->hgsmiDisplayHeap, p); 346 346 347 DISPDBG((0, "VBoxDISP::vboxHGSMIBufferSubmit: offset 0x%x\n", offBuffer)); 348 347 349 ppdev->pfnHGSMIGHCommandPost(ppdev->hMpHGSMI, offBuffer); 348 350 // ASMOutU16 (VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VBVA_GUEST); … … 389 391 BOOL bRc = FALSE; 390 392 391 DISPDBG((1, "VBoxDisp::vboxVbvaEnable called \n"));393 DISPDBG((1, "VBoxDisp::vboxVbvaEnable called ppdev %p, hgsmi %d, vbva %p\n", ppdev, ppdev->bHGSMISupported, ppdev->pVBVA)); 392 394 393 395 if (ppdev->bHGSMISupported) 394 396 { 395 397 VBVABUFFER *pVBVA = (VBVABUFFER *)((uint8_t *)ppdev->pjScreen + ppdev->layout.offVBVABuffer); 398 399 DISPDBG((1, "VBoxDisp::vboxVbvaEnable screen %p vbva off 0x%x\n", ppdev->pjScreen, ppdev->layout.offVBVABuffer)); 396 400 397 401 pVBVA->u32HostEvents = 0; … … 677 681 pScreen->i32OriginX = ppdev->ptlDevOrg.x; 678 682 pScreen->i32OriginY = ppdev->ptlDevOrg.y; 683 pScreen->u32StartOffset = 0; 679 684 pScreen->u32LineSize = ppdev->lDeltaScreen > 0?ppdev->lDeltaScreen: -ppdev->lDeltaScreen; 680 685 pScreen->u32Width = ppdev->cxScreen; -
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
r22141 r22412 1565 1565 Result = vboxUpdatePointerShape(&PointerAttributes, sizeof (PointerAttributes)); 1566 1566 #else 1567 Result = vboxUpdatePointerShape(( PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));1568 #endif /* VBOX_WITH_HGSMI */1567 Result = vboxUpdatePointerShape(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, &PointerAttributes, sizeof (PointerAttributes)); 1568 #endif /* VBOX_WITH_HGSMI */ 1569 1569 1570 1570 if (!Result) … … 1597 1597 Result = vboxUpdatePointerShape(&PointerAttributes, sizeof (PointerAttributes)); 1598 1598 #else 1599 Result = vboxUpdatePointerShape(( PDEVICE_EXTENSION)HwDeviceExtension, &PointerAttributes, sizeof (PointerAttributes));1600 #endif /* VBOX_WITH_HGSMI */1599 Result = vboxUpdatePointerShape(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, &PointerAttributes, sizeof (PointerAttributes)); 1600 #endif /* VBOX_WITH_HGSMI */ 1601 1601 1602 1602 if (!Result) … … 1644 1644 Result = vboxUpdatePointerShape(pPointerAttributes, RequestPacket->InputBufferLength); 1645 1645 #else 1646 Result = vboxUpdatePointerShape(( PDEVICE_EXTENSION)HwDeviceExtension, pPointerAttributes, RequestPacket->InputBufferLength);1647 #endif /* VBOX_WITH_HGSMI */1646 Result = vboxUpdatePointerShape(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, pPointerAttributes, RequestPacket->InputBufferLength); 1647 #endif /* VBOX_WITH_HGSMI */ 1648 1648 if (!Result) 1649 1649 dprintf(("VBoxVideo::VBoxVideoStartIO: Could not set hardware pointer -> fallback\n")); … … 2225 2225 VP_STATUS Status; 2226 2226 2227 dprintf(("VBoxVideo::VBoxVideoMapVideoMemory \n"));2227 dprintf(("VBoxVideo::VBoxVideoMapVideoMemory: fb offset 0x%x\n", DeviceExtension->ulFrameBufferOffset)); 2228 2228 2229 2229 FrameBuffer.QuadPart = VBE_DISPI_LFB_PHYSICAL_ADDRESS + DeviceExtension->ulFrameBufferOffset; -
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r22388 r22412 5343 5343 char *pchEnd; 5344 5344 LogFlow(("vgaReset\n")); 5345 5346 #ifdef VBOX_WITH_HGSMI 5347 VBVAReset(pThis); 5348 #endif /* VBOX_WITH_HGSMI */ 5349 5345 5350 5346 5351 /* Clear the VRAM ourselves. */ -
trunk/src/VBox/Devices/Graphics/DevVGA.h
r22388 r22412 453 453 void VBVADestroy (PVGASTATE pVGAState); 454 454 int VBVAUpdateDisplay (PVGASTATE pVGAState); 455 void VBVAReset (PVGASTATE pVGAState); 455 456 456 457 # ifdef VBOX_WITH_VIDEOHWACCEL -
trunk/src/VBox/Main/DisplayImpl.cpp
r22277 r22412 213 213 memset (&maFramebuffers[ul].dirtyRect, 0 , sizeof (maFramebuffers[ul].dirtyRect)); 214 214 memset (&maFramebuffers[ul].pendingResize, 0 , sizeof (maFramebuffers[ul].pendingResize)); 215 #ifdef VBOX_WITH_HGSMI 216 maFramebuffers[ul].fVBVAEnabled = false; 217 #endif /* VBOX_WITH_HGSMI */ 215 218 } 216 219 … … 582 585 pFramebuffer->Unlock(); 583 586 587 #ifndef VBOX_WITH_HGSMI 584 588 if (!mfVideoAccelEnabled) 585 589 { 590 #else 591 if (!mfVideoAccelEnabled && !maFramebuffers[uScreenId].fVBVAEnabled) 592 { 593 LogFlowFunc(("HGSMI: VRDP update without VBVA.\n")); 594 #endif /* VBOX_WITH_HGSMI */ 586 595 /* When VBVA is enabled, the VRDP server is informed in the VideoAccelFlush. 587 596 * Inform the server here only if VBVA is disabled. … … 2376 2385 #endif 2377 2386 2387 #ifdef VBOX_WITH_HGSMI 2388 DECLCALLBACK(int) Display::displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId) 2389 { 2390 LogFlowFunc(("uScreenId %d\n", uScreenId)); 2391 2392 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2393 Display *pThis = pDrv->pDisplay; 2394 2395 pThis->maFramebuffers[uScreenId].fVBVAEnabled = true; 2396 2397 return VINF_SUCCESS; 2398 } 2399 2400 DECLCALLBACK(void) Display::displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId) 2401 { 2402 LogFlowFunc(("uScreenId %d\n", uScreenId)); 2403 2404 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2405 Display *pThis = pDrv->pDisplay; 2406 2407 pThis->maFramebuffers[uScreenId].fVBVAEnabled = false; 2408 } 2409 2410 DECLCALLBACK(void) Display::displayVBVAUpdateBegin(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId) 2411 { 2412 LogFlowFunc(("uScreenId %d\n", uScreenId)); 2413 2414 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2415 Display *pThis = pDrv->pDisplay; 2416 2417 NOREF(uScreenId); 2418 } 2419 2420 DECLCALLBACK(void) Display::displayVBVAUpdateProcess(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, const PVBVACMDHDR pCmd, size_t cbCmd) 2421 { 2422 LogFlowFunc(("uScreenId %d pCmd %p cbCmd %d\n", uScreenId, pCmd, cbCmd)); 2423 2424 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2425 Display *pThis = pDrv->pDisplay; 2426 2427 pThis->mParent->consoleVRDPServer()->SendUpdate (uScreenId, pCmd, cbCmd); 2428 } 2429 2430 DECLCALLBACK(void) Display::displayVBVAUpdateEnd(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy) 2431 { 2432 LogFlowFunc(("uScreenId %d %d,%d %dx%d\n", uScreenId, x, y, cx, cy)); 2433 2434 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2435 Display *pThis = pDrv->pDisplay; 2436 2437 /* @todo handleFramebufferUpdate (uScreenId, 2438 * x - pThis->maFramebuffers[uScreenId].xOrigin, 2439 * y - pThis->maFramebuffers[uScreenId].yOrigin, 2440 * cx, cy); 2441 */ 2442 pThis->handleDisplayUpdate(x, y, cx, cy); 2443 } 2444 2445 DECLCALLBACK(int) Display::displayVBVAResize(PPDMIDISPLAYCONNECTOR pInterface, const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM) 2446 { 2447 LogFlowFunc(("pScreen %p, pvVRAM %p\n", pScreen, pvVRAM)); 2448 2449 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2450 Display *pThis = pDrv->pDisplay; 2451 2452 DISPLAYFBINFO *pFBInfo = &pThis->maFramebuffers[pScreen->u32ViewIndex]; 2453 2454 pFBInfo->u32Offset = pView->u32ViewOffset; /* Not used in HGSMI. */ 2455 pFBInfo->u32MaxFramebufferSize = pView->u32MaxScreenSize; /* Not used in HGSMI. */ 2456 pFBInfo->u32InformationSize = 0; /* Not used in HGSMI. */ 2457 2458 pFBInfo->xOrigin = pScreen->i32OriginX; 2459 pFBInfo->yOrigin = pScreen->i32OriginY; 2460 2461 pFBInfo->w = pScreen->u32Width; 2462 pFBInfo->h = pScreen->u32Height; 2463 2464 return pThis->handleDisplayResize(pScreen->u32ViewIndex, pScreen->u16BitsPerPixel, 2465 (uint8_t *)pvVRAM + pScreen->u32StartOffset, 2466 pScreen->u32LineSize, pScreen->u32Width, pScreen->u32Height); 2467 } 2468 2469 DECLCALLBACK(int) Display::displayVBVAMousePointerShape(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha, 2470 uint32_t xHot, uint32_t yHot, 2471 uint32_t cx, uint32_t cy, 2472 const void *pvShape) 2473 { 2474 LogFlowFunc(("\n")); 2475 2476 PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface); 2477 Display *pThis = pDrv->pDisplay; 2478 2479 /* Tell the console about it */ 2480 pDrv->pDisplay->mParent->onMousePointerShapeChange(fVisible, fAlpha, 2481 xHot, yHot, cx, cy, (void *)pvShape); 2482 2483 return VINF_SUCCESS; 2484 } 2485 #endif /* VBOX_WITH_HGSMI */ 2486 2378 2487 /** 2379 2488 * Queries an interface to the driver. … … 2458 2567 pData->Connector.pfnVHWACommandProcess = Display::displayVHWACommandProcess; 2459 2568 #endif 2569 #ifdef VBOX_WITH_HGSMI 2570 pData->Connector.pfnVBVAEnable = Display::displayVBVAEnable; 2571 pData->Connector.pfnVBVADisable = Display::displayVBVADisable; 2572 pData->Connector.pfnVBVAUpdateBegin = Display::displayVBVAUpdateBegin; 2573 pData->Connector.pfnVBVAUpdateProcess = Display::displayVBVAUpdateProcess; 2574 pData->Connector.pfnVBVAUpdateEnd = Display::displayVBVAUpdateEnd; 2575 pData->Connector.pfnVBVAResize = Display::displayVBVAResize; 2576 pData->Connector.pfnVBVAMousePointerShape = Display::displayVBVAMousePointerShape; 2577 #endif 2578 2460 2579 2461 2580 /* -
trunk/src/VBox/Main/include/DisplayImpl.h
r22277 r22412 80 80 } pendingResize; 81 81 82 #ifdef VBOX_WITH_HGSMI 83 bool fVBVAEnabled; 84 #endif /* VBOX_WITH_HGSMI */ 82 85 } DISPLAYFBINFO; 83 86 … … 277 280 #endif 278 281 282 #ifdef VBOX_WITH_HGSMI 283 static DECLCALLBACK(int) displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId); 284 static DECLCALLBACK(void) displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId); 285 static DECLCALLBACK(void) displayVBVAUpdateBegin(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId); 286 static DECLCALLBACK(void) displayVBVAUpdateProcess(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, const PVBVACMDHDR pCmd, size_t cbCmd); 287 static DECLCALLBACK(void) displayVBVAUpdateEnd(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy); 288 static DECLCALLBACK(int) displayVBVAResize(PPDMIDISPLAYCONNECTOR pInterface, const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM); 289 static DECLCALLBACK(int) displayVBVAMousePointerShape(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha, uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy, const void *pvShape); 290 #endif 291 292 279 293 static DECLCALLBACK(void) displaySSMSave (PSSMHANDLE pSSM, void *pvUser); 280 294 static DECLCALLBACK(int) displaySSMLoad (PSSMHANDLE pSSM, void *pvUser, uint32_t u32Version);
Note:
See TracChangeset
for help on using the changeset viewer.