test: Add X11 drawable grabbing test

This commit is contained in:
Kim Woelders 2021-11-21 14:43:34 +01:00
parent 21a4172e81
commit 008e4e9fd4
2 changed files with 321 additions and 0 deletions

View File

@ -10,6 +10,7 @@ CLEANFILES = file.c img_save-*.*
GTESTS += test_load
GTESTS += test_load_2
GTESTS += test_save
GTESTS += test_grab
AM_CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter
AM_CFLAGS += $(CFLAGS_ASAN)
@ -41,6 +42,9 @@ test_load_2_LDADD = $(LIBS) -lz
test_save_SOURCES = test_save.cpp
test_save_LDADD = $(LIBS)
test_grab_SOURCES = test_grab.cpp
test_grab_LDADD = $(LIBS)
TESTS_RUN = $(addprefix run-, $(GTESTS))
TEST_ENV = IMLIB2_LOADER_PATH=$(top_builddir)/src/modules/loaders/.libs

317
test/test_grab.cpp Normal file
View File

@ -0,0 +1,317 @@
#include <gtest/gtest.h>
#include <X11/Xutil.h>
#include <Imlib2.h>
typedef struct {
Display *dpy;
Window root;
Visual *vis;
Colormap cmap;
Visual *argb_vis;
Colormap argb_cmap;
int depth;
int scale;
const char *test;
} xd_t;
static xd_t xd;
int debug = 0;
#define D(...) if (debug) printf(__VA_ARGS__)
#define D2(...) if (debug > 1) printf(__VA_ARGS__)
static Visual *
_x11_vis_argb(void)
{
XVisualInfo *xvi, xvit;
int i, num;
Visual *vis;
xvit.screen = DefaultScreen(xd.dpy);
xvit.depth = 32;
xvit.c_class = TrueColor;
xvi = XGetVisualInfo(xd.dpy,
VisualScreenMask | VisualDepthMask | VisualClassMask,
&xvit, &num);
if (!xvi)
return NULL;
for (i = 0; i < num; i++)
{
if (xvi[i].depth == 32)
break;
}
vis = (i < num) ? xvi[i].visual : NULL;
XFree(xvi);
xd.argb_vis = vis;
xd.argb_cmap = XCreateColormap(xd.dpy, xd.root, vis, AllocNone);
return vis;
}
static void
_x11_init(int depth)
{
xd.dpy = XOpenDisplay(NULL);
if (!xd.dpy)
{
fprintf(stderr, "Can't open display\n");
exit(1);
}
xd.root = DefaultRootWindow(xd.dpy);
if (depth == 32)
{
xd.vis = _x11_vis_argb();
xd.cmap = xd.argb_cmap;
}
else
{
xd.vis = DefaultVisual(xd.dpy, DefaultScreen(xd.dpy));
xd.cmap = DefaultColormap(xd.dpy, DefaultScreen(xd.dpy));
}
imlib_context_set_display(xd.dpy);
imlib_context_set_visual(xd.vis);
imlib_context_set_colormap(xd.cmap);
}
static void
_x11_fini(void)
{
XCloseDisplay(xd.dpy);
}
static Pixmap
_pmap_mk_fill_solid(int w, int h, unsigned int color)
{
XGCValues gcv;
GC gc;
Pixmap pmap;
pmap = XCreatePixmap(xd.dpy, xd.root, w, h, xd.depth);
gcv.foreground = color;
gcv.graphics_exposures = False;
gc = XCreateGC(xd.dpy, pmap, GCForeground | GCGraphicsExposures, &gcv);
XFillRectangle(xd.dpy, pmap, gc, 0, 0, w, h);
XFreeGC(xd.dpy, gc);
return pmap;
}
static void
_img_dump(Imlib_Image im, const char *file)
{
static int seqn = 0;
char buf[1024];
snprintf(buf, sizeof(buf), file, seqn++);
imlib_context_set_image(im);
imlib_save_image(buf);
}
DATA32 color = 0;
static void
_test_grab_1(int w, int h, int x0, int y0)
{
Imlib_Image im;
DATA32 *dptr, pix, col;
int x, y, err;
int xs, ys, ws, hs;
char buf[128];
xs = xd.scale > 0 ? xd.scale * x0 : x0;
ws = xd.scale > 0 ? xd.scale * w : w;
#if 0
// FIXME - y scaling doesn't work
ys = xd.scale > 0 ? xd.scale * y0 : y0;
hs = xd.scale > 0 ? xd.scale * h : h;
#else
ys = y0;
hs = h;
#endif
if (xd.scale == 0)
im = imlib_create_image_from_drawable(None, x0, y0, w, h, 0);
else
im = imlib_create_scaled_image_from_drawable(None, x0, y0, w, h,
ws, hs, 0, 0);
imlib_context_set_image(im);
snprintf(buf, sizeof(buf), "%s-%%d.png", xd.test);
_img_dump(im, buf);
dptr = imlib_image_get_data_for_reading_only();
err = 0;
for (y = 0; y < hs; y++)
{
for (x = 0; x < ws; x++)
{
pix = *dptr++;
if (xs + x < 0 || ys + y < 0 || xs + x >= ws || ys + y >= hs)
{
#if 1
// FIXME - Pixels outside source drawable are not properly initialized
if (x0 != 0 || y0 != 0)
continue;
#endif
col = 0x00000000; // Use 0xff000000 if non-alpa
}
else
{
col = color;
}
if (pix != col)
{
D2("%3d,%3d (%3d,%3d): %08x != %08x\n",
x, y, x0, y0, pix, col);
err = 1;
}
}
}
EXPECT_FALSE(err);
imlib_free_image_and_decache();
}
static void
_test_grab_1(const char *test, int depth, int scale, int opt)
{
Pixmap pmap;
int w, h, d;
color = 0xffff0000;
_x11_init(depth);
xd.depth = depth;
xd.scale = scale;
xd.test = test;
w = 32;
h = 45;
pmap = _pmap_mk_fill_solid(w, h, color);
imlib_context_set_drawable(pmap);
switch (opt)
{
case 0:
_test_grab_1(w, h, 0, 0);
break;
case 1:
d = 1;
_test_grab_1(w, h, -d, -d);
_test_grab_1(w, h, -d, d);
_test_grab_1(w, h, d, d);
_test_grab_1(w, h, d, -d);
break;
}
XFreePixmap(xd.dpy, pmap);
_x11_fini();
}
#define ENABLE_S2 1
TEST(GRAB, grab_noof_24_s0)
{
_test_grab_1("grab_noof_24_s0", 24, 0, 0);
}
TEST(GRAB, grab_noof_24_s1)
{
_test_grab_1("grab_noof_24_s1", 24, 1, 0);
}
#if ENABLE_S2
TEST(GRAB, grab_noof_24_s2)
{
_test_grab_1("grab_noof_24_s2", 24, 2, 0);
}
#endif
TEST(GRAB, grab_noof_32_s0)
{
_test_grab_1("grab_noof_32_s0", 32, 0, 0);
}
TEST(GRAB, grab_noof_32_s1)
{
_test_grab_1("grab_noof_32_s1", 32, 1, 0);
}
#if ENABLE_S2
TEST(GRAB, grab_noof_32_s2)
{
_test_grab_1("grab_noof_32_s2", 32, 2, 0);
}
#endif
TEST(GRAB, grab_offs_24_s0)
{
_test_grab_1("grab_offs_24_s0", 24, 0, 1);
}
TEST(GRAB, grab_offs_24_s1)
{
_test_grab_1("grab_offs_24_s1", 24, 1, 1);
}
#if ENABLE_S2
TEST(GRAB, grab_offs_24_s2)
{
_test_grab_1("grab_offs_24_s2", 24, 2, 1);
}
#endif
TEST(GRAB, grab_offs_32_s0)
{
_test_grab_1("grab_offs_32_s0", 32, 0, 1);
}
TEST(GRAB, grab_offs_32_s1)
{
_test_grab_1("grab_offs_32_s1", 32, 1, 1);
}
#if ENABLE_S2
TEST(GRAB, grab_offs_32_s2)
{
_test_grab_1("grab_offs_32_s2", 32, 2, 1);
}
#endif
int
main(int argc, char **argv)
{
const char *s;
::testing::InitGoogleTest(&argc, argv);
for (argc--, argv++; argc > 0; argc--, argv++)
{
s = argv[0];
if (*s++ != '-')
break;
switch (*s)
{
case 'd':
while (*s++ == 'd')
debug++;
break;
}
}
return RUN_ALL_TESTS();
}