Direct-framebuffer ink pipeline (stock-quality strokes), finger-wipe erase, growable scrolling canvas with color-ghost cleanup, bidirectional toggle with a persistent 4-finger return launcher, instant button feedback. Includes prebuilt aarch64 binaries (dist/), build/deploy/install scripts, a user guide, and a complete technical reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
47 lines
2.2 KiB
C++
47 lines
2.2 KiB
C++
// 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"
|