Пример #1
0
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);
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
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 );
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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);
}
Пример #8
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;
}
Пример #9
0
/**
 * 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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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);
}
Пример #14
0
// INPUT   display
// OUTPUT  int (nb of screens)
CAMLprim value
caml_xscreen_count(value disp)
{
  CAMLparam1(disp);
  CAMLreturn(Val_int(XScreenCount((Display*) disp)));
}
Пример #15
0
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;
}
Пример #16
0
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);
}
Пример #17
0
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();
}
Пример #18
0
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;
	}
Пример #19
0
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;
}