1、XOpenDisplay 打开xrandr句柄,参数是显示后端xorg或者xwayland,也就是localhost:0.0
dpy = XOpenDisplay (display_name); //XOpenDisplay(":0");if (dpy == NULL) {fprintf (stderr, "Can't open display %s\n", XDisplayName(display_name));exit (1);
}
2、RootWindow通过screen下标获取到显示器设备句柄
static int screen = -1;
if (screen < 0)screen = DefaultScreen (dpy);if (screen >= ScreenCount (dpy)) {fprintf (stderr, "Invalid screen number %d (display has %d)\n", screen, ScreenCount (dpy));exit (1);
}root = RootWindow (dpy, screen);
3、获取屏幕信息XRRScreenResources(同时获取XRRGetScreenSizeRange最大,最小分辨率,XRRGetScreenResourcesCurrent/XRRGetScreenResources当前分辨率)
static void
get_screen (Bool current)
{if (!has_1_2)fatal ("Server RandR version before 1.2\n");//已经获取到了,直接返回static XRRScreenResources *res;if (res) return;XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight);if (current)res = XRRGetScreenResourcesCurrent (dpy, root);elseres = XRRGetScreenResources (dpy, root);if (!res) fatal ("could not get screen resources");
}
4、获取crtcs
typedef struct _XRRPanning {Time timestamp;unsigned int left;unsigned int top;unsigned int width;unsigned int height;unsigned int track_left;unsigned int track_top;unsigned int track_width;unsigned int track_height;int border_left;int border_top;int border_right;int border_bottom;
} XRRPanning;typedef struct _XRRModeInfo {RRMode id;unsigned int width;unsigned int height;unsigned long dotClock;unsigned int hSyncStart;unsigned int hSyncEnd;unsigned int hTotal;unsigned int hSkew;unsigned int vSyncStart;unsigned int vSyncEnd;unsigned int vTotal;char *name;unsigned int nameLength;XRRModeFlags modeFlags;
} XRRModeInfo;typedef struct _XRRCrtcInfo {Time timestamp;int x, y;unsigned int width, height;RRMode mode;Rotation rotation;int noutput;RROutput *outputs;Rotation rotations;int npossible;RROutput *possible;
} XRRCrtcInfo;struct _crtc {name_t crtc;Bool changing;XRRCrtcInfo *crtc_info;XRRModeInfo *mode_info;XRRPanning *panning_info;int x;int y;Rotation rotation;output_t **outputs;int noutput;transform_t current_transform, pending_transform;
};typedef struct _crtc crtc_t;static void
get_crtcs (void)
{num_crtcs = res->ncrtc;crtcs = calloc (num_crtcs, sizeof (crtc_t)); //保存到crtcsif (!crtcs) fatal ("out of memory\n");for (int c = 0; c < res->ncrtc; c++){XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (dpy, res, res->crtcs[c]);XRRCrtcTransformAttributes *attr;XRRPanning *panning_info = NULL;if (has_1_3) {XRRPanning zero;memset(&zero, 0, sizeof(zero));panning_info = XRRGetPanning (dpy, res, res->crtcs[c]);zero.timestamp = panning_info->timestamp;if (!memcmp(panning_info, &zero, sizeof(zero))) {Xfree(panning_info);panning_info = NULL;}}set_name_xid (&crtcs[c].crtc, res->crtcs[c]);set_name_index (&crtcs[c].crtc, c);if (!crtc_info)fatal ("could not get crtc 0x%lx information\n", res->crtcs[c]);crtcs[c].crtc_info = crtc_info;crtcs[c].panning_info = panning_info;if (crtc_info->mode == None){crtcs[c].mode_info = NULL;crtcs[c].x = 0;crtcs[c].y = 0;crtcs[c].rotation = RR_Rotate_0;}if (XRRGetCrtcTransform (dpy, res->crtcs[c], &attr) && attr) {set_transform (&crtcs[c].current_transform, &attr->currentTransform, attr->currentFilter, attr->currentParams, attr->currentNparams);XFree (attr);}else{init_transform (&crtcs[c].current_transform);}copy_transform (&crtcs[c].pending_transform, &crtcs[c].current_transform);}
}