Okay, I've spent the last days looking into this matter and I'd like to
suggest a way to get it started. So. This is the plan:
1. In winex11.drv:
-INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
+HBITMAP X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL force)
Lossy isn't used anywhere for LockDIBSection anyway. Force means that
the function will only lock if the DIB is already in AppMod. The
returned bitmap is ofcourse physDev->bitmap->hbitmap.
Rationale: If you lock the DIB to write on it it makes sense that the
function actually provides you with that DIB.
2. Export LockDIBSection/Unlock to gdi32.
Adding more exports is not nice but there really is no way around
that, right?
3. Move dc->funcs to dc->physDev->funcs. Many changes but mostly
mechanical work.
Rationale: This really belongs there. And I need it. :)
4. Now we write dibdrv.c for now just containing DIBDRV_Install
and DIBDRV_Remove. That function will go through the physDev->funcs
list and overwrite each function pointer which is actually
implemented with DIBDRV_PutPixel(), whatever.
DIBDRV_Install/DIBDRV_Remove will be called from
BITMAP_SelectObject() when we switch from non-DIB to DIB vice versa.
Note that we can't use DRIVER_load_driver here because of the
wanted "forward to original driver when not implemented".
For this we will need to extend the "for DIB objects" part in
BITMAPOBJ by
const DC_FUNCTIONS *orig_funcs;
DC_FUNCTIONS local_funcs;
where orig_funcs to the old physDev->funcs and the new physDev->funcs
points to &bmp->local_funcs.
5. In dibdrv.c we get us:
enum {
DIBDRV_MIXED, /* Choose driver depending on current AppMod */
DIBDRV_ALWAYS, /* Always use DIBDRV (unless function not
implemented) */
DIBDRV_NEVER /* Always use DC driver */
} DIB_Mode = DIBDRV_MIXED;
and DIB_Lock(PHYSDEV physDev) / DIB_Unlock(PHYSDEV).
Now, here comes the reason we need the HBITMAP from
LockDIBSection() and funcs inside PHYSDEV:
Since we don't have the DC here we have no way of
calling LockDIBSection(), forwarding to the original driver
if NEVER/MIXED or writing to the actual DIB in case of
MIXED/ALWAYS.
6. From this point we can start implementing one function at a time,
touching nothing but dibdrv.c.
So far so good. I did all those steps (except 3., I hacked around that
in my local tree) in a clean way and it works nice (for 6. I implemented
SetPixel() and tried that with a test-app).
I attached patches for the steps 1 2 and 4 so you can see where this is
going.
Comments?
Felix