1
0
forked from vitrine/wmaker

Create integration tests for WINGs WMPixmap API.

This commit is contained in:
2026-03-09 00:22:02 -04:00
parent c527a9f007
commit 6097395d45
36 changed files with 559 additions and 17 deletions

View File

@@ -10,6 +10,7 @@ insta-image = { version = "1.0", features = ["png"] }
png = "0.18"
tempdir = "0.3.7"
wings-rs = { path = "../wings-rs" }
wrlib-rs = { path = "../../wrlib-rs" }
wutil-rs = { path = "../../wutil-rs" }
x11 = "2.21.0"

View File

@@ -2,21 +2,12 @@ fn main() {
println!("cargo::rustc-link-search=../.libs");
println!("cargo::rustc-link-search=../../wrlib/.libs");
println!("cargo::rustc-link-arg=-lX11");
println!("cargo::rustc-link-arg-tests=-lwraster");
println!("cargo::rustc-link-arg-tests=-lWUtil");
println!("cargo::rustc-link-arg-tests=-lWINGs");
println!("cargo::rustc-link-arg-tests=-lXft");
println!("cargo::rustc-link-arg-tests=-lpango-1.0");
println!("cargo::rustc-link-arg-tests=-lpangoxft-1.0");
println!("cargo::rustc-link-arg-tests=-lpangoft2-1.0");
println!("cargo::rustc-link-arg-examples=-lWUtil");
println!("cargo::rustc-link-arg-examples=-lWINGs");
println!("cargo::rustc-link-arg-examples=-lwraster");
println!("cargo::rustc-link-arg-examples=-lX11");
println!("cargo::rustc-link-arg-examples=-lXft");
println!("cargo::rustc-link-arg-examples=-lpango-1.0");
println!("cargo::rustc-link-arg-examples=-lpangoxft-1.0");
println!("cargo::rustc-link-arg-examples=-lpangoft2-1.0");
println!("cargo::rustc-link-arg=-lWUtil");
println!("cargo::rustc-link-arg=-lWINGs");
println!("cargo::rustc-link-arg=-lwraster");
println!("cargo::rustc-link-arg=-lX11");
println!("cargo::rustc-link-arg=-lXft");
println!("cargo::rustc-link-arg=-lpango-1.0");
println!("cargo::rustc-link-arg=-lpangoxft-1.0");
println!("cargo::rustc-link-arg=-lpangoft2-1.0");
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 63
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 41
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 142
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 160
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 175
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 58
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 204
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 222
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 268
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 286
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 304
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 239
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 130
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,7 @@
---
source: tests/wmpixmap_tests.rs
assertion_line: 229
expression: app.xvfb.png_screenshot()
extension: png
snapshot_kind: binary
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,450 @@
use insta_image::assert_png_snapshot;
use std::{
ptr::{self, NonNull},
time::Instant,
};
use wings_rs::WINGsP::{
WMCreateBlendedPixmapFromFile, WMCreateBlendedPixmapFromRImage, WMCreatePixmap,
WMCreatePixmapFromFile, WMCreatePixmapFromRImage, WMCreateScaledBlendedPixmapFromFile,
WMDrawPixmap, WMReleasePixmap,
};
use wings_rs_tests::HeadlessApplication;
use wrlib_rs::ffi::{RColor, RLoadImage, RReleaseImage};
#[test]
fn draw_blank_pixmap() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let pixmap = NonNull::new(WMCreatePixmap(app.screen.as_ptr(), 128, 196, 24, 1)).unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("empty_window", app.xvfb.png_screenshot());
let gc = x11::xlib::XCreateGC(display, (*pixmap.as_ptr()).pixmap, 0, ptr::null_mut());
x11::xlib::XSetForeground(display, gc, 0);
x11::xlib::XFillRectangle(display, (*pixmap.as_ptr()).pixmap, gc, 0, 0, 128, 196);
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("empty_pixmap_on_window", app.xvfb.png_screenshot());
x11::xlib::XFreeGC(display, gc);
WMReleasePixmap(pixmap.as_ptr());
}
}
// WMCreatePixmapFromXPixmaps is not tested because it simply fills in struct
// fields. Coverage from other tests in this file should be adequate.
#[test]
fn draw_pixmap_from_file() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let pixmap = NonNull::new(WMCreatePixmapFromFile(
app.screen.as_ptr(),
c"tests/image_128x120.png".as_ptr(),
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_file_pixmap", app.xvfb.png_screenshot());
WMReleasePixmap(pixmap.as_ptr());
}
}
#[test]
fn draw_pixmap_from_r_image_no_mask() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let rimage = RLoadImage(
(*app.screen.as_ptr()).rcontext,
c"tests/image_128x120.png".as_ptr(),
0,
);
let pixmap =
NonNull::new(WMCreatePixmapFromRImage(app.screen.as_ptr(), rimage, 255)).unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 70, 74);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_r_image_no_mask", app.xvfb.png_screenshot());
WMReleasePixmap(pixmap.as_ptr());
}
}
#[test]
fn draw_pixmap_from_r_image_with_mask() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XBlackPixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let rimage = NonNull::new(RLoadImage(
(*app.screen.as_ptr()).rcontext,
c"tests/image_128x120_varying_alpha.png".as_ptr(),
255,
))
.unwrap();
// The threshold given to WMCreatePixmapFromRImage is compared against
// the image's alpha channel. Pixels whose transparency are below the
// threshold are masked out. This should draw a quartet of images with
// varying masks.
// Totally masked.
let pixmap_255 = NonNull::new(WMCreatePixmapFromRImage(
app.screen.as_ptr(),
rimage.as_ptr(),
255,
))
.unwrap();
WMDrawPixmap(pixmap_255.as_ptr(), win, 70, 74);
// Three bubbles masked.
let pixmap_200 = NonNull::new(WMCreatePixmapFromRImage(
app.screen.as_ptr(),
rimage.as_ptr(),
200,
))
.unwrap();
WMDrawPixmap(pixmap_200.as_ptr(), win, 200, 74);
// Two bubbles masked.
let pixmap_128 = NonNull::new(WMCreatePixmapFromRImage(
app.screen.as_ptr(),
rimage.as_ptr(),
128,
))
.unwrap();
WMDrawPixmap(pixmap_128.as_ptr(), win, 70, 200);
// Nothing masked.
let pixmap_0 = NonNull::new(WMCreatePixmapFromRImage(
app.screen.as_ptr(),
rimage.as_ptr(),
0,
))
.unwrap();
WMDrawPixmap(pixmap_0.as_ptr(), win, 200, 200);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_r_image_with_mask", app.xvfb.png_screenshot());
WMReleasePixmap(pixmap_255.as_ptr());
WMReleasePixmap(pixmap_200.as_ptr());
WMReleasePixmap(pixmap_128.as_ptr());
WMReleasePixmap(pixmap_0.as_ptr());
RReleaseImage(rimage.as_ptr());
}
}
#[test]
fn draw_blended_pixmap_from_r_image() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let rimage = RLoadImage(
(*app.screen.as_ptr()).rcontext,
c"tests/image_128x120.png".as_ptr(),
0,
);
let pixmap = NonNull::new(WMCreateBlendedPixmapFromRImage(
app.screen.as_ptr(),
rimage,
&RColor {
red: 255,
green: 0,
blue: 0,
alpha: 255,
} as *const _,
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 70, 74);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_r_image_no_mask", app.xvfb.png_screenshot());
WMReleasePixmap(pixmap.as_ptr());
}
}
#[test]
fn draw_blended_pixmap_from_file() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let pixmap = NonNull::new(WMCreatePixmapFromFile(
app.screen.as_ptr(),
c"tests/image_with_transparent_dot_128x120.png".as_ptr(),
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_file_blended_base_pixmap", app.xvfb.png_screenshot());
x11::xlib::XUnmapWindow(display, win);
WMReleasePixmap(pixmap.as_ptr());
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_blended_cleared_window",
app.xvfb.png_screenshot()
);
let pixmap = NonNull::new(WMCreateBlendedPixmapFromFile(
app.screen.as_ptr(),
c"tests/image_with_transparent_dot_128x120.png".as_ptr(),
&RColor {
red: 255,
green: 0,
blue: 0,
alpha: 255,
} as *const _,
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!("from_file_blended_with_red", app.xvfb.png_screenshot());
WMReleasePixmap(pixmap.as_ptr());
}
}
#[test]
fn draw_scaled_blended_pixmap_from_file() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let pixmap = NonNull::new(WMCreatePixmapFromFile(
app.screen.as_ptr(),
c"tests/image_with_transparent_dot_128x120.png".as_ptr(),
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_base_pixmap",
app.xvfb.png_screenshot()
);
x11::xlib::XUnmapWindow(display, win);
WMReleasePixmap(pixmap.as_ptr());
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_cleared_window",
app.xvfb.png_screenshot()
);
let pixmap = NonNull::new(WMCreateScaledBlendedPixmapFromFile(
app.screen.as_ptr(),
c"tests/image_with_transparent_dot_128x120.png".as_ptr(),
&RColor {
red: 255,
green: 0,
blue: 0,
alpha: 255,
} as *const _,
60,
64,
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_with_red",
app.xvfb.png_screenshot()
);
WMReleasePixmap(pixmap.as_ptr());
}
}
#[test]
fn draw_scaled_blended_pixmap_from_file_non_integral_scaling() {
let mut app = HeadlessApplication::new();
unsafe {
let display = (*app.screen.as_ptr()).display;
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
let pixmap = NonNull::new(WMCreatePixmapFromFile(
app.screen.as_ptr(),
c"tests/image_128x120.png".as_ptr(),
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_non_integral_base_pixmap",
app.xvfb.png_screenshot()
);
x11::xlib::XUnmapWindow(display, win);
WMReleasePixmap(pixmap.as_ptr());
let win = x11::xlib::XCreateSimpleWindow(
display,
(*app.screen.as_ptr()).rootWin,
0,
0,
512,
512,
1,
1,
x11::xlib::XWhitePixel(display, 0),
);
x11::xlib::XMapWindow(display, win);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_non_integral_cleared_window",
app.xvfb.png_screenshot()
);
let pixmap = NonNull::new(WMCreateScaledBlendedPixmapFromFile(
app.screen.as_ptr(),
// No alpha channel on this image, so no color blending happens.
c"tests/image_128x120.png".as_ptr(),
&RColor {
red: 255,
green: 0,
blue: 0,
alpha: 255,
} as *const _,
// Shrink by only a little bit, such that simple integer division
// might be thrown off. This test ensures that rescaling will
// actually happen.
110,
114,
))
.unwrap();
WMDrawPixmap(pixmap.as_ptr(), win, 64, 96);
while app.pump_event_queue(Instant::now()) {}
assert_png_snapshot!(
"from_file_scaled_blended_non_integral_scaled",
app.xvfb.png_screenshot()
);
WMReleasePixmap(pixmap.as_ptr());
}
}

View File

@@ -51,6 +51,7 @@ src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs
--allowlist-type "_WINGsConfiguration" \
--allowlist-item "^WMAlignment" \
--allowlist-item "^WMReliefType" \
--allowlist-function "^WM(Create|Release|Draw)Pixmap|^WMCreate(|Blended|ScaledBlended)PixmapFromFile|^WMCreate(|Blended)PixmapFromRImage" \
-o src/WINGsP.rs -- \
@PANGO_CFLAGS@ \
-I../../wrlib \

View File

@@ -12,6 +12,7 @@ src/ffi.rs: ../wrlib/wraster.h patch_ffi.sed Makefile
--allowlist-type "Bool" \
--allowlist-type "R(Context|ContextAttributes|Image|RenderingMode|ScalingFilter|StdColormapMode|ImageFormat|Color)" \
--allowlist-function "RGetClosestXColor" \
--allowlist-function "RLoadImage|RReleaseImage" \
-o src/ffi.rs \
-- \
-I../../wrlib \