Changeset 37423 in vbox for trunk/src/VBox/Additions/WINNT/Graphics
- Timestamp:
- Jun 12, 2011 6:37:56 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/Graphics/Video
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h
r36867 r37423 78 78 79 79 PFNQUEUEDPC pfnQueueDpc; 80 80 81 81 PFNCREATESECONDARYDISPLAY pfnCreateSecondaryDisplay; 82 82 } VBOXVIDEOPORTPROCS; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp
r37216 r37423 4955 4955 * for some reason we're getting pSurf->SysMemPitch as if took 4x1 column from this block, 4956 4956 * which leads us to having 4x times bigger pitch than actual line takes. 4957 * Simply trying to read here provided pointer 4957 * Simply trying to read here provided pointer 4958 4958 * at (byte*)pSurf->pSysMem + pSurf->pSurf->SysMemPitch*pSurf->Height - 1 causes access violation. 4959 4959 */ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h
r36867 r37423 102 102 HANDLE hDriver; /* Display device handle which was passed to VBoxDispDrvEnablePDEV */ 103 103 HDEV hDevGDI; /* GDI's handle for PDEV created in VBoxDispDrvEnablePDEV */ 104 104 105 105 VBOXDISPCURRENTMODE mode; /* Current device mode */ 106 106 ULONG iDevice; /* Miniport's device index */ … … 152 152 VOID APIENTRY VBoxDispDrvDisableSurface(DHPDEV dhpdev); 153 153 154 BOOL APIENTRY VBoxDispDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 154 BOOL APIENTRY VBoxDispDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 155 155 LONG x1, LONG y1, LONG x2, LONG y2, RECTL *prclBounds, MIX mix); 156 156 BOOL APIENTRY VBoxDispDrvStrokePath(SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, … … 171 171 COLORADJUSTMENT *pca, POINTL *pptlHTOrg, RECTL *prclDest, RECTL *prclSrc, 172 172 POINTL *pptlMask, ULONG iMode); 173 BOOL APIENTRY VBoxDispDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 173 BOOL APIENTRY VBoxDispDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 174 174 RECTL *prclDest, POINTL *pptlSrc); 175 175 … … 192 192 193 193 #ifdef VBOX_WITH_DDRAW 194 BOOL APIENTRY VBoxDispDrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps, 194 BOOL APIENTRY VBoxDispDrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps, 195 195 VIDEOMEMORY *pvmList, DWORD *pdwNumFourCCCodes, DWORD *pdwFourCC); 196 BOOL APIENTRY VBoxDispDrvEnableDirectDraw(DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, 196 BOOL APIENTRY VBoxDispDrvEnableDirectDraw(DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, 197 197 DD_SURFACECALLBACKS *pSurfaceCallBacks, 198 198 DD_PALETTECALLBACKS *pPaletteCallBacks); … … 217 217 return pso; 218 218 } 219 219 220 220 #endif /*VBOXDISP_H*/ -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp
r36867 r37423 248 248 } 249 249 250 /* Called to destroy DirectDraw surface, 250 /* Called to destroy DirectDraw surface, 251 251 * in particular we should free vhwa resources allocated on VBoxDispDDCreateSurface. 252 252 * Note: we're always returning DDHAL_DRIVER_NOTHANDLED because we rely on DirectDraw memory manager. … … 499 499 VBoxVBVABufferEndUpdate(&pDev->vbvaCtx); 500 500 } 501 else if ((pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE) 501 else if ((pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE) 502 502 || ((pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && pDesc->bVisible)) 503 503 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDrawVHWA.cpp
r36867 r37423 59 59 if (VBOXVHWA_CAP(pDev, VBOXVHWA_CAPS_BLT)) 60 60 { 61 /* we only support simple dst=src copy 61 /* we only support simple dst=src copy 62 62 * Note: search "ternary raster operations" on msdn for more info 63 63 */ … … 540 540 { 541 541 PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; 542 542 543 543 if (!pDstDesc) 544 544 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDrawCmd.cpp
r36867 r37423 285 285 */ 286 286 287 BOOL APIENTRY 287 BOOL APIENTRY 288 288 VBoxDispDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, LONG x1, LONG y1, LONG x2, LONG y2, 289 289 RECTL *prclBounds, MIX mix) … … 300 300 } 301 301 302 BOOL APIENTRY 302 BOOL APIENTRY 303 303 VBoxDispDrvStrokePath(SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, 304 304 BRUSHOBJ *pbo, POINTL *pptlBrushOrg, LINEATTRS *plineattrs, MIX mix) … … 315 315 } 316 316 317 BOOL APIENTRY 317 BOOL APIENTRY 318 318 VBoxDispDrvFillPath(SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, 319 319 MIX mix, FLONG flOptions) … … 343 343 } 344 344 345 BOOL APIENTRY 345 BOOL APIENTRY 346 346 VBoxDispDrvTextOut(SURFOBJ *pso, STROBJ *pstro, FONTOBJ *pfo, CLIPOBJ *pco, 347 347 RECTL *prclExtra, RECTL *prclOpaque, BRUSHOBJ *pboFore, … … 498 498 } 499 499 500 BOOL APIENTRY 500 BOOL APIENTRY 501 501 VBoxDispDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, 502 502 RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4) … … 509 509 "pptlMask = %p, pbo = %p, pptlBrush = %p, rop4 = %08X", 510 510 psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4)); 511 511 512 512 bRc = EngBitBlt(getSurfObj(psoTrg), getSurfObj(psoSrc), psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); 513 513 VBVA_OPERATION(psoTrg, BitBlt, … … 537 537 538 538 BOOL APIENTRY 539 VBoxDispDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 539 VBoxDispDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 540 540 RECTL *prclDest, POINTL *pptlSrc) 541 541 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriverDDraw.cpp
r36867 r37423 63 63 /* Called to get supported DirectDraw caps */ 64 64 BOOL APIENTRY 65 VBoxDispDrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps, 65 VBoxDispDrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps, 66 66 VIDEOMEMORY *pvmList, DWORD *pdwNumFourCCCodes, DWORD *pdwFourCC) 67 67 { … … 181 181 pSurfaceCallBacks->dwFlags |= DDHAL_SURFCB32_UPDATEOVERLAY|DDHAL_SURFCB32_SETOVERLAYPOSITION; 182 182 } 183 } 183 } 184 184 #endif 185 185 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp
r36867 r37423 58 58 59 59 /* Allocate temp buffer */ 60 pMiniportModes = (PVIDEO_MODE_INFORMATION) 60 pMiniportModes = (PVIDEO_MODE_INFORMATION) 61 61 EngAllocMem(0, numModes.NumModes*numModes.ModeInformationLength, MEM_ALLOC_TAG); 62 62 … … 75 75 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); 76 76 } 77 77 78 78 /* Check which of miniport modes are supprted by display driver. 79 79 * Note: size of VIDEO_MODE_INFORMATION is returned by miniport driver in numModes.ModeInformationLength, … … 111 111 112 112 /* Allocate and zero output buffer */ 113 *ppModesTable = (PVIDEO_MODE_INFORMATION) 113 *ppModesTable = (PVIDEO_MODE_INFORMATION) 114 114 EngAllocMem(FL_ZERO_MEMORY, cSupportedModes*sizeof(VIDEO_MODE_INFORMATION), MEM_ALLOC_TAG); 115 115 … … 121 121 } 122 122 123 /* Copy supported modes to output buffer */ 123 /* Copy supported modes to output buffer */ 124 124 pMode = pMiniportModes; 125 125 for (j=0, i=0; i<numModes.NumModes; ++i) … … 238 238 239 239 memset(pInfo, 0, sizeof(QUERYHGSMIRESULT)); 240 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_HGSMI_INFO, NULL, 0, 240 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_HGSMI_INFO, NULL, 0, 241 241 pInfo, sizeof(QUERYHGSMIRESULT), &cbReturned); 242 242 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); … … 343 343 Assert(pDev->pointer.pAttrs); 344 344 345 dwrc = EngDeviceIoControl(pDev->hDriver, IOCTL_VIDEO_SET_POINTER_ATTR, pDev->pointer.pAttrs, pDev->pointer.cbAttrs, 345 dwrc = EngDeviceIoControl(pDev->hDriver, IOCTL_VIDEO_SET_POINTER_ATTR, pDev->pointer.pAttrs, pDev->pointer.cbAttrs, 346 346 NULL, 0, &cbReturned); 347 347 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); … … 384 384 LOGF_ENTER(); 385 385 386 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY), 386 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_SHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY), 387 387 pSMemInfo, sizeof(VIDEO_SHARE_MEMORY_INFORMATION), &cbReturned); 388 388 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); 389 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_SHARE_VIDEO_MEMORY", cbReturned, 389 VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_SHARE_VIDEO_MEMORY", cbReturned, 390 390 sizeof(VIDEO_SHARE_MEMORY_INFORMATION), VERR_DEV_IO_ERROR); 391 391 … … 400 400 LOGF_ENTER(); 401 401 402 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY), 402 dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY, pSMem, sizeof(VIDEO_SHARE_MEMORY), 403 403 NULL, 0, &cbReturned); 404 404 VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMouse.cpp
r36867 r37423 206 206 { 207 207 LOG(("BMF_32BPP")); 208 memcpy(psoRes->pvBits, psoBitmap->pvBits, min(psoRes->cjBits, psoBitmap->cjBits)); 208 memcpy(psoRes->pvBits, psoBitmap->pvBits, min(psoRes->cjBits, psoBitmap->cjBits)); 209 209 } 210 210 else … … 495 495 pDev->pointer.pAttrs->Enable |= VBOX_MOUSE_POINTER_VISIBLE; 496 496 } 497 497 498 498 if (fl & SPS_ALPHA) 499 499 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVBVA.cpp
r36867 r37423 323 323 { 324 324 pDev->hgsmi.bSupported = TRUE; 325 325 326 326 pDev->hgsmi.mp = callbacks; 327 327 pDev->vpAPI = portProcs; … … 398 398 } 399 399 400 /* Setup HGSMI heap in the display information area. 400 /* Setup HGSMI heap in the display information area. 401 401 * The area has some space reserved for HGSMI event flags in the beginning. 402 402 */ … … 561 561 */ 562 562 563 void vbvaDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 563 void vbvaDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 564 564 LONG x1, LONG y1, LONG x2, LONG y2, RECTL *prclBounds, MIX mix) 565 565 { … … 620 620 } 621 621 622 void vbvaDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 622 void vbvaDrvCopyBits(SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, 623 623 RECTL *prclDest, POINTL *pptlSrc) 624 624 { -
trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp
r36867 r37423 929 929 */ 930 930 931 void vrdpDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 931 void vrdpDrvLineTo(SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, 932 932 LONG x1, LONG y1, LONG x2, LONG y2, RECTL *prclBounds, MIX mix) 933 933 { … … 1231 1231 WARN(("unsupported: pstro->pwszOrg=%p, prclExtra=%p, pfo->flFontType & FO_TYPE_RASTER = 0x%08X, " 1232 1232 "pstro->cGlyphs = %d, pboOpaque->iSolidColor %p, pfo->iUniq = %p", 1233 pstro->pwszOrg, prclExtra, pfo->flFontType & FO_TYPE_RASTER, pstro->cGlyphs, 1233 pstro->pwszOrg, prclExtra, pfo->flFontType & FO_TYPE_RASTER, pstro->cGlyphs, 1234 1234 pboOpaque? pboOpaque->iSolidColor: 0, pfo->iUniq)); 1235 1235 vrdpReportDirtyRects(pDev, &clipRects); -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
r37207 r37423 38 38 39 39 /* Fills given video mode BPP related fields */ 40 static void 41 VBoxFillVidModeBPP(VIDEO_MODE_INFORMATION *pMode, ULONG bitsR, ULONG bitsG, ULONG bitsB, 40 static void 41 VBoxFillVidModeBPP(VIDEO_MODE_INFORMATION *pMode, ULONG bitsR, ULONG bitsG, ULONG bitsB, 42 42 ULONG maskR, ULONG maskG, ULONG maskB) 43 43 { … … 51 51 52 52 /* Fills given video mode structure */ 53 static void 53 static void 54 54 VBoxFillVidModeInfo(VIDEO_MODE_INFORMATION *pMode, ULONG xres, ULONG yres, ULONG bpp, ULONG index, ULONG yoffset) 55 55 { … … 327 327 } 328 328 329 /* Check registry for manually added modes, up to 128 entries is supported 329 /* Check registry for manually added modes, up to 128 entries is supported 330 330 * Give up on the first error encountered. 331 331 */ … … 537 537 uint32_t xres=0, yres=0, bpp=0, display=0; 538 538 539 /* Check if there's a pending display change request for this display */ 539 /* Check if there's a pending display change request for this display */ 540 540 if (VBoxQueryDisplayRequest(&xres, &yres, &bpp, &display) && (xres || yres || bpp)) 541 541 { … … 720 720 721 721 /* Add special mode to the table 722 * Note: Y offset isn't used for a host-supplied modes 722 * Note: Y offset isn't used for a host-supplied modes 723 723 */ 724 724 specialMode.ModeIndex = g_NumVideoModes+1; … … 728 728 /* Save special mode in the custom modes table */ 729 729 memcpy(&g_CustomVideoModes[pExt->iDevice], &specialMode, sizeof(VIDEO_MODE_INFORMATION)); 730 731 730 731 732 732 /* Make sure we've added 2nd mode if necessary to maintain table size */ 733 733 if (VBoxMPIsStartingUp(pExt, pExt->iDevice)) … … 793 793 794 794 static void 795 VBoxWddmBuildResolutionTable(PVIDEO_MODE_INFORMATION pModesTable, size_t tableSize, 795 VBoxWddmBuildResolutionTable(PVIDEO_MODE_INFORMATION pModesTable, size_t tableSize, 796 796 SIZE *pResolutions, uint32_t * pcResolutions) 797 797 { … … 836 836 static void 837 837 VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId, 838 PVBOXWDDM_VIDEOMODES_INFO pModes, VIDEO_MODE_INFORMATION *paAddlModes, 838 PVBOXWDDM_VIDEOMODES_INFO pModes, VIDEO_MODE_INFORMATION *paAddlModes, 839 839 UINT cAddlModes) 840 840 { … … 897 897 UINT bpp=8; 898 898 #else 899 UINT bpp=16; 899 UINT bpp=16; 900 900 #endif 901 901 for (; bpp<=32; bpp+=8) -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp
r36867 r37423 81 81 pMapInfo->VideoRamLength = pExt->pPrimary->u.primary.ulMaxFrameBufferSize; 82 82 83 pStatus->Status = VideoPortMapMemory(pExt, framebuffer, &pMapInfo->VideoRamLength, 83 pStatus->Status = VideoPortMapMemory(pExt, framebuffer, &pMapInfo->VideoRamLength, 84 84 &inIoSpace, &pMapInfo->VideoRamBase); 85 85 … … 157 157 pStatus->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION); 158 158 } 159 159 160 160 VBOXMPIOCTL_UNHIDE(); 161 161 LOGF_LEAVE(); … … 200 200 } 201 201 202 LOG(("width %d, height %d, bpp %d", 202 LOG(("width %d, height %d, bpp %d", 203 203 pModeInfo->VisScreenWidth, pModeInfo->VisScreenHeight, pModeInfo->BitsPerPlane)); 204 204 … … 216 216 217 217 /* Perform actual mode switch */ 218 VBoxVideoSetModeRegisters((USHORT)pModeInfo->VisScreenWidth, (USHORT)pModeInfo->VisScreenHeight, 218 VBoxVideoSetModeRegisters((USHORT)pModeInfo->VisScreenWidth, (USHORT)pModeInfo->VisScreenHeight, 219 219 (USHORT)pModeInfo->VisScreenWidth, (USHORT)pModeInfo->BitsPerPlane, 0, 0, 0); 220 220 … … 241 241 242 242 /* Called for IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES. 243 * Returns count of supported video modes and structure size in bytes, 243 * Returns count of supported video modes and structure size in bytes, 244 244 * used by the following IOCTL_VIDEO_QUERY_AVAIL_MODES. 245 245 */ … … 342 342 343 343 /* Visible and No Shape means show the pointer, 0 means hide pointer. 344 * It's enough to init only this field. 344 * It's enough to init only this field. 345 345 */ 346 346 attrs.Enable = bEnable ? VBOX_MOUSE_POINTER_VISIBLE:0; … … 612 612 bRC=FALSE; 613 613 } 614 614 615 615 LOGF_LEAVE(); 616 616 return bRC; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp
r36867 r37423 112 112 { 113 113 LOGF_ENTER(); 114 114 115 115 PVBOXMP_COMMON pCommon = VBoxCommonFromDeviceExt(pExt); 116 116 VBOXVIDEOPORTPROCS *pAPI = &pExt->u.primary.VideoPortProcs; … … 315 315 VbglGRFree(&req->header); 316 316 } 317 else 317 else 318 318 { 319 319 WARN(("VbglGRAlloc(VMMDevVideoAccelEnable) rc = %#xrc", rc)); … … 431 431 } 432 432 433 WARN(("Failed to allocate %d bytes", size)); 433 WARN(("Failed to allocate %d bytes", size)); 434 434 return VERR_GENERAL_FAILURE; 435 435 } … … 445 445 PVBOXMP_DEVEXT pExt = VBoxCommonToPrimaryExt(pCommon); 446 446 PEVENT pEvent = (PEVENT)pvEvent; 447 pExt->u.primary.VideoPortProcs.pfnSetEvent(pExt, pEvent); 447 pExt->u.primary.VideoPortProcs.pfnSetEvent(pExt, pEvent); 448 448 } 449 449 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPVideoPortAPI.cpp
r36896 r37423 64 64 } 65 65 66 static BOOLEAN 66 static BOOLEAN 67 67 vboxQueueDpcVoid(IN PVOID HwDeviceExtension, IN PMINIPORT_DPC_ROUTINE CallbackRoutine, IN PVOID Context) 68 68 {
Note:
See TracChangeset
for help on using the changeset viewer.