in skiko/src/awtMain/cpp/linux/drawlayer.cc [121:192]
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_HardwareLayer_getCurrentDPI(JNIEnv *env, jobject canvas, jlong platformInfoPtr)
{
JAWT_X11DrawingSurfaceInfo *dsi_x11 = fromJavaPointer<JAWT_X11DrawingSurfaceInfo *>(platformInfoPtr);
Display *display = dsi_x11->display;
Window window = (Window)Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(env, canvas, platformInfoPtr);
XRRScreenResources * res = XRRGetScreenResourcesCurrentDynamic(display, window);
XRRCrtcInfo *crtc_info;
std::vector<MonitorInfo> monitors;
for (int i = 0; i < res->ncrtc; i++)
{
XRROutputInfo * output_info = XRRGetOutputInfoDynamic(display, res, res->outputs[i]);
if (output_info->connection || output_info->crtc == NULL) {
XRRFreeOutputInfoDynamic(output_info);
continue;
}
XRRCrtcInfo * crtc_info = XRRGetCrtcInfoDynamic(display, res, output_info->crtc);
MonitorInfo minfo;
minfo.x = crtc_info->x;
minfo.y = crtc_info->y;
minfo.wPx = crtc_info->width;
minfo.hPx = crtc_info->height;
if (crtc_info->rotation == RR_Rotate_90 || crtc_info->rotation == RR_Rotate_270)
{
minfo.wMm = output_info->mm_height;
minfo.hMm = output_info->mm_width;
}
else
{
minfo.wMm = output_info->mm_width;
minfo.hMm = output_info->mm_height;
}
// If XRandr does not provide a physical size, assume the X11 default 96 DPI
if (minfo.wMm <= 0 || minfo.hMm <= 0)
{
minfo.wMm = (int) (minfo.wPx * 25.4f / 96.f);
minfo.hMm = (int) (minfo.hPx * 25.4f / 96.f);
}
monitors.push_back(minfo);
XRRFreeCrtcInfoDynamic(crtc_info);
XRRFreeOutputInfoDynamic(output_info);
}
XRRFreeScreenResourcesDynamic(res);
if (monitors.size() == 1) {
return (jint)(monitors[0].wPx / (monitors[0].wMm / 25.4));
}
// Determining which monitor the current window is open on
XWindowAttributes xwa;
XGetWindowAttributes(display, window, &xwa);
int index = 0;
int maxIntersectSquare = 0;
for (int m = 0; m < monitors.size(); m++) {
int intersectSquare = getIntersectSquare(
xwa.x, xwa.y, xwa.width, xwa.height,
monitors[m].x, monitors[m].y, monitors[m].wPx, monitors[m].hPx
);
if (maxIntersectSquare < intersectSquare) {
maxIntersectSquare = intersectSquare;
index = m;
}
}
return (jint)(monitors[index].wPx / (monitors[index].wMm / 25.4));
}