Пример #1
0
static display init(XRRScreenResources* sr, RROutput output)
{
	display result;

	XRROutputInfo* oi = XRRGetOutputInfo(g_display, sr, output);
	if (oi->connection == RR_Connected)
	{
		result.scale = 1;
		result.name = oi->name;
		result.color_depth = XDefaultDepth(g_display, g_screen);
		result.color_depth_per_component = result.color_depth >= 24? 8 : 0;

		result.crtc = oi->crtc;
		result.output = output;

		XRRCrtcInfo* ci = XRRGetCrtcInfo(g_display, sr, oi->crtc);
		result.rect.left = ci->x;
		result.rect.top = ci->y;
		result.rect.width = ci->width;
		result.rect.height = ci->height;
		if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
		{
			std::swap(result.rect.width, result.rect.height);
		}
		XRRFreeCrtcInfo(ci);

		result.work_rect = result.rect;
	}
	XRRFreeOutputInfo(oi);
	return result;
}
Пример #2
0
static void dumpOutput(const char *prefix, Display *dpy, int screen_idx, XRRScreenResources *resources, int outputIdx, RROutput output) {
    int i, j, primIdx=0;
    Window root = RootWindow(dpy, screen_idx);
    RROutput pxid = XRRGetOutputPrimary (dpy, root);
    int isPrim =0;
    if ( None != pxid && pxid == output ) {
        primIdx = i;
        isPrim = 1;
    }
    XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output);
    fprintf(stderr, "%s: Output[%d]: id %#lx, crtx 0x%lX, name %s (%d), %lux%lu, ncrtc %d, nclone %d, nmode %d (preferred %d), primary %d\n", 
        prefix, outputIdx, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, 
        xrrOutputInfo->mm_width, xrrOutputInfo->mm_height,
        xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred, isPrim);
    for(j=0; j<xrrOutputInfo->ncrtc; j++) {
        fprintf(stderr, "%s: Output[%d].Crtc[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->crtcs[j]);
    }
    for(j=0; j<xrrOutputInfo->nclone; j++) {
        fprintf(stderr, "%s: Output[%d].Clones[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->clones[j]);
    }
    for(j=0; j<xrrOutputInfo->nmode; j++) {
        fprintf(stderr, "%s: Output[%d].Mode[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->modes[j]);
    }
    XRRFreeOutputInfo (xrrOutputInfo);
}
Пример #3
0
std::vector<display::mode> display::modes() const
{
	std::vector<display::mode> result;
	if (randr.is_available)
	{
		XRRScreenResources* sr = XRRGetScreenResources(g_display, g_root);
		XRRCrtcInfo* ci = XRRGetCrtcInfo(g_display, sr, crtc);
		XRROutputInfo* oi = XRRGetOutputInfo(g_display, sr, output);

		for (int i = 0; i < oi->nmode; ++i)
		{
			XRRModeInfo const* mi = mode_info(sr, oi->modes[i]);
			if (mi && !(mi->modeFlags & RR_Interlace))
			{
				result.emplace_back(make_mode(mi, ci));
			}
		}

		XRRFreeOutputInfo(oi);
		XRRFreeCrtcInfo(ci);
		XRRFreeScreenResources(sr);

		std::sort(result.begin(), result.end());
		result.erase(std::unique(result.begin(), result.end()), result.end());
	}
	else
	{
		result.emplace_back(current_mode());
	}
	return result;
}
/* In the case of multiple outputs of a single crtc (mirroring), we consider one of the
 * outputs the "main". This is the one we consider "owning" the windows, so if
 * the mirroring is changed to a dual monitor setup then the windows are moved to the
 * crtc that now has that main output. If one of the outputs is the primary that is
 * always the main, otherwise we just use the first.
 */
static XID
find_main_output_for_crtc (XRRScreenResources *resources,
                           XRRCrtcInfo        *crtc,
                           Display            *xdisplay,
                           XID                 xroot)
{
    XRROutputInfo *output;
    RROutput primary_output;
    int i;
    XID res;

    primary_output = XRRGetOutputPrimary (xdisplay, xroot);

    res = None;
    for (i = 0; i < crtc->noutput; i++)
    {
        output = XRRGetOutputInfo (xdisplay, resources, crtc->outputs[i]);
        if (output->connection != RR_Disconnected &&
            (res == None || crtc->outputs[i] == primary_output))
        {
            res = crtc->outputs[i];
        }

        XRRFreeOutputInfo (output);
    }

    return res;
}
Пример #5
0
int main() {
    Display *disp;
    XRRScreenResources *screen;
    XRROutputInfo *info;
    XRRCrtcInfo *crtc_info;
    int iscres;
    int icrtc;

    disp = XOpenDisplay(0);
    screen = XRRGetScreenResources (disp, DefaultRootWindow(disp));
    for (iscres = screen->noutput; iscres > 0; ) {
        --iscres;

        info = XRRGetOutputInfo (disp, screen, screen->outputs[iscres]);
        if (info->connection == RR_Connected) {
            for (icrtc = info->ncrtc; icrtc > 0;) {
                --icrtc;

                crtc_info = XRRGetCrtcInfo (disp, screen, screen->crtcs[icrtc]);
                fprintf(stderr, "==> %dx%d+%dx%d\n", crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height);

                XRRFreeCrtcInfo(crtc_info);
            }
        }
        XRRFreeOutputInfo (info);
    }
    XRRFreeScreenResources(screen);

    return 0;
}
Пример #6
0
void XRRConfiguration::AddResolutions(wxArrayString& arrayStringFor_FullscreenResolution)
{
    if (!bValid || !screenResources)
        return;

    //Get all full screen resolutions for the config dialog
    for (int i = 0; i < screenResources->noutput; i++)
    {
        XRROutputInfo *output_info =
            XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]);

        if (output_info && output_info->crtc && output_info->connection == RR_Connected)
        {
            std::vector<std::string> resos;
            for (int j = 0; j < output_info->nmode; j++)
                for (int k = 0; k < screenResources->nmode; k++)
                    if (output_info->modes[j] == screenResources->modes[k].id)
                    {
                        const std::string strRes =
                            std::string(output_info->name) + ": " +
                            std::string(screenResources->modes[k].name);
                        // Only add unique resolutions
                        if (std::find(resos.begin(), resos.end(), strRes) == resos.end())
                        {
                            resos.push_back(strRes);
                            arrayStringFor_FullscreenResolution.Add(StrToWxStr(strRes));
                        }
                    }
        }
        if (output_info)
            XRRFreeOutputInfo(output_info);
    }
}
Пример #7
0
/* Caller must free return value */
static XRROutputInfo*
find_output_xrandr(Display *dpy, const char *output_name)
{
    XRRScreenResources *res;
    XRROutputInfo *output_info = NULL;
    int i;
    int found = 0;

    res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy));

    for (i = 0; i < res->noutput && !found; i++)
    {
        output_info = XRRGetOutputInfo(dpy, res, res->outputs[i]);

        if (output_info->crtc && output_info->connection == RR_Connected &&
            strcmp(output_info->name, output_name) == 0)
        {
            found = 1;
            break;
        }

        XRRFreeOutputInfo(output_info);
    }

    XRRFreeScreenResources(res);

    if (!found)
        output_info = NULL;

    return output_info;
}
Пример #8
0
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
    GLFWvidmode* result;

    *found = 0;

    // Build array of available resolutions

    if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
    {
        int i, j;
        XRRScreenResources* sr;
        XRROutputInfo* oi;

        sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
        oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);

        result = calloc(oi->nmode, sizeof(GLFWvidmode));

        for (i = 0;  i < oi->nmode;  i++)
        {
            const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
            if (!modeIsGood(mi))
                continue;

            const GLFWvidmode mode = vidmodeFromModeInfo(mi);

            for (j = 0;  j < *found;  j++)
            {
                if (result[j].width == mode.width &&
                    result[j].height == mode.height &&
                    result[j].refreshRate == mode.refreshRate)
                {
                    break;
                }
            }

            if (j < *found)
            {
                // This is a duplicate, so skip it
                continue;
            }

            result[*found] = mode;
            (*found)++;
        }

        XRRFreeOutputInfo(oi);
        XRRFreeScreenResources(sr);
    }
    else
    {
        *found = 1;
        result = calloc(1, sizeof(GLFWvidmode));
        _glfwPlatformGetVideoMode(monitor, result);
    }

    return result;
}
Пример #9
0
void RandROutput::queryOutputInfo(void)
{
	XRROutputInfo *info = XRRGetOutputInfo(QX11Info::display(), m_screen->resources(), m_id);
	Q_ASSERT(info);
	
	if (RandR::timestamp != info->timestamp)
		RandR::timestamp = info->timestamp;
	
	// Set up the output's connection status, name, and current
	// CRT controller.
	m_connected = (info->connection == RR_Connected);
	m_name = info->name;
	
	kDebug() << "XID" << m_id << "is output" << m_name <<
	            (isConnected() ? "(connected)" : "(disconnected)");
	
	setCrtc(m_screen->crtc(info->crtc));
	kDebug() << "Possible CRTCs for output" << m_name << ":";

	if (!info->ncrtc) {
		kDebug() << "   - none";
	}
	for(int i = 0; i < info->ncrtc; ++i) {
		kDebug() << "   - CRTC" << info->crtcs[i];
		m_possibleCrtcs.append(info->crtcs[i]);
	}
	
	//TODO: is it worth notifying changes on mode list changing?
	m_modes.clear();
	
	for (int i = 0; i < info->nmode; ++i) {
		if (i < info->npreferred) {
			m_preferredMode = m_screen->mode(info->modes[i]);
		}
		m_modes.append(info->modes[i]);
	}
	
	//get all possible rotations
	m_rotations = 0;
	for (int i = 0; i < m_possibleCrtcs.count(); ++i)
	{
		RandRCrtc *crtc = m_screen->crtc(m_possibleCrtcs.at(i));
		Q_ASSERT(crtc);
		m_rotations |= crtc->rotations();
	}
	m_originalRotation = m_crtc->rotation();
	m_originalRate     = m_crtc->refreshRate();
	m_originalRect     = m_crtc->rect();
	
	if(isConnected()) {
		kDebug() << "Current configuration for output" << m_name << ":";
		kDebug() << "   - Refresh rate:" << m_originalRate;
		kDebug() << "   - Rect:" << m_originalRect;
		kDebug() << "   - Rotation:" << m_originalRotation;
	}
	
	XRRFreeOutputInfo(info);
}
Пример #10
0
static void
randrd(void)
{
	XRRScreenResources		*resources;
	XRROutputInfo			*info;
	XRROutputChangeNotifyEvent	*rrocevt;
	XRRNotifyEvent			*rrevt;
	char				*new_edidhash;
	Window				 root;
	XEvent	 			 evt;

	exec_script(script, "init", "", current_edidhash);

	XRRSelectInput(dpy, DefaultRootWindow(dpy), RROutputChangeNotifyMask);
	while (!quit) {
		root = RootWindow(dpy, DefaultScreen(dpy));
		resources = XRRGetScreenResources(dpy, root);

		while (XPending(dpy)) {
			XNextEvent(dpy, &evt);

			if (evt.type != rr_event_base + RRNotify)
				continue;

			rrevt = (XRRNotifyEvent *)&evt;
			if (rrevt->subtype != RRNotify_OutputChange)
				continue;

			new_edidhash = getedidhash1(resources);
			if (new_edidhash == NULL)
				continue;

			if (!strcmp(current_edidhash, new_edidhash)) {
				free(new_edidhash);
				continue;
			}

			free(current_edidhash);
			current_edidhash = new_edidhash;

			rrocevt = (XRROutputChangeNotifyEvent *)&evt;
			info = XRRGetOutputInfo(rrocevt->display, resources,
					rrocevt->output);

			syslog(LOG_INFO, "%s %s", info->name,
					connstates[info->connection]);
			exec_script(script, connstates[info->connection],
					info->name, new_edidhash);

			XRRFreeOutputInfo(info);
		}

		XRRFreeScreenResources(resources);
		sleep(interval);
	}
}
Пример #11
0
MonitorManager *monitor_mgr_create()
{
    Display *display = XOpenDisplay(NULL);
    if (!display)
    {
        fprintf(stderr, "Cannot open display.\n");
        return NULL;
    }

    MonitorManager *mgr = malloc(sizeof(MonitorManager*));
    mgr->monitor_count = 0;
    mgr->monitors = NULL;

    Window root = DefaultRootWindow(display);
    RROutput primary_output = XRRGetOutputPrimary(display, root);

    XRRScreenResources *screen = XRRGetScreenResources(display, root);
    assert(screen);

    for (int i = 0; i < screen->noutput; i++)
    {
        XRROutputInfo *output_info = XRRGetOutputInfo(
            display, screen, screen->outputs[i]);
        assert(output_info);

        if (output_info->connection == RR_Connected)
        {
            XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(
                display, screen, output_info->crtc);
            assert(crtc_info);

            int primary = 0;
            for (int j = 0; j < crtc_info->noutput; j++)
                if (crtc_info->outputs[j] == primary_output)
                    primary = 1;

            Monitor *monitor = monitor_create(
                primary,
                crtc_info->x,
                crtc_info->y,
                crtc_info->width,
                crtc_info->height);
            assert(monitor);

            monitor_mgr_add(mgr, monitor);

            XRRFreeCrtcInfo(crtc_info);
        }

        XRRFreeOutputInfo(output_info);
    }

    XRRFreeScreenResources(screen);
    XCloseDisplay(display);
    return mgr;
}
Пример #12
0
static void
ExtInitRR(int available)
{
   Rotation            rot;

   if (!available)
      return;

   /* Listen for RandR events */
   XRRSelectInput(disp, WinGetXwin(VROOT), RRScreenChangeNotifyMask);
   XRRRotations(disp, Dpy.screen, &rot);
   Mode.screen.rotation = rot;

#if 0				/* Debug */
   if (EDebug(EDBUG_TYPE_VERBOSE))
     {
	XRRScreenResources *psr;
	XRRCrtcInfo        *pci;
	XRROutputInfo      *poi;
	int                 i;

	psr = XRRGetScreenResources(disp, WinGetXwin(VROOT));
	if (!psr)
	   return;

	Eprintf("CRTC  ID      X,Y         WxH     mode   rot   nout\n");
	for (i = 0; i < psr->ncrtc; i++)
	  {
	     pci = XRRGetCrtcInfo(disp, psr, psr->crtcs[i]);
	     if (!pci)
		break;
	     Eprintf("%3d  %#04lx  %4d,%4d   %4ux%4u  %#04lx %4d %5d\n",
		     i, psr->crtcs[i],
		     pci->x, pci->y, pci->width, pci->height,
		     pci->mode, pci->rotation, pci->noutput);
	     XRRFreeCrtcInfo(pci);
	  }

	Eprintf("OUTP  ID  Name            WxH     crtc  ncrtc nclon nmode\n");
	for (i = 0; i < psr->noutput; i++)
	  {
	     poi = XRRGetOutputInfo(disp, psr, psr->outputs[i]);
	     if (!poi)
		break;
	     Eprintf("%3d  %#04lx %-8s     %4lux%4lu  %#04lx %4d %5d %5d\n",
		     i, psr->outputs[i],
		     poi->name, poi->mm_width, poi->mm_height,
		     poi->crtc, poi->ncrtc, poi->nclone, poi->nmode);
	     XRRFreeOutputInfo(poi);
	  }

	XRRFreeScreenResources(psr);
     }
#endif
}
Пример #13
0
// Set the current video mode for the specified monitor
//
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
    if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
    {
        XRRScreenResources* sr;
        XRRCrtcInfo* ci;
        XRROutputInfo* oi;
        GLFWvidmode current;
        const GLFWvidmode* best;
        RRMode native = None;
        int i;

        best = _glfwChooseVideoMode(monitor, desired);
        _glfwPlatformGetVideoMode(monitor, &current);
        if (_glfwCompareVideoModes(&current, best) == 0)
            return;

        sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
        ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
        oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);

        for (i = 0;  i < oi->nmode;  i++)
        {
            const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
            if (!modeIsGood(mi))
                continue;

            const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
            if (_glfwCompareVideoModes(best, &mode) == 0)
            {
                native = mi->id;
                break;
            }
        }

        if (native)
        {
            if (monitor->x11.oldMode == None)
                monitor->x11.oldMode = ci->mode;

            XRRSetCrtcConfig(_glfw.x11.display,
                             sr, monitor->x11.crtc,
                             CurrentTime,
                             ci->x, ci->y,
                             native,
                             ci->rotation,
                             ci->outputs,
                             ci->noutput);
        }

        XRRFreeOutputInfo(oi);
        XRRFreeCrtcInfo(ci);
        XRRFreeScreenResources(sr);
    }
}
Пример #14
0
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{
    GLFWvidmode* result;

    *count = 0;

    if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
    {
        int i, j;
        XRRScreenResources* sr;
        XRRCrtcInfo* ci;
        XRROutputInfo* oi;

        sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
        ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
        oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);

        result = calloc(oi->nmode, sizeof(GLFWvidmode));

        for (i = 0;  i < oi->nmode;  i++)
        {
            const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
            if (!modeIsGood(mi))
                continue;

            const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);

            for (j = 0;  j < *count;  j++)
            {
                if (_glfwCompareVideoModes(result + j, &mode) == 0)
                    break;
            }

            // Skip duplicate modes
            if (j < *count)
                continue;

            (*count)++;
            result[*count - 1] = mode;
        }

        XRRFreeOutputInfo(oi);
        XRRFreeCrtcInfo(ci);
        XRRFreeScreenResources(sr);
    }
    else
    {
        *count = 1;
        result = calloc(1, sizeof(GLFWvidmode));
        _glfwPlatformGetVideoMode(monitor, result);
    }

    return result;
}
Пример #15
0
void RandROutput::loadSettings(bool notify)
{
	int changes = 0;
	XRROutputInfo *info = XRRGetOutputInfo(QX11Info::display(), m_screen->resources(), m_id);
	Q_ASSERT(info);


	if (RandR::timestamp != info->timestamp)
		RandR::timestamp = info->timestamp;

	// this information shouldn't change, so
	m_name = info->name;

	m_possibleCrtcs.clear();
	for (int i = 0; i < info->ncrtc; ++i)
		m_possibleCrtcs.append(info->crtcs[i]);

	//check if the crtc changed
	if (info->crtc != m_currentCrtc)
	{
		setCrtc(info->crtc);
		changes |= RandR::ChangeCrtc;
	}

			

	bool connected = (info->connection == RR_Connected);
	if (connected != m_connected)
	{
		m_connected = connected;
		changes |= RandR::ChangeConnection;
	}

	//CHECK: is it worth notifying changes on mode list changing?
	//get modes
	m_modes.clear();
	for (int i = 0; i < info->nmode; ++i)
		m_modes.append(info->modes[i]);

	//get all possible rotations
	m_rotations = 0;
	for (int i = 0; i < m_possibleCrtcs.count(); ++i)
	{
		RandRCrtc *crtc = m_screen->crtc(m_possibleCrtcs.at(i));
		Q_ASSERT(crtc);
		m_rotations |= crtc->rotations();
	}

	// free the info
	XRRFreeOutputInfo(info);

	if (changes && notify)
		emit outputChanged(m_id, changes);
}
Пример #16
0
/*
 * Class:     jogamp_newt_driver_x11_RandR13
 * Method:    getMonitorDevice0
 * Signature: (JJJJ)[I
 */
JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice0
  (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx)
{
    Display * dpy = (Display *) (intptr_t) display;
    XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
    XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;

    if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) {
        // n/a
        return NULL;
    }

    if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) {
        // disabled
        return NULL;
    }

    RROutput output = xrrCrtcInfo->outputs[0];
    XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output);
    int numModes = xrrOutputInfo->nmode;

    jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 + numModes;
    jint prop[ propCount ];
    int propIndex = 0;

    prop[propIndex++] = propCount;
    prop[propIndex++] = crt_idx;
    prop[propIndex++] = xrrOutputInfo->mm_width;
    prop[propIndex++] = xrrOutputInfo->mm_height;
    prop[propIndex++] = xrrCrtcInfo->x;
    prop[propIndex++] = xrrCrtcInfo->y;
    prop[propIndex++] = xrrCrtcInfo->width;
    prop[propIndex++] = xrrCrtcInfo->height;
    prop[propIndex++] = xrrCrtcInfo->mode; // current mode id
    prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation);
    int i;
    for(i=0; i<numModes; i++) {
        // avail modes ..
        prop[propIndex++] = xrrOutputInfo->modes[i];
    }

    XRRFreeOutputInfo (xrrOutputInfo);

    jintArray properties = (*env)->NewIntArray(env, propCount);
    if (properties == NULL) {
        NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
    }
    (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
    
    return properties;
}
Пример #17
0
static RRCrtc get_crtc_id(Display *display,
                          XRRScreenResources *resources,
                          const char* const x_output_name)
{
    if (!display || !resources || !x_output_name)
        return (RRCrtc) -1;

    size_t len = strlen(x_output_name);
    if (len == 0)
        return (RRCrtc) -1;

    // Check if x_output_name is XID
    bool is_digit = true;
    for (size_t i = 0; i < len; ++i) {
        if (!isdigit(x_output_name[i])) {
            is_digit = false;
            break;
        }
    }

    XRROutputInfo *output_info = 0;
    for (int i = 0; i < resources->noutput; ++i) {
        XRROutputInfo *info = XRRGetOutputInfo(display, resources, resources->outputs[i]);
        if (is_digit) {
            RROutput output = strtoul(x_output_name, 0, 0);
            if (output == resources->outputs[i]) {
                output_info = info;
                break;
            }
        } else {
            if (strcmp(x_output_name, info->name) == 0) {
                output_info = info;
                break;
            }
        }
        XRRFreeOutputInfo(info);
    }

    RRCrtc crtc_id = (RRCrtc) -1;
    if (output_info) {
        if (output_info->connection != RR_Connected)
            printf("Output \"%s\" is not connected to a monitor. Default will be used.\n", output_info->name);
        else
            crtc_id = output_info->crtc;
        XRRFreeOutputInfo(output_info);
    } else
        printf("\"%s\" is not valid output. Default will be used.\n", x_output_name);

    return crtc_id;
}
Пример #18
0
static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *resources, int noutput, RROutput * outputs) {
    int i, j;
    fprintf(stderr, "%s %p: Output count %d\n", prefix, resources, noutput);
    for(i=0; i<noutput; i++) {
        RROutput output = outputs[i];
        XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output);
        fprintf(stderr, "  Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, .., nmode %d (preferred %d)\n", 
            i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height,
            xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred);
        for(j=0; j<xrrOutputInfo->nmode; j++) {
            fprintf(stderr, "    Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]);
        }
        XRRFreeOutputInfo (xrrOutputInfo);
    }
}
Пример #19
0
void
get_xrandr_config(Display *dpy, Window root, char *name,
    int *x, int *y, int *width, int *height)
{
	XRRScreenResources *res;
	XRROutputInfo *output_info;
	XRRCrtcInfo *crtc_info;
	int o, found = 0;

	res = XRRGetScreenResources(dpy, root);

	for (o = 0; o < res->noutput; o++) {
		output_info = XRRGetOutputInfo (dpy, res, res->outputs[o]);
		if (!output_info) {
			fprintf(stderr,
			    "could not get output 0x%lx information\n",
			    res->outputs[o]);
			exit(2);
		}
		if (output_info->crtc != 0) {
			crtc_info = XRRGetCrtcInfo(dpy, res,
			    output_info->crtc);
			if (!crtc_info) {
				fprintf(stderr,
				    "%s: could not get crtc 0x%lx "
				    "information\n", __progname,
				    output_info->crtc);
				exit(2);
			}
			printf("%s: %dx%d+%d+%d\n",
			    output_info->name,
			    crtc_info->width, crtc_info->height,
			    crtc_info->x, crtc_info->y);
			if (!strcmp(output_info->name, name)) {
				*x = crtc_info->x;
				*y = crtc_info->y;
				*width = crtc_info->width;
				*height = crtc_info->height;
				found = 1;
			}
		}
	}
	if (!found) {
		fprintf(stderr, "%s: output %s not found\n", __progname, name);
		exit(2);
	}
}
Пример #20
0
static XRROutputInfo *
pick_output (Display *xdpy, XRRScreenResources *screen_res)
{
  XRROutputInfo *laptop_output   = NULL;
  XRROutputInfo *external_output = NULL;
  int            i;

  for (i = 0; i < screen_res->noutput; i++)
    {
      XRROutputInfo *oi;
      RROutput       o = screen_res->outputs[i];

      oi = XRRGetOutputInfo (xdpy, screen_res, o);

      if (oi->connection != RR_Connected)
        {
          XRRFreeOutputInfo (oi);
          continue;
        }

      if (output_is_laptop (oi->name))
        {
          if (laptop_output)
            XRRFreeOutputInfo (laptop_output);

          laptop_output = oi;
        }
      else
        {
          if (external_output)
            XRRFreeOutputInfo (external_output);

          external_output = oi;
        }
    }

  g_assert (laptop_output || external_output);

  return external_output ? external_output : laptop_output;
}
Пример #21
0
int init_monitor(){
	int outi;
	char msg[255];
	dis = XOpenDisplay(NULL);

	startLogger();

	if (!dis){
		logMessage(ERROR, "Cannot connect into XServer using default display...exiting");
		return ENOMEM;
	}

	screen = DefaultScreen(dis);

	logMessage(INFO, "Loading root window");
	root = RootWindow(dis, screen);

	/*Select X input to handle the events*/
	logMessage(INFO, "Selecting input");
	XSelectInput(dis, root, StructureNotifyMask);

	/*Getting Screen Resources*/
	logMessage(INFO, "Getting screen resources");
	res = XRRGetScreenResources(dis, root);

	sprintf(msg, "%d resources found", res->noutput);
	
	logMessage(INFO, msg);

	for (outi = 0; outi < res->noutput; outi++){
		output_info = XRRGetOutputInfo(dis, res, res->outputs[outi]);
	
		sprintf(msg, "Output name: %s", output_info->name);
		
		logMessage(INFO, msg);
	}

	return 0;
}
Пример #22
0
int _screen_info(const char *name, int num, Rect *r) {
	XRRScreenResources *res = XRRGetScreenResources(dpy, root);
	if (!res) return 0;
	int i, n = res->noutput;
	XRROutputInfo *info;
	XRRCrtcInfo *crtc;
	r->w = r->h = 0;
	for (i = 0; i < n; ++i) {
		/* skip if output lacks info or crtc */
		if (!(info=XRRGetOutputInfo(dpy, res, res->outputs[i]))) continue;
		if (!info->crtc || !(crtc=XRRGetCrtcInfo(dpy,res,info->crtc))) {
			XRRFreeOutputInfo(info);
			continue;
		}
		/* skip if name is provided and doesn't match */
		if (name && strncmp(name, info->name, strlen(name))) {
			XRRFreeCrtcInfo(crtc);
			XRRFreeOutputInfo(info);
			continue;
		}
		/* and skip if number is provided and doesn't match */
		if (num && num - 1 != i) {
			XRRFreeCrtcInfo(crtc);
			XRRFreeOutputInfo(info);
			continue;
		}
		/* match found, return size */
		r->x = crtc->x;
		r->y = crtc->y;
		r->w = crtc->width;
		r->h = crtc->height;
		XRRFreeCrtcInfo(crtc);
		XRRFreeOutputInfo(info);
		if (r->w && r->h) break;
	}
	XRRFreeScreenResources(res);
	return n;
}
Пример #23
0
void XRRConfiguration::AddResolutions(std::vector<std::string>& resos)
{
	if (!bValid || !screenResources)
		return;

	//Get all full screen resolutions for the config dialog
	for (int i = 0; i < screenResources->noutput; i++)
	{
		XRROutputInfo *output_info =
			XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]);

		if (output_info && output_info->crtc && output_info->connection == RR_Connected)
		{
			for (int j = 0; j < output_info->nmode; j++)
			{
				for (int k = 0; k < screenResources->nmode; k++)
				{
					if (output_info->modes[j] == screenResources->modes[k].id)
					{
						bool interlaced = !!(screenResources->modes[k].modeFlags & RR_Interlace);
						const std::string strRes =
							std::string(output_info->name) + ": " +
							std::string(screenResources->modes[k].name) + (interlaced? "i" : "");
						// Only add unique resolutions
						if (std::find(resos.begin(), resos.end(), strRes) == resos.end())
						{
							resos.push_back(strRes);
						}
					}
				}
			}
		}
		if (output_info)
			XRRFreeOutputInfo(output_info);
	}
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_system_linux_Xrandr_nXRRGetOutputInfo(JNIEnv *__env, jclass clazz, jlong displayAddress, jlong resourcesAddress, jlong output) {
	Display *display = (Display *)(intptr_t)displayAddress;
	XRRScreenResources *resources = (XRRScreenResources *)(intptr_t)resourcesAddress;
	UNUSED_PARAMS(__env, clazz)
	return (jlong)(intptr_t)XRRGetOutputInfo(display, resources, (RROutput)output);
}
Пример #25
0
void XRRConfiguration::Update()
{
	if (SConfig::GetInstance().strFullscreenResolution == "Auto")
		return;

	if (!bValid)
		return;

	if (outputInfo)
	{
		XRRFreeOutputInfo(outputInfo);
		outputInfo = nullptr;
	}
	if (crtcInfo)
	{
		XRRFreeCrtcInfo(crtcInfo);
		crtcInfo = nullptr;
	}
	fullMode = 0;

	// Get the resolution setings for fullscreen mode
	unsigned int fullWidth, fullHeight;
	char *output_name = nullptr;
	char auxFlag = '\0';
	if (SConfig::GetInstance().strFullscreenResolution.find(':') ==
			std::string::npos)
	{
		fullWidth = fb_width;
		fullHeight = fb_height;
	}
	else
	{
		sscanf(SConfig::GetInstance().strFullscreenResolution.c_str(),
				"%m[^:]: %ux%u%c", &output_name, &fullWidth, &fullHeight, &auxFlag);
	}
	bool want_interlaced = ('i' == auxFlag);

	for (int i = 0; i < screenResources->noutput; i++)
	{
		XRROutputInfo *output_info = XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]);
		if (output_info && output_info->crtc && output_info->connection == RR_Connected)
		{
			XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(dpy, screenResources, output_info->crtc);
			if (crtc_info)
			{
				if (!output_name || !strcmp(output_name, output_info->name))
				{
					// Use the first output for the default setting.
					if (!output_name)
					{
						output_name = strdup(output_info->name);
						SConfig::GetInstance().strFullscreenResolution =
							StringFromFormat("%s: %ux%u", output_info->name, fullWidth, fullHeight);
					}
					outputInfo = output_info;
					crtcInfo = crtc_info;
					for (int j = 0; j < output_info->nmode && fullMode == 0; j++)
					{
						for (int k = 0; k < screenResources->nmode && fullMode == 0; k++)
						{
							if (output_info->modes[j] == screenResources->modes[k].id)
							{
								if (fullWidth == screenResources->modes[k].width &&
										fullHeight == screenResources->modes[k].height &&
										want_interlaced == !!(screenResources->modes[k].modeFlags & RR_Interlace))
								{
									fullMode = screenResources->modes[k].id;
									if (crtcInfo->x + (int)screenResources->modes[k].width > fs_fb_width)
										fs_fb_width = crtcInfo->x + screenResources->modes[k].width;
									if (crtcInfo->y + (int)screenResources->modes[k].height > fs_fb_height)
										fs_fb_height = crtcInfo->y + screenResources->modes[k].height;
								}
							}
						}
					}
				}
				else
				{
					if (crtc_info->x + (int)crtc_info->width > fs_fb_width)
						fs_fb_width = crtc_info->x + crtc_info->width;
					if (crtc_info->y + (int)crtc_info->height > fs_fb_height)
						fs_fb_height = crtc_info->y + crtc_info->height;
				}
			}
			if (crtc_info && crtcInfo != crtc_info)
				XRRFreeCrtcInfo(crtc_info);
		}
		if (output_info && outputInfo != output_info)
			XRRFreeOutputInfo(output_info);
	}
	fs_fb_width_mm = fs_fb_width * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen);
	fs_fb_height_mm = fs_fb_height * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen);

	if (output_name)
		free(output_name);

	if (outputInfo && crtcInfo && fullMode)
	{
		INFO_LOG(VIDEO, "Fullscreen Resolution %dx%d", fullWidth, fullHeight);
	}
	else
	{
		ERROR_LOG(VIDEO, "Failed to obtain fullscreen size.\n"
				"Using current desktop resolution for fullscreen.");
	}
}
Пример #26
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;
}
Пример #27
0
static void
xfce_randr_populate (XfceRandr *randr,
                     Display   *xdisplay,
                     GdkWindow *root_window)
{
    GPtrArray     *outputs;
    XRROutputInfo *output_info;
    XRRCrtcInfo   *crtc_info;
    gint           n;
    guint          m;

    g_return_if_fail (randr != NULL);
    g_return_if_fail (randr->priv != NULL);
    g_return_if_fail (randr->priv->resources != NULL);

    /* prepare the temporary cache */
    outputs = g_ptr_array_new ();

    /* walk the outputs */
    for (n = 0; n < randr->priv->resources->noutput; ++n)
    {
        /* get the output info */
        output_info = XRRGetOutputInfo (xdisplay, randr->priv->resources,
                                        randr->priv->resources->outputs[n]);

        /* forget about disconnected outputs */
        if (output_info->connection != RR_Connected)
        {
            XRRFreeOutputInfo (output_info);
            continue;
        }

        /* cache it */
        g_ptr_array_add (outputs, output_info);
    }

    /* migrate the temporary cache */
    randr->noutput = outputs->len;
    randr->priv->output_info = (XRROutputInfo **) g_ptr_array_free (outputs, FALSE);

    /* allocate final space for the settings */
    randr->mode = g_new0 (RRMode, randr->noutput);
    randr->priv->modes = g_new0 (XfceRRMode *, randr->noutput);
    randr->priv->position = g_new0 (XfceOutputPosition, randr->noutput);
    randr->rotation = g_new0 (Rotation, randr->noutput);
    randr->rotations = g_new0 (Rotation, randr->noutput);
    randr->relation = g_new0 (XfceOutputRelation, randr->noutput);
    randr->related_to = g_new0 (guint, randr->noutput);
    randr->status = g_new0 (XfceOutputStatus, randr->noutput);
    randr->friendly_name = g_new0 (gchar *, randr->noutput);

    /* walk the connected outputs */
    for (m = 0; m < randr->noutput; ++m)
    {
        /* fill in supported modes */
        randr->priv->modes[m] = xfce_randr_list_supported_modes (randr->priv->resources, randr->priv->output_info[m]);

#ifdef HAS_RANDR_ONE_POINT_THREE
        /* find the primary screen if supported */
        if (randr->priv->has_1_3 && XRRGetOutputPrimary (xdisplay, GDK_WINDOW_XID (root_window)) == randr->priv->resources->outputs[m])
            randr->status[m] = XFCE_OUTPUT_STATUS_PRIMARY;
        else
#endif
            randr->status[m] = XFCE_OUTPUT_STATUS_SECONDARY;

        if (randr->priv->output_info[m]->crtc != None)
        {
            crtc_info = XRRGetCrtcInfo (xdisplay, randr->priv->resources,
                                        randr->priv->output_info[m]->crtc);
            randr->mode[m] = crtc_info->mode;
            randr->rotation[m] = crtc_info->rotation;
            randr->rotations[m] = crtc_info->rotations;
            randr->priv->position[m].x = crtc_info->x;
            randr->priv->position[m].y = crtc_info->y;
            XRRFreeCrtcInfo (crtc_info);
        }
        else
        {
            /* output disabled */
            randr->mode[m] = None;
            randr->rotation[m] = RR_Rotate_0;
            randr->rotations[m] = xfce_randr_get_safe_rotations (randr, xdisplay, m);
        }

        /* fill in the name used by the UI */
        randr->friendly_name[m] = xfce_randr_friendly_name (randr, m);
    }

    /* calculate relations from positions */
    xfce_randr_guess_relations (randr);
}
Пример #28
0
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
    GLFWvidmode* result;
    int depth, r, g, b;

    depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
    _glfwSplitBPP(depth, &r, &g, &b);

    *found = 0;

    // Build array of available resolutions

    if (_glfw.x11.randr.available)
    {
        int i, j;
        XRRScreenResources* sr;
        XRROutputInfo* oi;

        sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
        oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);

        result = calloc(oi->nmode, sizeof(GLFWvidmode));

        for (i = 0;  i < oi->nmode;  i++)
        {
            GLFWvidmode mode;
            const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);

            mode.width  = mi->width;
            mode.height = mi->height;
            mode.refreshRate = calculateRefreshRate(mi);

            for (j = 0;  j < *found;  j++)
            {
                if (result[j].width == mode.width &&
                    result[j].height == mode.height &&
                    result[j].refreshRate == mode.refreshRate)
                {
                    break;
                }
            }

            if (j < *found)
            {
                // This is a duplicate, so skip it
                continue;
            }

            mode.redBits = r;
            mode.greenBits = g;
            mode.blueBits = b;

            result[*found] = mode;
            (*found)++;
        }

        XRRFreeOutputInfo(oi);
        XRRFreeScreenResources(sr);
    }
    else
    {
        *found = 1;

        result = calloc(1, sizeof(GLFWvidmode));

        result[0].width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
        result[0].height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
        result[0].redBits = r;
        result[0].greenBits = g;
        result[0].blueBits = b;
        result[0].refreshRate = 0;
    }

    return result;
}
Пример #29
0
// Set the current video mode for the specified monitor
//
void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
    if (_glfw.x11.randr.available)
    {
        int i, j;
        XRRScreenResources* sr;
        XRRCrtcInfo* ci;
        XRROutputInfo* oi;
        RRMode bestMode = 0;
        unsigned int sizeDiff, leastSizeDiff = UINT_MAX;
        unsigned int rateDiff, leastRateDiff = UINT_MAX;

        sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
        ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
        oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);

        for (i = 0;  i < sr->nmode;  i++)
        {
            const XRRModeInfo* mi = sr->modes + i;

            if (mi->modeFlags & RR_Interlace)
                continue;

            for (j = 0;  j < oi->nmode;  j++)
            {
                if (oi->modes[j] == mi->id)
                    break;
            }

            if (j == oi->nmode)
                continue;

            sizeDiff = (mi->width - desired->width) *
                       (mi->width - desired->width) +
                       (mi->height - desired->height) *
                       (mi->height - desired->height);

            if (desired->refreshRate)
                rateDiff = abs(calculateRefreshRate(mi) - desired->refreshRate);
            else
                rateDiff = UINT_MAX - calculateRefreshRate(mi);

            if ((sizeDiff < leastSizeDiff) ||
                (sizeDiff == leastSizeDiff && rateDiff < leastRateDiff))
            {
                bestMode = mi->id;
                leastSizeDiff = sizeDiff;
                leastRateDiff = rateDiff;
            }
        }

        if (bestMode == ci->mode)
            return;

        if (monitor->x11.oldMode == None)
            monitor->x11.oldMode = ci->mode;

        XRRSetCrtcConfig(_glfw.x11.display,
                         sr, monitor->x11.crtc,
                         CurrentTime,
                         ci->x, ci->y,
                         bestMode,
                         ci->rotation,
                         ci->outputs,
                         ci->noutput);

        XRRFreeOutputInfo(oi);
        XRRFreeCrtcInfo(ci);
        XRRFreeScreenResources(sr);
    }
}
Пример #30
0
void psb_xrandr_refresh(VADriverContextP ctx)
{
    int i;

    XRROutputInfo *output_info;
    XRRCrtcInfo *crtc_info;

    psb_xrandr_crtc_p p_crtc;
    psb_xrandr_output_p p_output;

    pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex);

    //deinit crtc
    if (psb_xrandr_info->crtc_head) {
        while (psb_xrandr_info->crtc_head) {
            psb_xrandr_info->crtc_tail = psb_xrandr_info->crtc_head->next;

            free(psb_xrandr_info->crtc_head);

            psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail;
        }
        psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = NULL;
    }

    for (i = 0; i < psb_xrandr_info->res->ncrtc; i++) {
        crtc_info = XRRGetCrtcInfo(psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->crtcs[i]);
        if (crtc_info) {
            p_crtc = (psb_xrandr_crtc_p)calloc(1, sizeof(psb_xrandr_crtc_s));
            if (!p_crtc) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "output of memory\n");
                return;
            }

            if (i == 0)
                psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = p_crtc;

            p_crtc->crtc_id = psb_xrandr_info->res->crtcs[i];
            p_crtc->x = crtc_info->x;
            p_crtc->y = crtc_info->y;
            p_crtc->width = crtc_info->width;
            p_crtc->height = crtc_info->height;
            p_crtc->crtc_mode = crtc_info->mode;
            p_crtc->noutput = crtc_info->noutput;
            p_crtc->rotation = crtc_info->rotation;

            psb_xrandr_info->crtc_tail->next = p_crtc;
            p_crtc->next = NULL;
            psb_xrandr_info->crtc_tail = p_crtc;
        } else {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get crtc_info\n");
            pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex);
            return;
        }
    }

    //deinit output
    if (psb_xrandr_info->output_head) {
        while (psb_xrandr_info->output_head) {
            psb_xrandr_info->output_tail = psb_xrandr_info->output_head->next;

            free(psb_xrandr_info->output_head);

            psb_xrandr_info->output_head = psb_xrandr_info->output_tail;
        }
        psb_xrandr_info->output_head = psb_xrandr_info->output_tail = NULL;
    }
#if 0
    //destroy the full-screen window
    //FIXME: commited out for X Error message: BadDrawable, need more investigation
    if (va_output) {
        if (va_output->extend_drawable) {
            XDestroyWindow(ctx->native_dpy, va_output->extend_drawable);
            va_output->extend_drawable = 0;
            texture_priv->extend_dri_init_flag = 0;
        }
    }
#endif
    for (i = 0; i < psb_xrandr_info->res->noutput; i++) {
        output_info = XRRGetOutputInfo(psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->outputs[i]);
        if (output_info) {
            p_output = (psb_xrandr_output_p)calloc(1, sizeof(psb_xrandr_output_s));
            if (!p_output) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "output of memory\n");
                return;
            }

            if (i == 0)
                psb_xrandr_info->output_head = psb_xrandr_info->output_tail = p_output;

            p_output->output_id = psb_xrandr_info->res->outputs[i];

            p_output->connection = output_info->connection;
            if (p_output->connection == RR_Connected)
                psb_xrandr_info->nconnected_output++;

            strcpy(p_output->name, output_info->name);

            if (output_info->crtc)
                p_output->crtc = get_crtc_by_id(output_info->crtc);
            else
                p_output->crtc = NULL;

            psb_xrandr_info->output_tail->next = p_output;
            p_output->next = NULL;
            psb_xrandr_info->output_tail = p_output;
        } else {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get output_info\n");
            pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex);
            return;
        }
    }

    psb_xrandr_coordinate_init(ctx);

    psb_RecalcAlternativeOutput(ctx);
    pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex);
}