// grp.SaveScreenShot: CPythonGraphic::SaveScreenShot queues a host frame request (ScreenShotHost.h) and // ScreenShotHost::WriteScreenShot runs the rest of 40250's SaveScreenShot on the frame: X8R8G8B8 rows -> // RGB -> SaveJPEG (jpeg_save, quality 100). #include "EterPythonLib/StdAfx.h" #include "EterPythonLib/PythonGraphic.h" #include "../../src/platform/EterPythonLib/ScreenShotHost.h" #include #include #include #include #include static int g_failures = 0; #define CHECK(cond) \ do { \ if (!(cond)) { \ std::fprintf(stderr, "%s:%d: CHECK(%s)\n", __FILE__, __LINE__, #cond); \ ++g_failures; \ } \ } while (0) static std::vector ReadFile(const std::string& path) { std::vector data; if (FILE* f = std::fopen(path.c_str(), "rb")) { int c; while ((c = std::fgetc(f)) != EOF) data.push_back(static_cast(c)); std::fclose(f); } return data; } int main() { CPythonGraphic graphic; // No host: 40250's GetBackBuffer failure path. ScreenShotHost::SetRequest(nullptr); CHECK(!graphic.SaveScreenShot("unused.jpg")); char dir[] = "/tmp/mt_screenshot_XXXXXX"; CHECK(mkdtemp(dir) != nullptr); const std::string path = std::string(dir) + "/shot.jpg"; std::vector requested; ScreenShotHost::SetRequest([&](const std::string& p) { requested.push_back(p); return true; }); CHECK(graphic.SaveScreenShot(path.c_str())); CHECK(requested.size() == 1 && requested[0] == path); CHECK(ReadFile(path).empty()); // written when the frame arrives, not by the call // 8x4 frame with a padded pitch; the padding bytes must not reach the image. const unsigned w = 8, h = 4, pitch = w * 4 + 16; std::vector frame(pitch * h, 0xAB); for (unsigned y = 0; y < h; ++y) for (unsigned x = 0; x < w; ++x) { std::uint8_t* px = &frame[y * pitch + x * 4]; px[0] = 0x20; px[1] = 0x80; px[2] = 0xE0; px[3] = 0xFF; // B, G, R, X } CHECK(ScreenShotHost::WriteScreenShot(requested[0].c_str(), frame.data(), w, h, pitch)); const std::vector jpeg = ReadFile(path); CHECK(jpeg.size() > 4); CHECK(jpeg.size() > 4 && jpeg[0] == 0xFF && jpeg[1] == 0xD8); CHECK(jpeg.size() > 4 && jpeg[jpeg.size() - 2] == 0xFF && jpeg[jpeg.size() - 1] == 0xD9); // An unwritable path is SaveJPEG's failure. CHECK(!ScreenShotHost::WriteScreenShot((std::string(dir) + "/missing/shot.jpg").c_str(), frame.data(), w, h, pitch)); ScreenShotHost::SetRequest(nullptr); std::remove(path.c_str()); rmdir(dir); if (g_failures) std::fprintf(stderr, "port_screenshot_test: %d failure(s)\n", g_failures); else std::puts("port_screenshot_test: ok"); return g_failures ? 1 : 0; }