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


Reply via email to