10

I need to know active screen DPI on Linux and Mac OS. I think on linux xlib might be useful, but I can't find a way how to get currect DPI. I want this information to get real screen size in inches.

Thanks in advance!

k3a
  • 1,296
  • 1
  • 15
  • 32
  • 4
    Be careful with this. DPI information is in general not reliable. Drivers can get it wrong and monitors' EDID information can lie, sometimes grossly. Make sure there is an override. – bobince Apr 12 '10 at 11:53

5 Answers5

9

On a mac, use CGDisplayScreenSize to get the screen size in millimeters.

uli
  • 224
  • 2
  • 6
6

In X on Linux, call XOpenDisplay() to get the Display, then use DisplayWidthMM() and DisplayHeightMM() together with DisplayWidth() and DisplayHeight() to compute the DPI.

On the Mac, there's almost certainly a more native API to use than X. Mac OS X does not run X Window by default, it has a native windowing environment.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • On a modern X server, the [RandR](http://www.x.org/wiki/Projects/XRandR/) extension will provide better information. – elmindreda Mar 20 '14 at 09:44
  • FYI [Answer for Windows](http://stackoverflow.com/questions/577736/how-to-obtain-the-correct-physical-size-of-the-monitor) – Brian Cannard Jan 16 '15 at 19:05
  • FYI: with X11, the hardware DPI can often be calculated wrong (especially when there are multiple screens with X11..) - when writing an application you should try to honour what the user has requested instead - see Xft.dpi. – totaam Sep 22 '16 at 06:46
4

I cobbled this together from xdpyinfo... Compile with: gcc -Wall -o getdpi getdpi.c -lX11

/* Get dots per inch 
 */
static void get_dpi(int *x, int *y)
{
    double xres, yres;
    Display *dpy;
    char *displayname = NULL;
    int scr = 0; /* Screen number */

    if( (NULL == x) || (NULL == y)){ return ; }

    dpy = XOpenDisplay (displayname);

    /*
     * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
     *
     *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
     *         = N pixels / (M inch / 25.4)
     *         = N * 25.4 pixels / M inch
     */
    xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / 
        ((double) DisplayWidthMM(dpy,scr)));
    yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / 
        ((double) DisplayHeightMM(dpy,scr)));

    *x = (int) (xres + 0.5);
    *y = (int) (yres + 0.5);

    XCloseDisplay (dpy);
}
jbal
  • 41
  • 1
  • I pasted this into a file and tried to compile this in OS X, but it gives me a few errors: http://hastebin.com/ocikivubed.pas. Any tips? – trusktr Oct 23 '14 at 06:44
2

You can use NSScreen to get the dimensions of the attached display(s) in pixels, but this won't give you the physical size/PPI of the display and in fact I don't think there are any APIs that will be able to do this reliably.

You can ask a window for its resolution like so:

NSDictionary* deviceDescription = [window deviceDescription];
NSSize resolution = [[deviceDescription objectForKey:NSDeviceResolution] sizeValue];

This will currently give you an NSSize of {72,72} for all screens, no matter what their actual PPI. The only thing that make this value change is changing the scaling factor in the Quartz Debug utility, or if Apple ever turns on resolution-independent UI. You can obtain the current scale factor by calling:

[[NSScreen mainScreen] userSpaceScaleFactor];

If you really must know the exact resolution (and I'd be interested to know why you think you do), you could create a screen calibration routine and have the user measure a line on-screen with an actual physical ruler. Crude, yes, but it will work.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
  • That's because answering the question is not possible, which is what my answer says. You CANNOT get a physically accurate measurement of the display using software alone. I don't think my answer deserved a ‑1. – Rob Keniger Aug 17 '10 at 00:27
1

Here's a platform independent way to get the screen DPI:

// Written in Java
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;

public final class DpiTest {

    public static void main(String[] args) {
        JFrame frame = new JFrame("DPI");
        JLabel label = new JLabel("Current Screen DPI: " + Toolkit.getDefaultToolkit().getScreenResolution());
        label.setBorder(new EmptyBorder(20, 20, 20, 20));
        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

}

You can download a compiled jar of this from here. After downloading, java -jar dpi.jar will show you the DPI.

HRJ
  • 17,079
  • 11
  • 56
  • 80