JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_HardwareLayer_getCurrentDPI()

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));
    }