Commit 44374369 authored by Keith Packard's avatar Keith Packard Committed by Dave Airlie

Add monitors, update to version 1.5 (v2)

v2: [airlied]
xrandr was giving the outputs from 0 for each monitor instead of
incrementing the pointer.
add get_active support.
Reviewed-by: default avatarDave Airlie <airlied@redhat.com>
Signed-off-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
parent 7402eaa0
......@@ -29,7 +29,7 @@ AC_PREREQ([2.60])
# digit in the version number to track changes which don't affect the
# protocol, so Xrandr version l.n.m corresponds to protocol version l.n
#
AC_INIT([libXrandr], [1.4.2],
AC_INIT([libXrandr], [1.5.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXrandr])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
......
......@@ -552,6 +552,36 @@ XRRGetProviderProperty (Display *dpy, RRProvider provider,
unsigned long *nitems, unsigned long *bytes_after,
unsigned char **prop);
typedef struct _XRRMonitorInfo {
Atom name;
Bool primary;
Bool automatic;
int noutput;
int x;
int y;
int width;
int height;
int mwidth;
int mheight;
RROutput *outputs;
} XRRMonitorInfo;
XRRMonitorInfo *
XRRAllocateMonitor(Display *dpy, int noutput);
XRRMonitorInfo *
XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors);
void
XRRSetMonitor(Display *dpy, Window window, XRRMonitorInfo *monitor);
void
XRRDeleteMonitor(Display *dpy, Window window, Atom name);
void
XRRFreeMonitors(XRRMonitorInfo *monitors);
_XFUNCPROTOEND
#endif /* _XRANDR_H_ */
......@@ -10,7 +10,8 @@ libXrandr_la_SOURCES = \
XrrProperty.c \
XrrScreen.c \
XrrProvider.c \
XrrProviderProperty.c
XrrProviderProperty.c \
XrrMonitor.c
libXrandr_la_LIBADD = @RANDR_LIBS@
......
/*
* Copyright © 2014 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 <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"
XRRMonitorInfo *
XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors)
{
XExtDisplayInfo *info = XRRFindDisplay(dpy);
xRRGetMonitorsReply rep;
xRRGetMonitorsReq *req;
int nbytes, nbytesRead, rbytes;
int nmon, noutput;
int m, o;
char *buf, *buf_head;
xRRMonitorInfo *xmon;
CARD32 *xoutput;
XRRMonitorInfo *mon = NULL;
RROutput *output;
RRCheckExtension (dpy, info, NULL);
*nmonitors = -1;
LockDisplay (dpy);
GetReq (RRGetMonitors, req);
req->reqType = info->codes->major_opcode;
req->randrReqType = X_RRGetMonitors;
req->window = window;
req->get_active = get_active;
if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
{
UnlockDisplay (dpy);
SyncHandle ();
return NULL;
}
nbytes = (long) rep.length << 2;
nmon = rep.nmonitors;
noutput = rep.noutputs;
nbytesRead = nmon * SIZEOF(xRRMonitorInfo) + noutput * 4;
if (nmon > 0) {
/*
* 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 = nmon * sizeof (XRRMonitorInfo) + noutput * sizeof(RROutput);
buf = buf_head = Xmalloc (nbytesRead);
mon = Xmalloc (rbytes);
if (buf == NULL || mon == NULL) {
if (buf != NULL) Xfree(buf);
if (mon != NULL) Xfree(mon);
_XEatDataWords (dpy, rep.length);
UnlockDisplay (dpy);
SyncHandle ();
return NULL;
}
_XReadPad(dpy, buf, nbytesRead);
output = (RROutput *) (mon + nmon);
for (m = 0; m < nmon; m++) {
xmon = (xRRMonitorInfo *) buf;
mon[m].name = xmon->name;
mon[m].primary = xmon->primary;
mon[m].automatic = xmon->automatic;
mon[m].noutput = xmon->noutput;
mon[m].x = xmon->x;
mon[m].y = xmon->y;
mon[m].width = xmon->width;
mon[m].height = xmon->height;
mon[m].mwidth = xmon->widthInMillimeters;
mon[m].mheight = xmon->heightInMillimeters;
mon[m].outputs = output;
buf += SIZEOF (xRRMonitorInfo);
xoutput = (CARD32 *) buf;
for (o = 0; o < xmon->noutput; o++)
output[o] = xoutput[o];
output += xmon->noutput;
buf += xmon->noutput * 4;
}
Xfree(buf_head);
}
/*
* Skip any extra data
*/
if (nbytes > nbytesRead)
_XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
UnlockDisplay (dpy);
SyncHandle ();
*nmonitors = nmon;
return mon;
}
void
XRRSetMonitor(Display *dpy, Window window, XRRMonitorInfo *monitor)
{
XExtDisplayInfo *info = XRRFindDisplay(dpy);
xRRSetMonitorReq *req;
RRSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq (RRSetMonitor, req);
req->reqType = info->codes->major_opcode;
req->randrReqType = X_RRSetMonitor;
req->length += monitor->noutput;
req->window = window;
req->monitor.name = monitor->name;
req->monitor.primary = monitor->primary;
req->monitor.automatic = False;
req->monitor.noutput = monitor->noutput;
req->monitor.x = monitor->x;
req->monitor.y = monitor->y;
req->monitor.width = monitor->width;
req->monitor.height = monitor->height;
req->monitor.widthInMillimeters = monitor->mwidth;
req->monitor.heightInMillimeters = monitor->mheight;
Data32 (dpy, monitor->outputs, monitor->noutput * 4);
UnlockDisplay (dpy);
SyncHandle ();
}
void
XRRDeleteMonitor(Display *dpy, Window window, Atom name)
{
XExtDisplayInfo *info = XRRFindDisplay(dpy);
xRRDeleteMonitorReq *req;
RRSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq (RRDeleteMonitor, req);
req->reqType = info->codes->major_opcode;
req->randrReqType = X_RRDeleteMonitor;
req->window = window;
req->name = name;
UnlockDisplay (dpy);
SyncHandle ();
}
XRRMonitorInfo *
XRRAllocateMonitor(Display *dpy, int noutput)
{
XRRMonitorInfo *monitor = calloc(1, sizeof (XRRMonitorInfo) + noutput * sizeof (RROutput));
if (!monitor)
return NULL;
monitor->outputs = (RROutput *) (monitor + 1);
monitor->noutput = noutput;
return monitor;
}
void
XRRFreeMonitors(XRRMonitorInfo *monitors)
{
if (monitors)
Xfree(monitors);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment