简体   繁体   中英

Is it possible to find the screen resolution from within a C program under Linux?

I know I can get the screen resolution from the command line on Linux using xdpyinfo but is it also possible to do this from within a C program? If so how?

If xdpyinfo works for you, just use that. Create some pipes, fork() , connect the pipes, and exec(xdpyinfo) It's a gazillion times easier than figuring out libX11; someone's already done that work for you. This isn't the idiom I'd use, but it gets the idea across:

int filedes[2];
if (pipe(filedes) == -1) {
  perror("pipe");
  exit(1);
}

pid_t pid = fork();
if (pid == -1) {
  perror("fork");
  exit(1);
} else if (pid == 0) {
  while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
  close(filedes[1]);
  close(filedes[0]);
  execl(cmdpath, cmdname, (char*)0);
  perror("execl");
  _exit(1);
}
close(filedes[1]);

The while(...EINTR)) loop is just about guarding against interrupts during the file descriptor close and duplication.

Following @Pablo's advice (thanks Pablo!) I was able to hack xdpyinfo.c to get what I want. Demo code is:

#ifdef WIN32
#include <X11/Xwindows.h>
#endif

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

static void
print_screen_info(Display *dpy, int scr)
{
    /*
     * 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
     */

    double xres, yres;

    xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /
            ((double) DisplayWidthMM(dpy,scr)));
    yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /
            ((double) DisplayHeightMM(dpy,scr)));

    printf ("\n");
    printf ("screen #%d:\n", scr);
    printf ("  dimensions:    %dx%d pixels (%dx%d millimeters)\n",
            XDisplayWidth (dpy, scr),  XDisplayHeight (dpy, scr),
            XDisplayWidthMM(dpy, scr), XDisplayHeightMM (dpy, scr));
    printf ("  resolution:    %dx%d dots per inch\n",
            (int) (xres + 0.5), (int) (yres + 0.5));
}


int
main(int argc, char *argv[])
{
    Display *dpy;                        /* X connection */
    char *displayname = NULL;            /* server to contact */
    int i;                      

    dpy = XOpenDisplay (displayname);
    if (!dpy) {
        fprintf (stderr, "unable to open display \"%s\".\n",
                 XDisplayName (displayname));
        exit (1);
    }

    printf ("name of display:    %s\n", DisplayString (dpy));
    printf ("default screen number:    %d\n", DefaultScreen (dpy));
    printf ("number of screens:    %d\n", ScreenCount (dpy));

    for (i = 0; i < ScreenCount (dpy); i++) {
        print_screen_info (dpy, i);
    }

    XCloseDisplay (dpy);
    exit (0);
}

Compile with:

gcc test.c -lX11

Output looks like:

erpsim1:~/linux_lib/test> ./a.out 
name of display:    localhost:15.0
default screen number:    0
number of screens:    1

screen #0:
  dimensions:    4400x1400 pixels (1552x494 millimeters)
  resolution:    72x72 dots per inch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM