// LD_PRELOAD trace shim: intercept EPFramebuffer::swapBuffers in libqsgepaper to
// learn the exact (contentType, screenMode, flags) the stock app uses for pen
// strokes. We define functions with the real mangled names so the dynamic loader
// interposes them, log the args, then chain to the real implementation.
//
// QRect is passed by value; its memory layout is {int x1,y1,x2,y2} (l,t,r,b), so
// we model it as a 16-byte POD to match the ABI without linking Qt. The enums and
// QFlags are all 4-byte int-sized.

#include <dlfcn.h>
#include <cstdio>

struct RawRect { int x1, y1, x2, y2; };

extern "C" {

// swapBuffers(QRect, EPContentType, EPScreenMode, QFlags<UpdateFlag>)
void _ZN13EPFramebuffer11swapBuffersE5QRect13EPContentType12EPScreenMode6QFlagsINS_10UpdateFlagEE(
    void *self, RawRect r, int contentType, int screenMode, int flags)
{
    static void (*real)(void *, RawRect, int, int, int) = nullptr;
    if (!real)
        real = (void (*)(void *, RawRect, int, int, int))dlsym(
            RTLD_NEXT,
            "_ZN13EPFramebuffer11swapBuffersE5QRect13EPContentType12EPScreenMode6QFlagsINS_10UpdateFlagEE");
    fprintf(stderr, "SWAPTRACE1 rect=(%d,%d)-(%d,%d) %dx%d content=%d screen=%d flags=%d\n",
            r.x1, r.y1, r.x2, r.y2, r.x2 - r.x1 + 1, r.y2 - r.y1 + 1,
            contentType, screenMode, flags);
    if (real) real(self, r, contentType, screenMode, flags);
}

// swapBuffers(const QRegion&, const EPContentMap&, const EPScreenModeMap&, QFlags<UpdateFlag>)
void _ZN13EPFramebuffer11swapBuffersERK7QRegionRK12EPContentMapRK15EPScreenModeMap6QFlagsINS_10UpdateFlagEE(
    void *self, const void *region, const void *contentMap, const void *modeMap, int flags)
{
    static void (*real)(void *, const void *, const void *, const void *, int) = nullptr;
    if (!real)
        real = (void (*)(void *, const void *, const void *, const void *, int))dlsym(
            RTLD_NEXT,
            "_ZN13EPFramebuffer11swapBuffersERK7QRegionRK12EPContentMapRK15EPScreenModeMap6QFlagsINS_10UpdateFlagEE");
    fprintf(stderr, "SWAPTRACE2 region=%p contentMap=%p modeMap=%p flags=%d\n",
            region, contentMap, modeMap, flags);
    if (real) real(self, region, contentMap, modeMap, flags);
}

} // extern "C"
