|
| 1 | +#include <jni.h> |
| 2 | +#include <windows.h> |
| 3 | +#include <icm.h> |
| 4 | +#include <fstream> |
| 5 | +#include <vector> |
| 6 | + |
| 7 | +extern "C" JNIEXPORT jbyteArray JNICALL Java_io_github_humbleui_jwm_Screen__1nGetICCProfile |
| 8 | + (JNIEnv* env, jclass jclass, jlong screenId) { |
| 9 | + HMONITOR monitor = reinterpret_cast<HMONITOR>(screenId); |
| 10 | + |
| 11 | + // monitor_info |
| 12 | + MONITORINFOEX monitor_info; |
| 13 | + ZeroMemory(&monitor_info, sizeof(monitor_info)); |
| 14 | + monitor_info.cbSize = sizeof(monitor_info); |
| 15 | + ::GetMonitorInfo(monitor, &monitor_info); |
| 16 | + |
| 17 | + // ICC profile path |
| 18 | + std::wstring profile_path; |
| 19 | + HDC hdc = ::CreateDC(monitor_info.szDevice, NULL, NULL, NULL); |
| 20 | + if (hdc) { |
| 21 | + DWORD path_length = MAX_PATH; |
| 22 | + WCHAR path[MAX_PATH + 1]; |
| 23 | + BOOL result = ::GetICMProfile(hdc, &path_length, path); |
| 24 | + ::DeleteDC(hdc); |
| 25 | + if (result) { |
| 26 | + profile_path = std::wstring(path); |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + if (profile_path.empty()) { |
| 31 | + return nullptr; |
| 32 | + } |
| 33 | + |
| 34 | + // Read ICC profile file |
| 35 | + std::ifstream file(profile_path, std::ios::binary | std::ios::ate); |
| 36 | + if (!file.is_open()) { |
| 37 | + return nullptr; |
| 38 | + } |
| 39 | + |
| 40 | + std::streamsize size = file.tellg(); |
| 41 | + file.seekg(0, std::ios::beg); |
| 42 | + |
| 43 | + std::vector<char> buffer(size); |
| 44 | + if (!file.read(buffer.data(), size)) { |
| 45 | + return nullptr; |
| 46 | + } |
| 47 | + |
| 48 | + // Create Java byte array |
| 49 | + jbyteArray result = env->NewByteArray(static_cast<jsize>(size)); |
| 50 | + if (result) { |
| 51 | + env->SetByteArrayRegion(result, 0, static_cast<jsize>(size), |
| 52 | + reinterpret_cast<const jbyte*>(buffer.data())); |
| 53 | + } |
| 54 | + |
| 55 | + return result; |
| 56 | +} |
0 commit comments