Mouse pointer problem in display driver

Hello,
I’m writing a display driver and I’m faced with the following problem.

I’m trying to get dirty regions and everything works fine, except the mouse
pointer. Somehow, if the pointer moves on the display’s area, I get correct
data for the bottom-right corner of the pointer, but the upper-left corner
is alway (0;0). This makes my dirty region a lot bigger every time I move
the pointer. I use device-managed surface and I implement DrvSetPointerShape
and DrvMovePointer calls. In DrvMovePointer I just call EngMovePointer with
the same parameters. The pointer shows up and works as expected, except the
dirty region problem. I used the debugger to trace which methods are being
called and I can see the DrvMovePointer is being called and followed by
several (2-3) DrvCopyBits calls. I also noticed that the last parameter of
the DrvMovePointer (RECTL *prcl) is always NULL. I read the MSDN
documentation about the mouse pointer and I know there are two ways to do
this. One way is the simulation by GDI. Is this the case here? And is it
normal, that the last parameter of DrvMovePointer is always NULL? Right
after DrvMovePointer, is it normal that DrvCopyBits are called with always
(0;0) upper-left coordinate at the fifth parameter (RECTL *prclDst)?
These DrvCopyBits calls make the drity region wrong.

I took a screenshot to show the problem. The red rectangle is the calculated
dirty region. If the pointer is on the display’s area, the dirty region’s
upper-left coordinate is always (0;0).

http://img244.imageshack.us/img244/1641/displayo.jpg

Please help me figure out what the problem is.

Thanks in advance,
R.B.

hu Norbicsek wrote:

I’m trying to get dirty regions and everything works fine, except the
mouse pointer. Somehow, if the pointer moves on the display’s area, I
get correct data for the bottom-right corner of the pointer, but the
upper-left corner is alway (0;0). This makes my dirty region a lot
bigger every time I move the pointer.

Right after DrvMovePointer, is it normal that DrvCopyBits are called
with always (0;0) upper-left coordinate at the fifth parameter (RECTL
*prclDst)? These DrvCopyBits calls make the drity region wrong.

Remember that DrvCopyBits is called to copy both TO the screen and FROM
the screen. Most cursor images today use alpha-blended shadows. To
simulate that on a device-managed surface, GDI has to grab a copy of the
old bits, blend the new pointer image in, and shove the resulting blend
back. My guess, from your description, is that you are seeing a
DrvCopyBits to copy the old screen bits into a memory bitmap. In that
case, the destination rectangle would be (0,0), but of course the
destination surface is not your surface. You have to make sure the API
is actually touching your surface before blindly copying the rectangle.

So, after a DrvMovePointer, I’d expect to see three CopyBits calls:

  • One to restore the desktop where the cursor used to be (memory -> screen)
  • One to fetch the untouched desktop where the new cursor will go
    (screen -> memory)
  • One to shove that region with the blended cursor back on the desktop
    (memory -> screen)


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes, the last parameter of the DrvMovePointer (RECTL *prcl) is always NULL.
the coordinates (upper-left and bottom-right) are correct,
If you want to snatch the screen of your screen, You should insure that it is your surface.
The follow are my debug output in my drivers.
EDesktop: DrvMovePointer( 108:-526) prcl(0)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 104:240: 127:266)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 0: 0: 23: 26)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 97:240: 120:266)

xxxxx@sina.com
Allen

You wrote:

Yes, the last parameter of the DrvMovePointer (RECTL *prcl) is
always NULL.
the coordinates (upper-left and bottom-right) are correct,
If you want to snatch the screen of your screen, You should insure
that it is your surface.
The follow are my debug output in my drivers.
EDesktop: DrvMovePointer( 108:-526) prcl(0)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 104:240: 127:266)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 0: 0: 23: 26)
EDesktop: DrvCopyBits( 0: 6) ( 0: 6) rc( 97:240: 120:266)

You aren't printing the source rectangle here. What are the first two set of numbers telling us? It seems clear that the second call is for a device bitmap, not for your surface.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes , I debug the dst rectangle
DebugPrint(“EDesktop: DrvCopyBits(%2X:%2X) (%2X:%2X) rc(%4d:%3d:%4d:%3d)\n”,
psoDst->iType, psoDst->iBitmapFormat, psoSrc->iType, psoSrc->iBitmapFormat,
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom);

Allen

the follow line in “DrvMovePointer”

DebugPrint(“EDesktop: DrvMovePointer(%4d:%4d) prcl(%X)\n”, x, y, prcl);

Allen

xxxxx@sina.com wrote:

Yes , I debug the dst rectangle
DebugPrint(“EDesktop: DrvCopyBits(%2X:%2X) (%2X:%2X) rc(%4d:%3d:%4d:%3d)\n”,
psoDst->iType, psoDst->iBitmapFormat, psoSrc->iType, psoSrc->iBitmapFormat,
prclDst->left, prclDst->top, prclDst->right, prclDst->bottom);

I thought you said you had a device managed surface. In the messages
you posted, iType is STYPE_BITMAP.

You should be able to tell whether the SURFOBJ really is your device by
checking psoDst->dhsurf. Theoretically, that should be 0 unless it is
your desktop surface. If dhsurf is 0, it’s not going to your desktop
surface, so you can ignore the dirty rectangle.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes, The surface is device managed, and psoDst->dhsurf is 0, It’s a virtual display driver only.
I ignore the rectangle and pass them to EngCopyBits.

Allen

xxxxx@sina.com wrote:

Yes, The surface is device managed, and psoDst->dhsurf is 0, It’s a virtual display driver only.
I ignore the rectangle and pass them to EngCopyBits.

Right, but the fact that dhsurf is 0 means that IT IS NOT YOUR PRIMARY
SURFACE. It’s a separate, temporary bitmap, which GDI will use to merge
the cursor image with the desktop bits. This request is NOT WRITING TO
YOUR DESKTOP. It’s copying FROM your desktop. Because of that, you
should NOT add this rectangle to your dirty list.

I’ve said this three times already. I don’t know how I can make it any
clearer.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

It is 0 always in my driver, My driver is an virtual display driver, It samed as maxivista.
I add this rectangle to my list by surface handle but doesn’t dhsurf.

Allen