• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

98
Views
X11 - Xrandr me da monitores falsos

Estaba tratando de encontrar todos los monitores y sus coordenadas (width w , height h , x origin/top-left-most x , y y origin/top-left-most y ) y estaba usando este código, funciona bien en algunos sistemas . Pero en otros sistemas obtengo entradas falsas y duplicadas. ¿Sería capaz de evitar estas entradas de monitor duplicadas/falsas si probara si el monitor es un espejo? ¿Cómo probar si es un espejo?

Así que este es mi código:

 // start - get all monitor resolutions var screen = XRRGetScreenResources(getXOpenDisplay(), getDefaultRootWindow(getXOpenDisplay())); var noutputs = screen.noutput; for (var i=noutputs-1; i>=0; i--) { var info = XRRGetOutputInfo(getXOpenDisplay(), screen, screen.outputs[i]); if (info.connection == RR_Connected) { var ncrtcs = info.ncrtc; for (var j=ncrtcs-1; j>=0; j--) { var crtc_info = XRRGetCrtcInfo(getXOpenDisplay(), screen, infoCrtcs[j]); console.info('screen #' + i + ' mon#' + j + ' details:', crtc_info.x, crtc_info.y, crtc_info.width, crtc_info.height); collMonInfos.push({ x: crtc_info.x, y: crtc_info.y, w: crtc_info.width, h: crtc_info.height }); XRRFreeCrtcInfo(crtc_info); } } XRRFreeOutputInfo(info); } XRRFreeScreenResources(screen); console.info('JSON:', JSON.stringify(collMonInfos)); // end - get all monitor resolutions

Y esto genera esto para iniciar sesión:

 "screen #4 mon#0 details:" 0 0 0 0 "screen #3 mon#1 details:" 0 0 1920 1200 "screen #3 mon#0 details:" 1920 469 1366 768 "screen #2 mon#1 details:" 0 0 1920 1200 "screen #2 mon#0 details:" 1920 469 1366 768 "screen #1 mon#1 details:" 0 0 1920 1200 "screen #1 mon#0 details:" 1920 469 1366 768 "screen #0 mon#1 details:" 0 0 1920 1200 "screen #0 mon#0 details:" 1920 469 1366 768

Esto es todo en formato JSON:

 [{ "x": 0, "y": 0, "w": 0, "h": 0 }, { "x": 0, "y": 0, "w": 1920, "h": 1200 }, { "x": 1920, "y": 469, "w": 1366, "h": 768 }, { "x": 0, "y": 0, "w": 1920, "h": 1200 }, { "x": 1920, "y": 469, "w": 1366, "h": 768 }, { "x": 0, "y": 0, "w": 1920, "h": 1200 }, { "x": 1920, "y": 469, "w": 1366, "h": 768 }, { "x": 0, "y": 0, "w": 1920, "h": 1200 }, { "x": 1920, "y": 469, "w": 1366, "h": 768 }]

Realmente solo tengo 2 monitores, el de 1920x1200 y el de 1366x768. ¿Cómo es que todas las demás entradas y cómo probar para evitar (en lugar de filtrar en retrospectiva en función de duplicados o 0 h/w)?

about 3 years ago · Santiago Trujillo
2 answers
Answer question

0

Está iterando innecesariamente sobre cada salida y luego sobre cada monitor . Así que recibe entradas duplicadas. No tiene que llamar a XRRGetOutputInfo para cada salida, ya que todos los datos que necesita (número de monitores) se pueden encontrar en la estructura devuelta por XRRGetScreenResources . Aquí está el código C que funciona (al menos para mí):

 #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> #include <X11/extensions/Xrandr.h> int main(void) { Display *d = XOpenDisplay(getenv("DISPLAY")); Window w = DefaultRootWindow(d); XRRScreenResources *xrrr = XRRGetScreenResources(d, w); XRRCrtcInfo *xrrci; int i; int ncrtc = xrrr->ncrtc; for (i = 0; i < ncrtc; ++i) { xrrci = XRRGetCrtcInfo(d, xrrr, xrrr->crtcs[i]); printf("%dx%d+%d+%d\n", xrrci->width, xrrci->height, xrrci->x, xrrci->y); XRRFreeCrtcInfo(xrrci); } XRRFreeScreenResources(xrrr); return 0; }
about 3 years ago · Santiago Trujillo Report

0

La respuesta aceptada no funcionó para mí. La forma correcta que encontré de hacer esto fue esta:

 #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h> #include <X11/extensions/Xrandr.h> int main(void) { Display *display = XOpenDisplay(NULL); if (NULL == display) { perror("No DISPLAY in environment!"); exit(EXIT_FAILURE); } Window window = DefaultRootWindow(display); XRRScreenResources *screenr = XRRGetScreenResources(display, window); // This is the key right here. Use XRRScreenResources::noutput int output = screenr->noutput; for (int i = 0; i < output; ++i) { XRROutputInfo* out_info = XRRGetOutputInfo(display, screenr, screenr->outputs[i]); if (NULL != out_info && out_info->connection == RR_Connected) { XRRCrtcInfo* crt_info = XRRGetCrtcInfo(display, screenr, out_info->crtc); printf("%s\t%dx%d+%d+%d\n", out_info->name, crt_info->width, crt_info->height, crt_info->x, crt_info->y); XRRFreeCrtcInfo(crt_info); } XRRFreeOutputInfo(out_info); } XRRFreeScreenResources(screenr); XCloseDisplay(display); return 0; }

Como dije en el comentario del código, el truco es usar XRRScreenResources::noutput en lugar de XRRScreenResources::ncrtc

about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error