Skip to content

Commit b80fcea

Browse files
committed
windows: Screen::getICCProfile
1 parent 9d6cc20 commit b80fcea

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

shared/java/Screen.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ public class Screen {
3535

3636
/**
3737
* <p>Get the ICC color profile data for this screen.</p>
38-
* <p>Currently only supported on macOS. Returns null on other platforms.</p>
38+
* <p>Currently supported on macOS and Windows. Returns null on other platforms.</p>
3939
*
4040
* @return ICC profile data as byte array, or null if not available
4141
*/
4242
@Nullable
4343
public byte[] getICCProfile() {
44-
if (Platform.CURRENT == Platform.MACOS) {
44+
if (Platform.CURRENT == Platform.MACOS || Platform.CURRENT == Platform.WINDOWS) {
4545
return _nGetICCProfile(_id);
4646
}
4747
return null;

windows/cc/Screen.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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

Comments
 (0)