Exemplo n.º 1
0
static gboolean
output_initialize (MateRROutput *output, XRRScreenResources *res, GError **error)
{
    XRROutputInfo *info = XRRGetOutputInfo (
	DISPLAY (output), res, output->id);
    GPtrArray *a;
    int i;
    
#if 0
    g_print ("Output %lx Timestamp: %u\n", output->id, (guint32)info->timestamp);
#endif
    
    if (!info || !output->info)
    {
	/* FIXME: see the comment in crtc_initialize() */
	/* Translators: here, an "output" is a video output */
	g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_RANDR_ERROR,
		     _("could not get information about output %d"),
		     (int) output->id);
	return FALSE;
    }
    
    output->name = g_strdup (info->name); /* FIXME: what is nameLen used for? */
    output->current_crtc = crtc_by_id (output->info, info->crtc);
    output->width_mm = info->mm_width;
    output->height_mm = info->mm_height;
    output->connected = (info->connection == RR_Connected);
    output->connector_type = get_connector_type_string (output);

    /* Possible crtcs */
    a = g_ptr_array_new ();
    
    for (i = 0; i < info->ncrtc; ++i)
    {
	MateRRCrtc *crtc = crtc_by_id (output->info, info->crtcs[i]);
	
	if (crtc)
	    g_ptr_array_add (a, crtc);
    }
    g_ptr_array_add (a, NULL);
    output->possible_crtcs = (MateRRCrtc **)g_ptr_array_free (a, FALSE);
    
    /* Clones */
    a = g_ptr_array_new ();
    for (i = 0; i < info->nclone; ++i)
    {
	MateRROutput *mate_rr_output = mate_rr_output_by_id (output->info, info->clones[i]);
	
	if (mate_rr_output)
	    g_ptr_array_add (a, mate_rr_output);
    }
    g_ptr_array_add (a, NULL);
    output->clones = (MateRROutput **)g_ptr_array_free (a, FALSE);
    
    /* Modes */
    a = g_ptr_array_new ();
    for (i = 0; i < info->nmode; ++i)
    {
	MateRRMode *mode = mode_by_id (output->info, info->modes[i]);
	
	if (mode)
	    g_ptr_array_add (a, mode);
    }
    g_ptr_array_add (a, NULL);
    output->modes = (MateRRMode **)g_ptr_array_free (a, FALSE);
    
    output->n_preferred = info->npreferred;
    
    /* Edid data */
    output->edid_data = read_edid_data (output);
    
    XRRFreeOutputInfo (info);

    return TRUE;
}
Exemplo n.º 2
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;
}