void get_pointer(int *pointer_x, int *pointer_y) { int number_of_screens, i, result; Window *root_windows; Window window_returned; int root_x, root_y; int win_x, win_y; unsigned int mask_return; Display *display = XOpenDisplay(NULL); assert(display); number_of_screens = XScreenCount(display); root_windows = malloc(sizeof(Window) * number_of_screens); for (i = 0; i < number_of_screens; i++) { root_windows[i] = XRootWindow(display, i); } for (i = 0; i < number_of_screens; i++) { result = XQueryPointer(display, root_windows[i], &window_returned, &window_returned, &root_x, &root_y, &win_x, &win_y, &mask_return); if (result == True) { break; } } if (result != True) { fprintf(stderr, "No mouse found.\n"); return -1; } *pointer_x = root_x; *pointer_y = root_y; free(root_windows); XCloseDisplay(display); }
/** * The x server was changed */ static bool xshm_server_changed(obs_properties_t *props, obs_property_t *p, obs_data_t *settings) { UNUSED_PARAMETER(p); bool advanced = obs_data_get_bool(settings, "advanced"); int_fast32_t old_screen = obs_data_get_int(settings, "screen"); const char *server = obs_data_get_string(settings, "server"); obs_property_t *screens = obs_properties_get(props, "screen"); /* we want a real NULL here in case there is no string here */ server = (advanced && *server) ? server : NULL; obs_property_list_clear(screens); Display *dpy = XOpenDisplay(server); if (!dpy) { obs_property_set_enabled(screens, false); return true; } struct dstr screen_info; dstr_init(&screen_info); bool xinerama = xinerama_is_active(dpy); int_fast32_t count = (xinerama) ? xinerama_screen_count(dpy) : XScreenCount(dpy); for (int_fast32_t i = 0; i < count; ++i) { int_fast32_t x, y, w, h; x = y = w = h = 0; if (xinerama) xinerama_screen_geo(dpy, i, &x, &y, &w, &h); else x11_screen_geo(dpy, i, &w, &h); dstr_printf(&screen_info, "Screen %"PRIuFAST32" (%"PRIuFAST32 "x%"PRIuFAST32" @ %"PRIuFAST32 ",%"PRIuFAST32")", i, w, h, x, y); obs_property_list_add_int(screens, screen_info.array, i); } /* handle missing screen */ if (old_screen + 1 > count) { dstr_printf(&screen_info, "Screen %"PRIuFAST32" (not found)", old_screen); size_t index = obs_property_list_add_int(screens, screen_info.array, old_screen); obs_property_list_item_disable(screens, index, true); } dstr_free(&screen_info); XCloseDisplay(dpy); obs_property_set_enabled(screens, true); return true; }
Screen * XpGetScreenOfContext ( Display *dpy, XPContext print_context ) { xPrintGetContextScreenReq *req; xPrintGetContextScreenReply rep; XExtensionVersion *ext; XExtDisplayInfo *info = (XExtDisplayInfo *) xp_find_display (dpy); int i; Screen *checkScr; Screen *screen; int ok; if (XpCheckExtInit(dpy, XP_DONT_CHECK) == -1) return ( (Screen *) NULL ); /* No such extension */ LockDisplay (dpy); GetReq(PrintGetContextScreen,req); req->reqType = info->codes->major_opcode; req->printReqType = X_PrintGetContextScreen; req->printContext = print_context; if (! _XReply (dpy, (xReply *) &rep, 0, xTrue)) { UnlockDisplay(dpy); SyncHandle(); return ( (Screen *) NULL ); /* No such extension */ } /* * Pull rootWindow ID and convert to the corresponding * Screen rec. */ ok = False; for ( i = 0; i < XScreenCount(dpy); i++ ) { checkScr = XScreenOfDisplay(dpy, i); if ( XRootWindowOfScreen( checkScr ) == (Window) rep.rootWindow ) { ok = True; break; } } if (!ok) checkScr = (Screen *) NULL; UnlockDisplay(dpy); SyncHandle(); return ( (Screen *) checkScr ); }
int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool applicationOnly, bool edidInfo) { OVR_UNUSED4(handle, extended, applicationOnly, edidInfo); static int extendedCount = -1; static int numScreens = -1; Linux::LinuxDisplaySearchHandle* localHandle = (Linux::LinuxDisplaySearchHandle*)handle; if (localHandle == NULL) { OVR::LogError("[Linux Display] No search handle passed into GetDisplayCount. Return 0 rifts."); return 0; } if (X11Display == NULL) { OVR::LogError("[Linux Display] Unable to open X Display!"); return 0; } int screen_count = XScreenCount(X11Display); if (screen_count != numScreens) { numScreens = screen_count; extended = true; for (int screen = 0; screen < numScreens; ++screen) { // Be sure we're subscribed to config changes on all screens. XRRSelectInput(X11Display, XRootWindow(X11Display, screen), RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask); } } XEvent event_return = XEvent(); if (XCheckTypedEvent(X11Display, BaseRREvent + RRScreenChangeNotify, &event_return)) { extended = true; } if (extendedCount == -1 || extended) { extendedCount = discoverExtendedRifts(localHandle->cachedDescriptorArray, Linux::LinuxDisplaySearchHandle::DescArraySize, edidInfo); } localHandle->extended = true; localHandle->extendedDisplayCount = extendedCount; int totalCount = extendedCount; localHandle->application = false; localHandle->applicationDisplayCount = 0; localHandle->displayCount = totalCount; return totalCount; }
gboolean xdk_display_open(XdkDisplay * self) { g_return_val_if_fail(self, FALSE); XdkDisplayPrivate * priv = self->priv; if(! priv->peer) { priv->peer = XOpenDisplay(priv->display_string); priv->own_peer = TRUE; } if(! priv->peer) { goto end; } priv->n_screens = XScreenCount(priv->peer); int i; for(i = 0; i < priv->n_screens; i ++) { g_ptr_array_add( priv->screens, g_object_new( XDK_TYPE_SCREEN, "peer", XScreenOfDisplay(priv->peer, i), "display", self, NULL)); } if(! priv->event_retrieval_disabled) { xdk_display_add_watch(self); } Atom atom = XInternAtom(priv->peer, "WM_DELETE_WINDOW", FALSE); g_object_set_qdata( G_OBJECT(self), XDK_ATOM_WM_DELETE_WINDOW, GUINT_TO_POINTER(atom)); if(g_getenv("XDK_DUMP_EVENT")) { xdk_display_add_event_filter( self, (XdkEventFilter) xdk_display_dump_event, NULL); } goto end; close_display: XCloseDisplay(priv->peer); priv->peer = NULL; end: return NULL != priv->peer; }
static int get_screen_of_root(Display *dpy, Window root) { int screen = -1; /* Find the screen the window belongs to */ screen = XScreenCount(dpy); while (screen > 0) { screen--; if (root == RootWindow(dpy, screen)) { break; } } return screen; }
int main(int argc, char **argv) { if (argc > 1) (void)(argv[1]); char *display_name = NULL; Display *display = NULL; /* Connect to X server */ display = XOpenDisplay(display_name); if (display == NULL) { fprintf(stderr, "Couldn't connect to X server %s\n", display_name); exit(EXIT_FAILURE); } active_window_prop = XInternAtom(display, "_NET_ACTIVE_WINDOW", False); /* Get root windows for every screen */ int screen_count = XScreenCount(display); Window *root_wins = calloc(screen_count, sizeof(Window*)); for (int i = 0; i < screen_count; i++) { root_wins[i] = XRootWindow(display, i); active_window = get_active_window(display, root_wins[i]); activation_time = get_time(display, active_window); int result = XSelectInput(display, root_wins[i], PropertyChangeMask); if (result == 0) fprintf(stderr, "Failed to attach handler to window #%i\n", i); } free(root_wins); while (True) handle_event(display); /* Clear resources */ if (active_window_name) XFree(active_window_name); if (active_window_class) XFree(active_window_class); /* Disconnect from X server */ XCloseDisplay(display); exit(0); }
CCursor::CCursor() { display = XOpenDisplay(NULL); assert(display); XSetErrorHandler(XlibErrorHandler); number_of_screens = XScreenCount(display); fprintf(stderr, "There are %d screens available in this X session\n", number_of_screens); root_windows = static_cast<Window *>(malloc(sizeof(Window) * number_of_screens)); for (int i = 0; i < number_of_screens; i++) { root_windows[i] = XRootWindow(display, i); } //Display *displayMain = XOpenDisplay(NULL); XWindowAttributes gwa; Window root = DefaultRootWindow(display); XGetWindowAttributes(display, root, &gwa); width = gwa.width; height = gwa.height; }
/** * Get the properties for the capture */ static obs_properties_t xshm_properties(void) { obs_properties_t props = obs_properties_create(); int_fast32_t screen_max; Display *dpy = XOpenDisplay(NULL); screen_max = xinerama_is_active(dpy) ? xinerama_screen_count(dpy) : XScreenCount(dpy); screen_max = (screen_max) ? screen_max - 1 : 0; XCloseDisplay(dpy); obs_properties_add_int(props, "screen", obs_module_text("Screen"), 0, screen_max, 1); obs_properties_add_bool(props, "show_cursor", obs_module_text("CaptureCursor")); return props; }
int_fast32_t x11_screen_geo(Display *dpy, const int_fast32_t screen, int_fast32_t *w, int_fast32_t *h) { Screen *scr; if (!dpy || screen < 0 || screen >= XScreenCount(dpy)) goto fail; scr = XScreenOfDisplay(dpy, screen); if (!scr) goto fail; *w = XWidthOfScreen(scr); *h = XHeightOfScreen(scr); return 0; fail: *w = *h = 0; return -1; }
static jboolean Solaris_DGA_Available(Display *display) { Window root; int screen; Dga_drawable dgaDrawable; SolarisJDgaDevInfo * devinfo; /* return true if any screen supports DGA and we have a library for this type of framebuffer */ for (screen = 0; screen < XScreenCount(display); screen++) { root = RootWindow(display, screen); dgaDrawable = XDgaGrabDrawable(display, root); if (dgaDrawable != 0) { devinfo = getDevInfo(dgaDrawable); XDgaUnGrabDrawable(dgaDrawable); if (devinfo != NULL) { return JNI_TRUE; } } } return JNI_FALSE; }
int ga_xwin_init(const char *displayname, gaImage *gaimg) { int ignore = 0; // bzero(&__xshminfo, sizeof(__xshminfo)); // open display if((display = XOpenDisplay(displayname)) == NULL) { ga_error("cannot open display \"%s\"\n", displayname ? displayname : "DEFAULT"); return -1; } // check MIT extension if(XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore) ) { int major, minor; Bool pixmaps; if(XShmQueryVersion(display, &major, &minor, &pixmaps) == True) { ga_error("XShm extention version %d.%d %s shared pixmaps\n", major, minor, (pixmaps==True) ? "with" : "without"); } else { ga_error("XShm extension not supported.\n"); goto xcap_init_error; } } // get default screen screenNumber = XDefaultScreen(display); if((screen = XScreenOfDisplay(display, screenNumber)) == NULL) { ga_error("cannot obtain screen #%d\n", screenNumber); goto xcap_init_error; } // width = XDisplayWidth(display, screenNumber); height = XDisplayHeight(display, screenNumber); depth = XDisplayPlanes(display, screenNumber); ga_error("X-Window-init: dimension: %dx%dx%d @ %d/%d\n", width, height, depth, screenNumber, XScreenCount(display)); // if((image = XShmCreateImage(display, XDefaultVisual(display, screenNumber), depth, ZPixmap, NULL, &__xshminfo, width, height)) == NULL) { ga_error("XShmCreateImage failed.\n"); goto xcap_init_error; } // if((__xshminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line*image->height, IPC_CREAT | 0777)) < 0) { perror("shmget"); goto xcap_init_error; } // __xshminfo.shmaddr = image->data = (char*) shmat(__xshminfo.shmid, 0, 0); __xshminfo.readOnly = False; if(XShmAttach(display, &__xshminfo) == 0) { ga_error("XShmAttach failed.\n"); goto xcap_init_error; } // __xshmattached = true; rootWindow = XRootWindow(display, screenNumber); gaimg->width = image->width; gaimg->height = image->height; gaimg->bytes_per_line = image->bytes_per_line; // return 0; // xcap_init_error: ga_xwin_deinit(); return -1; }
int main(int argc, const char *argv[]) { /* RUN AS DAEMON pid_t pid; if((pid = fork())) return(pid < 0); */ int ret_val = EXIT_FAILURE; int is_tracking = 0; int has_face; //XLIB VAR Init Display* display = XOpenDisplay(NULL); assert(display); //int Screen_Count = XScreenCount(display); int Screen_Count = XScreenCount(display); //For laptop Window* window = (Window *)malloc(sizeof(Window)*Screen_Count); Window ret; Mouse mouse; unsigned int mask; int i; //Capture Init CvCapture* capture = cvCaptureFromCAM(-1); CvMemStorage* mem_storage = cvCreateMemStorage(0); CvHaarClassifierCascade* haarclassifier_face = (CvHaarClassifierCascade*)cvLoad(CASCADE_XML_FILENAME_FACE, 0, 0, 0); CvHaarClassifierCascade* haarclassifier_nose = (CvHaarClassifierCascade*)cvLoad(CASCADE_XML_FILENAME_NOSE, 0, 0, 0); CvHaarClassifierCascade* haarclassifier_eyel = (CvHaarClassifierCascade*)cvLoad(CASCADE_XML_FILENAME_EYEL, 0, 0, 0); CvHaarClassifierCascade* haarclassifier_eyer = (CvHaarClassifierCascade*)cvLoad(CASCADE_XML_FILENAME_EYER, 0, 0, 0); IplImage* image; //cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH, 1280); //cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT, 1024); int res_w = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH); int res_h = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT); //double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); int counter = 0; printf("Capturing : %dx%d \n", res_w, res_h); cvNamedWindow("Window", CV_WINDOW_NORMAL); CvRect tracking_window; CvPoint nosetip, lefteye, righteye; CvRect face, l_eye, r_eye, nose; TrackObject face_obj; //isophote_init(); while(1) { for(i = 0; i < Screen_Count; i++) { window[i] = XRootWindow(display, i); if(XQueryPointer(display, window[i], &ret, &ret, &mouse.root.x, &mouse.root.y, &mouse.win.x, &mouse.win.y, &mask)) break; } has_face = 0; image = cvQueryFrame(capture); if(is_tracking && CAMSHIFT) { //CAMSHIFT if(CAMSHIFT_MAX_ITER > camshift(image, &face_obj)) continue; has_face = 1; cvEllipseBox(image, face_obj.track_box, CV_RGB(255, 0, 0), 3, CV_AA, 0); tracking_window = face_obj.track_window; tracking_window.y += tracking_window.height*0.2; tracking_window.height *= 0.4; tracking_window.width *= 0.6; } else if(!Haar_Detect(image, haarclassifier_face, mem_storage, &face)) { /* tracking_window.x += tracking_window.width*0.1; tracking_window.width *= 0.8; tracking_window.height *= 0.8; */ cvSetImageROI(image, face); #ifdef DEBUG cvSaveImage("face.png", image, 0); #endif #if CAMSHIFT camshift_init(image, &face_obj); printf("Face Found, Start Tracking...\n"); #endif cvResetImageROI(image); is_tracking = 1; has_face = 1; } //Once face is detected if(has_face) { //Draw Face Area cvRectangle(image, cvPoint(face.x, face.y), cvPoint(face.x+face.width, face.y+face.height), CV_RGB(255, 255, 255), 3, 8, 0); //Estimate eyes and nose (NO ROI) nose = face; //nose nose.y += (1-NOSE_UPPER)*face.height; nose.height *= (NOSE_UPPER-NOSE_LOWER); nose.x += NOSE_LR*face.width; nose.width *= (1-2*NOSE_LR); l_eye = face; l_eye.y += (1-EYE_UPPER)*face.height; l_eye.height *= EYE_UPPER-EYE_LOWER; l_eye.x += EYE_LR*face.width; l_eye.width *= EYE_SIZE; r_eye = l_eye; r_eye.x += (1-2*EYE_LR)*face.width - r_eye.width; //detect nose /* NOSE AREA cvRectangle(image, cvPoint(tracking_window.x, tracking_window.y), cvPoint(tracking_window.x+tracking_window.width, tracking_window.y+tracking_window.height), CV_RGB(0, 255, 0), 3, 8, 0); */ cvSetImageROI(image, nose); if(!Haar_Detect(image, haarclassifier_nose, mem_storage, &tracking_window)) { nosetip = CALC_POINT(tracking_window); cvRectangle(image, cvPoint(nosetip.x-3, nosetip.y-3), cvPoint(nosetip.x+3, nosetip.y+3), CV_RGB(255, 0, 0), 3, 8, 0); nosetip.x += cvGetImageROI(image).x; nosetip.y += cvGetImageROI(image).y; } #ifdef POS_DISPLAY printf("Nose: %d, %d ", nosetip.x, nosetip.y); #endif /* NOSE 2 cvRectangle(image, cvPoint(tracking_window.x, tracking_window.y), cvPoint(tracking_window.x+tracking_window.width, tracking_window.y+tracking_window.height), CV_RGB(0, 255, 0), 3, 8, 0); */ //no nose detected, use kalman //find pupil using isophote curvature //LEFT EYE cvSetImageROI(image, l_eye); #ifdef USE_HAAR_REFINE if(!Haar_Detect(image, haarclassifier_eyel, mem_storage, &tracking_window)) { l_eye.x += tracking_window.x; l_eye.y += tracking_window.y; l_eye.width = tracking_window.width; l_eye.height = tracking_window.height; //printf("eye:%d, %d @ %d, %d\n", l_eye.x, l_eye.y, l_eye.x, l_eye.y); cvSetImageROI(image, l_eye); } #endif cvRectangle(image, cvPoint(0, 0), cvPoint(l_eye.width, l_eye.height), CV_RGB(0, 0, 255), 3, 8, 0); #ifdef DEBUG cvSaveImage("lefteye.png", image, 0); #endif #ifdef CENTERMAP calc_stable_ic(image, &tracking_window); //cvRectangle(image, cvPoint(tracking_window.x, tracking_window.y), // cvPoint(tracking_window.x+tracking_window.width, tracking_window.y+tracking_window.height), // CV_RGB(255, 0, 0), 3, 8, 0); cvCircle(image, CALC_POINT(tracking_window),3, CV_RGB(255, 0, 0), 1, 8, 0); //l_eye.x += CALC_POINT(tracking_window).x - PUPIL_SIZE/2; //l_eye.y += CALC_POINT(tracking_window).y - PUPIL_SIZE/2; lefteye.x = tracking_window.x+PUPIL_SIZE/2+l_eye.x; lefteye.y = tracking_window.y+PUPIL_SIZE/2+l_eye.y; #else cvCircle(image, lefteye = calc_heyecenter(image),3, CV_RGB(255, 0, 0), 1, 8, 0); lefteye.x += l_eye.x; lefteye.y += l_eye.y; #endif #ifdef POS_DISPLAY printf("LEYE: %d, %d ", tracking_window.x+PUPIL_SIZE/2+l_eye.x, tracking_window.y+PUPIL_SIZE/2+l_eye.y); #endif //RIGHT EYE cvSetImageROI(image, r_eye); #ifdef USE_HAAR_REFINE if(!Haar_Detect(image, haarclassifier_eyer, mem_storage, &tracking_window)) { r_eye.x += tracking_window.x; r_eye.y += tracking_window.y; r_eye.width = tracking_window.width; r_eye.height = tracking_window.height; //printf("right eye:%d, %d @ %d, %d\n", r_eye.x, r_eye.y, r_eye.x, r_eye.y); cvSetImageROI(image, r_eye); } #endif cvRectangle(image, cvPoint(0, 0), cvPoint(r_eye.width, r_eye.height), CV_RGB(0, 0, 255), 3, 8, 0); /* counter++; char filename[32]; sprintf(filename, "%d.png", counter); cvSaveImage(filename, image, 0); */ #ifdef DEBUG cvSaveImage("right.png", image, 0); #endif #ifdef CENTERMAP calc_stable_ic(image, &tracking_window); cvCircle(image, CALC_POINT(tracking_window),3, CV_RGB(255, 0, 0), 1, 8, 0); righteye.x = tracking_window.x+PUPIL_SIZE/2+r_eye.x; righteye.y = tracking_window.y+PUPIL_SIZE/2+r_eye.y+300; #else cvCircle(image, righteye = calc_heyecenter(image),3, CV_RGB(255, 0, 0), 1, 8, 0); righteye.x += r_eye.x; righteye.y += r_eye.y; #endif #ifdef POS_DISPLAY printf("REYE: %d, %d \r", tracking_window.x+PUPIL_SIZE/2+r_eye.x, tracking_window.y+PUPIL_SIZE/2+r_eye.y); #endif cvResetImageROI(image); } cvShowImage("Window", image); //printf("%d %d %d %d : %d \r", mouse.root.x, mouse.root.y, mouse.win.x, mouse.win.y, i); fflush(stdout); /* mouse.win.x = X_A0*(lefteye.x-nosetip.x+42)*LREYE_WEIGHT+X_A0*(righteye.x-nosetip.x-52)*(1-LREYE_WEIGHT) +1920*(1-LREYE_WEIGHT); mouse.win.y = Y_A0*(lefteye.y-nosetip.y+74)*LREYE_WEIGHT+Y_A0*(righteye.y-nosetip.y+65)*(1-LREYE_WEIGHT) +1080*(1-LREYE_WEIGHT); //if(abs(mouse.win.x-mouse.root.x) < 10 && abs((mouse.win.y-mouse.root.y) < 10)) { mouse.root.x += mouse.win.x; mouse.root.y += mouse.win.y; mouse.root.x /= 2; mouse.root.y /= 2; XWarpPointer(display, window[i], window[i], 0, 0, 0, 0, mouse.root.x, mouse.root.y); } */ mouse.root.x = 1920+NOSE_AX*nosetip.x; mouse.root.y = -540+NOSE_AY*nosetip.y; mouse.root.x += X_A0*((lefteye.x+righteye.x)/2-nosetip.x); //mouse.root.y += Y_A0*((lefteye.y+righteye.y)/2-nosetip.y-73)+800; XWarpPointer(display, 0, window[i], 0, 0, 0, 0, mouse.root.x, mouse.root.y); printf("%d \r",X_A0*((lefteye.x+righteye.x)/2-nosetip.x)); //printf("\n%d %d %d %d : %d \r", mouse.root.x, mouse.root.y, mouse.win.x, mouse.win.y, i); //Save video //cvCreateVideoWriter if(cvWaitKey(30) == 'q') goto RELEASE_OpenCV_RESOURCE; //goto RELEASE_XLib_RESOURCE; // // // } ret_val = EXIT_SUCCESS; RELEASE_OpenCV_RESOURCE: #if CAMSHIFT camshift_free(&face_obj); #endif cvDestroyWindow("Window"); /* Let OS Handle It ! cvReleaseImage(&image); cvReleaseHaarClassifierCascade(&haarclassifier_eyer); cvReleaseHaarClassifierCascade(&haarclassifier_eyel); cvReleaseHaarClassifierCascade(&haarclassifier_nose); cvReleaseHaarClassifierCascade(&haarclassifier_face); cvReleaseMemStorage(&mem_storage); cvReleaseCapture(&capture); */ RELEASE_XLib_RESOURCE: free(window); XCloseDisplay(display); exit(ret_val); }
// INPUT display // OUTPUT int (nb of screens) CAMLprim value caml_xscreen_count(value disp) { CAMLparam1(disp); CAMLreturn(Val_int(XScreenCount((Display*) disp))); }
static Status Validate(Display *dpy, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, bool *found_port, int *screen, int *chroma_format, int *mc_type, int *surface_flags, unsigned short *subpic_max_w, unsigned short *subpic_max_h) { bool found_surface = false; XvAdaptorInfo *adaptor_info; unsigned int num_adaptors; int num_types; unsigned int max_width = 0, max_height = 0; Status ret; assert(dpy); assert(found_port); assert(screen); assert(chroma_format); assert(mc_type); assert(surface_flags); assert(subpic_max_w); assert(subpic_max_h); *found_port = false; for (int i = 0; i < XScreenCount(dpy); ++i) { ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info); if (ret != Success) return ret; for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) { for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) { XvMCSurfaceInfo *surface_info; if (adaptor_info[j].base_id + k != port) continue; *found_port = true; surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types); if (!surface_info) { XvFreeAdaptorInfo(adaptor_info); return BadAlloc; } for (int l = 0; l < num_types && !found_surface; ++l) { if (surface_info[l].surface_type_id != surface_type_id) continue; found_surface = true; max_width = surface_info[l].max_width; max_height = surface_info[l].max_height; *chroma_format = surface_info[l].chroma_format; *mc_type = surface_info[l].mc_type; *surface_flags = surface_info[l].flags; *subpic_max_w = surface_info[l].subpicture_max_width; *subpic_max_h = surface_info[l].subpicture_max_height; *screen = i; XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \ "[XvMC] screen=%u, port=%u\n" \ "[XvMC] id=0x%08X\n" \ "[XvMC] max width=%u, max height=%u\n" \ "[XvMC] chroma format=0x%08X\n" \ "[XvMC] acceleration level=0x%08X\n" \ "[XvMC] flags=0x%08X\n" \ "[XvMC] subpicture max width=%u, max height=%u\n", i, port, surface_type_id, max_width, max_height, *chroma_format, *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h); } free(surface_info); } } XvFreeAdaptorInfo(adaptor_info); } if (!*found_port) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n"); return XvBadPort; } if (!found_surface) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n"); return BadMatch; } if (width > max_width || height > max_height) { XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n", width, height, max_width, max_height); return BadValue; } if (flags != XVMC_DIRECT && flags != 0) { XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags); return BadValue; } return Success; }
static int _gfx_x11_init_monitors( int major, int minor) { /* Iterate over all screens */ Screen* def = XDefaultScreenOfDisplay(_gfx_x11.display); unsigned int count = XScreenCount(_gfx_x11.display); while(count--) { /* Get screen resources */ Screen* scr = XScreenOfDisplay(_gfx_x11.display, count); Window root = XRootWindowOfScreen(scr); XRRScreenResources* res = XRRGetScreenResources(_gfx_x11.display, root); RROutput prim = res->outputs[0]; /* Get primary if RandR 1.3 is supported */ if(major > 1 || (major == 1 && minor > 2)) prim = XRRGetOutputPrimary(_gfx_x11.display, root); /* Insert the screen's display modes */ size_t first = _gfx_x11_init_modes(scr, res); /* Iterate through outputs */ unsigned int i; for(i = 0; i < res->noutput; ++i) { /* Validate output */ XRROutputInfo* out = XRRGetOutputInfo(_gfx_x11.display, res, res->outputs[i]); if(out->connection != RR_Connected) { XRRFreeOutputInfo(out); continue; } /* Create new monitor */ XRRCrtcInfo* crtc = XRRGetCrtcInfo(_gfx_x11.display, res, out->crtc); int rot = crtc->rotation & (RR_Rotate_90 | RR_Rotate_270); GFX_X11_Monitor mon = { .screen = scr, .crtc = out->crtc, .mode = crtc->mode, .numModes = 0, .modes = malloc(sizeof(size_t) * out->nmode), .x = crtc->x, .y = crtc->y, .width = rot ? crtc->height : crtc->width, .height = rot ? crtc->width : crtc->height }; /* Retrieve output modes */ unsigned int j; if(mon.modes) for(j = 0; j < out->nmode; ++j) { GFX_X11_Mode* mode; for( mode = gfx_vector_at(&_gfx_x11.modes, first); mode != _gfx_x11.modes.end; mode = gfx_vector_next(&_gfx_x11.modes, mode)) { /* Also check if resolution isn't too big */ if( mode->id == out->modes[j] && mode->mode.width <= crtc->width && mode->mode.height <= crtc->height) { mon.modes[mon.numModes++] = gfx_vector_get_index( &_gfx_x11.modes, mode ); break; } } } /* Insert at beginning if primary */ GFXVectorIterator monPos = scr == def && res->outputs[i] == prim ? _gfx_x11.monitors.begin : _gfx_x11.monitors.end; monPos = gfx_vector_insert(&_gfx_x11.monitors, &mon, monPos); if(monPos == _gfx_x11.monitors.end) free(mon.modes); XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(out); } XRRFreeScreenResources(res); } /* Need at least one monitor */ return _gfx_x11.monitors.begin != _gfx_x11.monitors.end; } /******************************************************/ static GFXKey _gfx_x11_get_key( KeySym symbol) { /* Unicode numbers */ if(symbol >= XK_0 && symbol <= XK_9) return (GFXKey)(symbol - XK_0 + GFX_KEY_0); /* Keypad numbers */ if(symbol >= XK_KP_0 && symbol <= XK_KP_9) return (GFXKey)(symbol - XK_KP_0 + GFX_KEY_KP_0); /* Unicode capitals */ if(symbol >= XK_A && symbol <= XK_Z) return (GFXKey)(symbol - XK_A + GFX_KEY_A); /* Unicode lowercase */ if(symbol >= XK_a && symbol <= XK_z) return (GFXKey)(symbol - XK_a + GFX_KEY_A); /* Function keys */ if(symbol >= XK_F1 && symbol <= XK_F24) return (GFXKey)(symbol - XK_F1 + GFX_KEY_F1); /* Non-unicode */ switch(symbol) { case XK_VoidSymbol : return GFX_KEY_UNKNOWN; case XK_BackSpace : return GFX_KEY_BACKSPACE; case XK_Tab : return GFX_KEY_TAB; case XK_KP_Tab : return GFX_KEY_TAB; case XK_Clear : return GFX_KEY_CLEAR; case XK_Return : return GFX_KEY_RETURN; case XK_Pause : return GFX_KEY_PAUSE; case XK_Scroll_Lock : return GFX_KEY_SCROLL_LOCK; case XK_Escape : return GFX_KEY_ESCAPE; case XK_Delete : return GFX_KEY_DELETE; case XK_KP_Delete : return GFX_KEY_DELETE; case XK_Home : return GFX_KEY_HOME; case XK_KP_Home : return GFX_KEY_HOME; case XK_Left : return GFX_KEY_LEFT; case XK_KP_Left : return GFX_KEY_LEFT; case XK_Up : return GFX_KEY_UP; case XK_KP_Up : return GFX_KEY_UP; case XK_Right : return GFX_KEY_RIGHT; case XK_KP_Right : return GFX_KEY_RIGHT; case XK_Down : return GFX_KEY_DOWN; case XK_KP_Down : return GFX_KEY_DOWN; case XK_Page_Down : return GFX_KEY_PAGE_DOWN; case XK_KP_Page_Down : return GFX_KEY_PAGE_DOWN; case XK_Page_Up : return GFX_KEY_PAGE_UP; case XK_KP_Page_Up : return GFX_KEY_PAGE_UP; case XK_End : return GFX_KEY_END; case XK_KP_End : return GFX_KEY_END; case XK_Select : return GFX_KEY_SELECT; case XK_Print : return GFX_KEY_PRINT; case XK_Execute : return GFX_KEY_EXECUTE; case XK_Insert : return GFX_KEY_INSERT; case XK_KP_Insert : return GFX_KEY_INSERT; case XK_Menu : return GFX_KEY_MENU; case XK_Cancel : return GFX_KEY_CANCEL; case XK_Help : return GFX_KEY_HELP; case XK_Num_Lock : return GFX_KEY_NUM_LOCK; case XK_KP_Space : return GFX_KEY_SPACE; case XK_space : return GFX_KEY_SPACE; case XK_KP_Enter : return GFX_KEY_KP_RETURN; case XK_KP_Multiply : return GFX_KEY_KP_MULTIPLY; case XK_KP_Add : return GFX_KEY_KP_ADD; case XK_KP_Separator : return GFX_KEY_KP_SEPARATOR; case XK_KP_Subtract : return GFX_KEY_KP_SUBTRACT; case XK_KP_Decimal : return GFX_KEY_KP_DECIMAL; case XK_KP_Divide : return GFX_KEY_KP_DIVIDE; case XK_Shift_L : return GFX_KEY_SHIFT_LEFT; case XK_Shift_R : return GFX_KEY_SHIFT_RIGHT; case XK_Control_L : return GFX_KEY_CONTROL_LEFT; case XK_Control_R : return GFX_KEY_CONTROL_RIGHT; case XK_Alt_L : return GFX_KEY_ALT_LEFT; case XK_Alt_R : return GFX_KEY_ALT_RIGHT; case XK_Super_L : return GFX_KEY_SUPER_LEFT; case XK_Super_R : return GFX_KEY_SUPER_RIGHT; } return GFX_KEY_UNKNOWN; } /******************************************************/ static void _gfx_x11_create_key_table(void) { /* Get permitted keycodes and their symbols */ int minKey, maxKey; XDisplayKeycodes(_gfx_x11.display, &minKey, &maxKey); maxKey = maxKey > GFX_X11_MAX_KEYCODE ? GFX_X11_MAX_KEYCODE : maxKey; int numKeys = maxKey - minKey + 1; int symbolsPerKey; KeySym* symbols = XGetKeyboardMapping( _gfx_x11.display, minKey, numKeys, &symbolsPerKey ); /* Use the first symbol of all keycodes */ size_t i; for(i = minKey; i <= maxKey; ++i) _gfx_x11.keys[i] = _gfx_x11_get_key( symbols[(i - minKey) * symbolsPerKey]); XFree(symbols); }
void CWinSystemX11::UpdateResolutions() { CWinSystemBase::UpdateResolutions(); int numScreens = XScreenCount(m_dpy); g_xrandr.SetNumScreens(numScreens); bool switchOnOff = CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOSCREEN_BLANKDISPLAYS); m_userOutput = CSettings::GetInstance().GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR); if (m_userOutput.compare("Default") == 0) switchOnOff = false; if(g_xrandr.Query(true, !switchOnOff)) { XOutput *out = NULL; if (m_userOutput.compare("Default") != 0) { out = g_xrandr.GetOutput(m_userOutput); if (out) { XMode mode = g_xrandr.GetCurrentMode(m_userOutput); if (!mode.isCurrent && !switchOnOff) { out = NULL; } } } if (!out) { m_userOutput = g_xrandr.GetModes()[0].name; out = g_xrandr.GetOutput(m_userOutput); } if (switchOnOff) { // switch on output g_xrandr.TurnOnOutput(m_userOutput); // switch off other outputs std::vector<XOutput> outputs = g_xrandr.GetModes(); for (size_t i=0; i<outputs.size(); i++) { if (StringUtils::EqualsNoCase(outputs[i].name, m_userOutput)) continue; g_xrandr.TurnOffOutput(outputs[i].name); } } XMode mode = g_xrandr.GetCurrentMode(m_userOutput); if (mode.id.empty()) mode = g_xrandr.GetPreferredMode(m_userOutput); m_bIsRotated = out->isRotated; if (!m_bIsRotated) UpdateDesktopResolution(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP), 0, mode.w, mode.h, mode.hz); else UpdateDesktopResolution(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP), 0, mode.h, mode.w, mode.hz); CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strId = mode.id; CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).strOutput = m_userOutput; } else { m_userOutput = "No Output"; m_nScreen = DefaultScreen(m_dpy); int w = DisplayWidth(m_dpy, m_nScreen); int h = DisplayHeight(m_dpy, m_nScreen); UpdateDesktopResolution(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP), 0, w, h, 0.0); } // erase previous stored modes CDisplaySettings::GetInstance().ClearCustomResolutions(); CLog::Log(LOGINFO, "Available videomodes (xrandr):"); XOutput *out = g_xrandr.GetOutput(m_userOutput); if (out != NULL) { std::vector<XMode>::iterator modeiter; CLog::Log(LOGINFO, "Output '%s' has %" PRIdS" modes", out->name.c_str(), out->modes.size()); for (modeiter = out->modes.begin() ; modeiter!=out->modes.end() ; modeiter++) { XMode mode = *modeiter; CLog::Log(LOGINFO, "ID:%s Name:%s Refresh:%f Width:%d Height:%d", mode.id.c_str(), mode.name.c_str(), mode.hz, mode.w, mode.h); RESOLUTION_INFO res; res.iScreen = 0; // not used by X11 res.iWidth = mode.w; res.iHeight = mode.h; res.iScreenWidth = mode.w; res.iScreenHeight = mode.h; if (!m_bIsRotated) { res.iWidth = mode.w; res.iHeight = mode.h; } else { res.iWidth = mode.h; res.iHeight = mode.w; } if (mode.h>0 && mode.w>0 && out->hmm>0 && out->wmm>0) res.fPixelRatio = ((float)out->wmm/(float)mode.w) / (((float)out->hmm/(float)mode.h)); else res.fPixelRatio = 1.0f; CLog::Log(LOGINFO, "Pixel Ratio: %f", res.fPixelRatio); res.strMode = StringUtils::Format("%s: %s @ %.2fHz", out->name.c_str(), mode.name.c_str(), mode.hz); res.strOutput = out->name; res.strId = mode.id; res.iSubtitles = (int)(0.965*mode.h); res.fRefreshRate = mode.hz; res.bFullScreen = true; if (mode.h > 0 && ((float)mode.w / (float)mode.h >= 1.59)) res.dwFlags = D3DPRESENTFLAG_WIDESCREEN; else res.dwFlags = 0; g_graphicsContext.ResetOverscan(res); CDisplaySettings::GetInstance().AddResolutionInfo(res); } } CDisplaySettings::GetInstance().ApplyCalibrations(); }
OutputConfiguration getOutputConfiguration(Display* display,int screen,const char* outputName) { /* Use the display's default screen if the given screen index is invalid: */ bool matchScreen=screen>=0; if(screen<0) screen=DefaultScreen(display); /* Create a default output configuration by assuming the entire root window goes to a single output: */ OutputConfiguration result; result.screen=screen; result.sizeMm[0]=DisplayWidthMM(display,screen); result.sizeMm[1]=DisplayHeightMM(display,screen); result.domainOrigin[0]=0; result.domainOrigin[1]=0; result.domainSize[0]=DisplayWidth(display,screen); result.domainSize[1]=DisplayHeight(display,screen); result.frameInterval=0U; // Unknown frame rate #if VRUI_INTERNAL_CONFIG_HAVE_XRANDR /* Check if the X server on the other end of the display connection understands XRANDR version >= 1.2: */ int xrandrEventBase,xrandrErrorBase; if(!XRRQueryExtension(display,&xrandrEventBase,&xrandrErrorBase)) return result; int xrandrMajor,xrandrMinor; if(!XRRQueryVersion(display,&xrandrMajor,&xrandrMinor)||xrandrMajor<1||(xrandrMajor==1&&xrandrMinor<2)) return result; /* Query the display name if in verbose mode: */ std::string displayName; if(vruiVerbose) { displayName=DisplayString(display); bool haveColon=false; std::string::iterator dotIt=displayName.end(); for(std::string::iterator dnIt=displayName.begin();dnIt!=displayName.end();++dnIt) if(*dnIt==':') haveColon=true; else if(haveColon&&*dnIt=='.') dotIt=dnIt; displayName.erase(dotIt,displayName.end()); } /* Iterate through all X screens belonging to the X display connection: */ bool firstOutput=true; bool haveMatch=false; for(int testScreen=0;testScreen<XScreenCount(display)&&(!haveMatch||vruiVerbose);++testScreen) if(!matchScreen||testScreen==screen) { /* Get the screen's resources: */ XRRScreenResources* screenResources=XRRGetScreenResources(display,RootWindow(display,testScreen)); if(screenResources!=0) { /* Find the first CRT controller that has an output of the given name: */ for(int crtcIndex=0;crtcIndex<screenResources->ncrtc&&(!haveMatch||vruiVerbose);++crtcIndex) { /* Get the CRT controller's information structure: */ XRRCrtcInfo* crtcInfo=XRRGetCrtcInfo(display,screenResources,screenResources->crtcs[crtcIndex]); if(crtcInfo!=0) { /* Find the specification of the CRT controller's current mode: */ unsigned int frameInterval=0U; for(int modeIndex=0;modeIndex<screenResources->nmode;++modeIndex) { XRRModeInfo& mode=screenResources->modes[modeIndex]; if(mode.id==crtcInfo->mode) { #if 0 /* Dump full modeline of detected CRT controller: */ std::cout<<"\tModeline: "<<mode.dotClock<<' '<<mode.width<<' '<<mode.hSyncStart<<' '<<mode.hSyncEnd<<' '<<mode.hTotal<<' '<<mode.hSkew; std::cout<<' '<<mode.height<<' '<<mode.vSyncStart<<' '<<mode.vSyncEnd<<' '<<mode.vTotal<<std::endl; #endif /* Calculate CRT controller's frame interval: */ frameInterval=(unsigned int)(((unsigned long)(mode.hTotal*mode.vTotal)*1000000000UL+mode.dotClock/2)/mode.dotClock); } } /* Try all outputs driven by the CRT controller: */ for(int outputIndex=0;outputIndex<crtcInfo->noutput&&(!haveMatch||vruiVerbose);++outputIndex) { /* Get the output's information structure: */ XRROutputInfo* outputInfo=XRRGetOutputInfo(display,screenResources,crtcInfo->outputs[outputIndex]); if(vruiVerbose&&outputName!=0&&outputName[0]!='\0') { std::cout<<"\tFound output "<<outputInfo->name<<" on display "<<displayName<<'.'<<testScreen; std::cout<<" at "<<crtcInfo->width<<'x'<<crtcInfo->height<<'+'<<crtcInfo->x<<'+'<<crtcInfo->y; std::cout<<" @ "<<1000000000.0/double(frameInterval)<<"Hz ("<<frameInterval<<")"<<std::endl; } /* Check if this output matches the search parameter: */ bool matchesName=strcmp(outputInfo->name,outputName)==0; if(!matchesName||vruiVerbose) { /* Check if the output has an associated EDID property: */ int numProperties; Atom* properties=XRRListOutputProperties(display,crtcInfo->outputs[outputIndex],&numProperties); for(int propertyIndex=0;propertyIndex<numProperties;++propertyIndex) { char* propertyName=XGetAtomName(display,properties[propertyIndex]); if(strcasecmp(propertyName,"EDID")==0) { Atom propertyType; int propertyFormat; unsigned long numItems; unsigned long bytes_after; unsigned char* propertyValue; XRRGetOutputProperty(display,crtcInfo->outputs[outputIndex],properties[propertyIndex],0,100,False,False,AnyPropertyType,&propertyType,&propertyFormat,&numItems,&bytes_after,&propertyValue); if(propertyType==XA_INTEGER&&propertyFormat==8) { /* Check the EDID's checksum and header ID: */ unsigned char checksum=0; for(unsigned long i=0;i<numItems;++i) checksum+=propertyValue[i]; unsigned char edidHeaderId[8]={0x00U,0xffU,0xffU,0xffU,0xffU,0xffU,0xffU,0x00U}; bool headerOk=true; for(int i=0;i<8&&headerOk;++i) headerOk=propertyValue[i]==edidHeaderId[i]; if(checksum==0&&headerOk) { /* Find the monitor name among the extension blocks: */ unsigned char* blockPtr=propertyValue+0x36; for(int i=0;i<4&&(!haveMatch||vruiVerbose);++i,blockPtr+=18) if(blockPtr[0]==0x00U&&blockPtr[1]==0x00U&&blockPtr[2]==0x00U&&blockPtr[3]==0xfcU) { /* Extract the monitor name: */ char monitorName[14]; char* mnPtr=monitorName; for(unsigned char* namePtr=blockPtr+5;namePtr<blockPtr+18&&*namePtr!='\n';++namePtr,++mnPtr) *mnPtr=char(*namePtr); *mnPtr='\0'; if(vruiVerbose&&outputName!=0&&outputName[0]!='\0') { std::cout<<"\tFound monitor "<<monitorName<<" on output "<<outputInfo->name<<" on display "<<displayName<<'.'<<testScreen; std::cout<<" at "<<crtcInfo->width<<'x'<<crtcInfo->height<<'+'<<crtcInfo->x<<'+'<<crtcInfo->y; std::cout<<" @ "<<1000000000.0/double(frameInterval)<<"Hz"<<std::endl; } matchesName=matchesName||strcmp(monitorName,outputName)==0; } } } XFree(propertyValue); } XFree(propertyName); } XFree(properties); } if(firstOutput||matchesName) { /* Remember the output's configuration: */ result.screen=testScreen; result.sizeMm[0]=outputInfo->mm_width; result.sizeMm[1]=outputInfo->mm_height; result.domainOrigin[0]=crtcInfo->x; result.domainOrigin[1]=crtcInfo->y; result.domainSize[0]=crtcInfo->width; result.domainSize[1]=crtcInfo->height; result.frameInterval=frameInterval; firstOutput=false; haveMatch=matchesName||outputName==0||outputName[0]=='\0'; } XRRFreeOutputInfo(outputInfo); } XRRFreeCrtcInfo(crtcInfo); } } XRRFreeScreenResources(screenResources); } } if(!haveMatch&&outputName!=0&&outputName[0]!='\0') std::cerr<<"\tOutput \""<<outputName<<"\" not found on display "<<DisplayString(display)<<std::endl; #endif /* Check the result configuration for sanity: */ if(result.sizeMm[0]==0||result.sizeMm[1]==0) { /* Assign a default display size based on a fixed and uniform resolution: */ int dpi=96; // Seems to be a reasonable number if(vruiVerbose) std::cout<<"\tSelected output advertises zero physical size; using default resolution of "<<dpi<<" dpi"<<std::endl; for(int i=0;i<2;++i) result.sizeMm[i]=(254*result.domainSize[i]+dpi*5)/(dpi*10); } return result; }
static int discoverExtendedRifts(OVR::DisplayDesc* descriptorArray, int inputArraySize, bool /*edidInfo*/) { int result = 0; if (X11Display == NULL) { OVR::LogError("[Linux Display] Unable to open X Display!"); return 0; } Atom EDIDAtom = XInternAtom(X11Display, RR_PROPERTY_RANDR_EDID, False); int numScreens = XScreenCount(X11Display); for (int i = 0; i < numScreens; ++i) { Window sr = XRootWindow(X11Display, i); XRRScreenResources* screen = XRRGetScreenResources(X11Display, sr); for (int ii = 0; ii < screen->ncrtc; ++ii) { XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(X11Display, screen, screen->crtcs[ii]); if (0 == crtcInfo->noutput) { XRRFreeCrtcInfo(crtcInfo); continue; } bool foundOutput = false; RROutput output = crtcInfo->outputs[0]; for (int k = 0; k < crtcInfo->noutput; ++k) { XRROutputInfo* outputInfo = XRRGetOutputInfo(X11Display, screen, crtcInfo->outputs[k]); for (int kk = 0; kk < outputInfo->nmode; ++kk) { if (outputInfo->modes[kk] == crtcInfo->mode) { output = crtcInfo->outputs[k]; foundOutput = true; break; } } XRRFreeOutputInfo(outputInfo); if (foundOutput) { break; } } if (!foundOutput) { XRRFreeCrtcInfo(crtcInfo); continue; } XRROutputInfo* outputInfo = XRRGetOutputInfo(X11Display, screen, output); if (RR_Connected != outputInfo->connection) { XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); continue; } // Read EDID associated with crtc. uint8_t* data = NULL; int dataLen = 0; if (getXRRProperty(X11Display, output, EDIDAtom, &data, &dataLen) != 0) { // Identify rifts based on EDID. Linux::DisplayEDID edid; parseEdid(data, edid); XFree(data); data = NULL; // TODO: Remove either this 3rdParty call to read EDID data // or remove our own parsing of the EDID. Probably opt // to remove our parsing. MonitorInfo* mi = read_edid_data(X11Display, output); if (mi == NULL) { XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); continue; } if (edid.VendorName == "OVR") { if( result >= inputArraySize ) { delete mi; XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); return result; } XRRModeInfo* modeInfo = findModeByXID(screen, crtcInfo->mode); int width = modeInfo->width; int height = modeInfo->height; int x = crtcInfo->x; int y = crtcInfo->y; // Generate a device ID string similar Windows does it char device_id[32]; OVR_sprintf(device_id, 32, "%s%04d-%d", mi->manufacturer_code, mi->product_code, screen->crtcs[ii]); OVR::DisplayDesc& desc = descriptorArray[result++]; desc.ResolutionInPixels = Sizei(width, height); desc.DesktopDisplayOffset = Vector2i(x, y); strncpy(desc.DisplayID, device_id, sizeof(desc.DisplayID)-1); desc.DisplayID[sizeof(desc.DisplayID)-1] = 0; strncpy(desc.ModelName, edid.MonitorName, sizeof(desc.ModelName)-1); desc.ModelName[sizeof(desc.ModelName)-1] = 0; strncpy(desc.EdidSerialNumber, edid.SerialNumber, sizeof(desc.EdidSerialNumber)-1); desc.EdidSerialNumber[sizeof(desc.EdidSerialNumber)-1] = 0; bool tallScreen = (height > width); switch (crtcInfo->rotation) { default: desc.Rotation = tallScreen ? 270 : 0; break; case RR_Rotate_90: desc.Rotation = tallScreen ? 0 : 90; break; case RR_Rotate_180: desc.Rotation = tallScreen ? 90 : 180; break; case RR_Rotate_270: desc.Rotation = tallScreen ? 180 : 270; break; } switch (mi->product_code) { case 3: desc.DeviceTypeGuess = HmdType_DK2; break; case 2: desc.DeviceTypeGuess = HmdType_DKHDProto; break; case 1: desc.DeviceTypeGuess = HmdType_DK1; break; default: case 0: desc.DeviceTypeGuess = HmdType_Unknown; break; } // Hard-coded defaults in case the device doesn't have the // data itself. DK2 prototypes (0003) or DK HD Prototypes (0002). if ( desc.DeviceTypeGuess == HmdType_DK2 || desc.DeviceTypeGuess == HmdType_DKHDProto) { desc.ResolutionInPixels = Sizei(1920, 1080); } else { desc.ResolutionInPixels = Sizei(width, height); } } delete mi; mi = NULL; } else { XFree(data); } XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); } XRRFreeScreenResources(screen); } return result; }