Edit

IABSD.fr/xenocara/lib/libXrandr/src/XrrScreen.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2016-11-03 10:47:58
    Hash : 20bda1d5
    Message : Update to libXrandr 1.5.1

  • lib/libXrandr/src/XrrScreen.c
  • /*
     * Copyright © 2006 Keith Packard
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that copyright
     * notice and this permission notice appear in supporting documentation, and
     * that the name of the copyright holders not be used in advertising or
     * publicity pertaining to distribution of the software without specific,
     * written prior permission.  The copyright holders make no representations
     * about the suitability of this software for any purpose.  It is provided "as
     * is" without express or implied warranty.
     *
     * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     * OF THIS SOFTWARE.
     */
    
    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    
    #include <limits.h>
    #include <stdio.h>
    #include <X11/Xlib.h>
    /* we need to be able to manipulate the Display structure on events */
    #include <X11/Xlibint.h>
    #include <X11/extensions/render.h>
    #include <X11/extensions/Xrender.h>
    #include "Xrandrint.h"
    
    /*
     * this is cheating on the knowledge that the two requests are identical
     * but for the request number.
     */
    static XRRScreenResources *
    doGetScreenResources (Display *dpy, Window window, int poll)
    {
        XExtDisplayInfo		*info = XRRFindDisplay(dpy);
        xRRGetScreenResourcesReply  rep;
        xRRGetScreenResourcesReq	*req;
        _XAsyncHandler		async;
        _XRRVersionState		async_state;
        int				nbytes, nbytesRead, rbytes;
        int				i;
        xRRQueryVersionReq		*vreq;
        XRRScreenResources		*xrsr;
        char			*names;
        char			*wire_names, *wire_name;
        Bool			getting_version = False;
        XRandRInfo			*xrri;
    
        RRCheckExtension (dpy, info, NULL);
    
        LockDisplay (dpy);
        xrri = (XRandRInfo *) info->data;
    
        if (xrri->major_version == -1)
        {
    	/* hide a version query in the request */
    	GetReq (RRQueryVersion, vreq);
    	vreq->reqType = info->codes->major_opcode;
    	vreq->randrReqType = X_RRQueryVersion;
    	vreq->majorVersion = RANDR_MAJOR;
    	vreq->minorVersion = RANDR_MINOR;
    
    	async_state.version_seq = dpy->request;
    	async_state.error = False;
    	async.next = dpy->async_handlers;
    	async.handler = _XRRVersionHandler;
    	async.data = (XPointer) &async_state;
    	dpy->async_handlers = &async;
    
    	getting_version = True;
        }
    
        GetReq (RRGetScreenResources, req);
        req->reqType = info->codes->major_opcode;
        req->randrReqType = poll ? X_RRGetScreenResources
    			     : X_RRGetScreenResourcesCurrent;
        req->window = window;
    
        if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
        {
    	if (getting_version)
    	    DeqAsyncHandler (dpy, &async);
    	UnlockDisplay (dpy);
    	SyncHandle ();
    	return NULL;
        }
        if (getting_version)
        {
    	DeqAsyncHandler (dpy, &async);
    	if (async_state.error)
    	{
    	    UnlockDisplay (dpy);
    	    SyncHandle();
    	    LockDisplay (dpy);
    	}
    	xrri->major_version = async_state.major_version;
    	xrri->minor_version = async_state.minor_version;
    	xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
        }
    
        if (rep.length < INT_MAX >> 2) {
    	nbytes = (long) rep.length << 2;
    
    	nbytesRead = (long) (rep.nCrtcs * 4 +
    			     rep.nOutputs * 4 +
    			     rep.nModes * SIZEOF (xRRModeInfo) +
    			     ((rep.nbytesNames + 3) & ~3));
    
    	/*
    	 * first we must compute how much space to allocate for
    	 * randr library's use; we'll allocate the structures in a single
    	 * allocation, on cleanlyness grounds.
    	 */
    
    	rbytes = (sizeof (XRRScreenResources) +
    		  rep.nCrtcs * sizeof (RRCrtc) +
    		  rep.nOutputs * sizeof (RROutput) +
    		  rep.nModes * sizeof (XRRModeInfo) +
    		  rep.nbytesNames + rep.nModes);    /* '\0' terminate names */
    
    	xrsr = (XRRScreenResources *) Xmalloc(rbytes);
    	wire_names = (char *) Xmalloc (rep.nbytesNames);
        } else {
    	nbytes = 0;
    	nbytesRead = 0;
    	rbytes = 0;
    	xrsr = NULL;
    	wire_names = NULL;
        }
    
        if (xrsr == NULL || wire_names == NULL) {
    	Xfree (xrsr);
    	Xfree (wire_names);
    	_XEatDataWords (dpy, rep.length);
    	UnlockDisplay (dpy);
    	SyncHandle ();
    	return NULL;
        }
    
        xrsr->timestamp = rep.timestamp;
        xrsr->configTimestamp = rep.configTimestamp;
        xrsr->ncrtc = rep.nCrtcs;
        xrsr->crtcs = (RRCrtc *) (xrsr + 1);
        xrsr->noutput = rep.nOutputs;
        xrsr->outputs = (RROutput *) (xrsr->crtcs + rep.nCrtcs);
        xrsr->nmode = rep.nModes;
        xrsr->modes = (XRRModeInfo *) (xrsr->outputs + rep.nOutputs);
        names = (char *) (xrsr->modes + rep.nModes);
    
        _XRead32 (dpy, (long *) xrsr->crtcs, rep.nCrtcs << 2);
        _XRead32 (dpy, (long *) xrsr->outputs, rep.nOutputs << 2);
    
        for (i = 0; i < rep.nModes; i++)  {
    	xRRModeInfo modeInfo;
    
    	_XReadPad (dpy, (char *) &modeInfo, SIZEOF (xRRModeInfo));
    	xrsr->modes[i].id = modeInfo.id;
    	xrsr->modes[i].width = modeInfo.width;
    	xrsr->modes[i].height = modeInfo.height;
    	xrsr->modes[i].dotClock = modeInfo.dotClock;
    	xrsr->modes[i].hSyncStart = modeInfo.hSyncStart;
    	xrsr->modes[i].hSyncEnd = modeInfo.hSyncEnd;
    	xrsr->modes[i].hTotal = modeInfo.hTotal;
    	xrsr->modes[i].hSkew = modeInfo.hSkew;
    	xrsr->modes[i].vSyncStart = modeInfo.vSyncStart;
    	xrsr->modes[i].vSyncEnd = modeInfo.vSyncEnd;
    	xrsr->modes[i].vTotal = modeInfo.vTotal;
    	xrsr->modes[i].nameLength = modeInfo.nameLength;
    	xrsr->modes[i].modeFlags = modeInfo.modeFlags;
        }
    
        /*
         * Read names and '\0' pad each one
         */
        _XReadPad (dpy, wire_names, rep.nbytesNames);
        wire_name = wire_names;
        for (i = 0; i < rep.nModes; i++)  {
    	xrsr->modes[i].name = names;
    	if (xrsr->modes[i].nameLength > rep.nbytesNames) {
    	    Xfree (xrsr);
    	    Xfree (wire_names);
    	    UnlockDisplay (dpy);
    	    SyncHandle ();
    	    return NULL;
    	}
    	rep.nbytesNames -= xrsr->modes[i].nameLength;
    	memcpy (names, wire_name, xrsr->modes[i].nameLength);
    	names[xrsr->modes[i].nameLength] = '\0';
    	names += xrsr->modes[i].nameLength + 1;
    	wire_name += xrsr->modes[i].nameLength;
        }
        Xfree (wire_names);
    
        /*
         * Skip any extra data
         */
        if (nbytes > nbytesRead)
    	_XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
    
        UnlockDisplay (dpy);
        SyncHandle();
        return (XRRScreenResources *) xrsr;
    }
    
    XRRScreenResources *
    XRRGetScreenResources(Display *dpy, Window window)
    {
        return doGetScreenResources(dpy, window, 1);
    }
    
    XRRScreenResources *
    XRRGetScreenResourcesCurrent(Display *dpy, Window window)
    {
        return doGetScreenResources(dpy, window, 0);
    }
    
    void
    XRRFreeScreenResources (XRRScreenResources *resources)
    {
        Xfree (resources);
    }
    
    Status
    XRRGetScreenSizeRange (Display *dpy, Window window,
    		       int *minWidth, int *minHeight,
    		       int *maxWidth, int *maxHeight)
    {
        XExtDisplayInfo		*info = XRRFindDisplay(dpy);
        xRRGetScreenSizeRangeReq	*req;
        xRRGetScreenSizeRangeReply	rep;
    
        RRCheckExtension (dpy, info, 0);
        LockDisplay (dpy);
        GetReq (RRGetScreenSizeRange, req);
        req->reqType = info->codes->major_opcode;
        req->randrReqType = X_RRGetScreenSizeRange;
        req->window = window;
        if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
        {
    	UnlockDisplay (dpy);
    	SyncHandle ();
    	return False;
        }
        UnlockDisplay (dpy);
        SyncHandle ();
        *minWidth = rep.minWidth;
        *minHeight = rep.minHeight;
        *maxWidth = rep.maxWidth;
        *maxHeight = rep.maxHeight;
       return True;
    }
    
    void
    XRRSetScreenSize (Display *dpy, Window window,
    		  int width, int height,
    		  int mmWidth, int mmHeight)
    {
        XExtDisplayInfo		*info = XRRFindDisplay(dpy);
        xRRSetScreenSizeReq		*req;
    
        RRSimpleCheckExtension (dpy, info);
        LockDisplay (dpy);
        GetReq (RRSetScreenSize, req);
        req->reqType = info->codes->major_opcode;
        req->randrReqType = X_RRSetScreenSize;
        req->window = window;
        req->width = width;
        req->height = height;
        req->widthInMillimeters = mmWidth;
        req->heightInMillimeters = mmHeight;
        UnlockDisplay (dpy);
        SyncHandle ();
    }