f13a9327a6a277bd49ed091c10597050c888d39b
[framework/uifw/xorg/lib/libxrandr.git] / src / XrrOutput.c
1 /*
2  * Copyright © 2006 Keith Packard
3  * Copyright © 2008 Red Hat, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS SOFTWARE.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <X11/Xlib.h>
30 /* we need to be able to manipulate the Display structure on events */
31 #include <X11/Xlibint.h>
32 #include <X11/extensions/render.h>
33 #include <X11/extensions/Xrender.h>
34 #include "Xrandrint.h"
35
36 #define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
37
38 XRROutputInfo *
39 XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output)
40 {
41     XExtDisplayInfo             *info = XRRFindDisplay(dpy);
42     xRRGetOutputInfoReply       rep;
43     xRRGetOutputInfoReq         *req;
44     int                         nbytes, nbytesRead, rbytes;
45     XRROutputInfo               *xoi;
46
47     RRCheckExtension (dpy, info, NULL);
48
49     LockDisplay (dpy);
50     GetReq (RRGetOutputInfo, req);
51     req->reqType = info->codes->major_opcode;
52     req->randrReqType = X_RRGetOutputInfo;
53     req->output = output;
54     req->configTimestamp = resources->configTimestamp;
55
56     if (!_XReply (dpy, (xReply *) &rep, OutputInfoExtra >> 2, xFalse))
57     {
58         UnlockDisplay (dpy);
59         SyncHandle ();
60         return NULL;
61     }
62
63     nbytes = ((long) (rep.length) << 2) - OutputInfoExtra;
64
65     nbytesRead = (long) (rep.nCrtcs * 4 +
66                          rep.nModes * 4 +
67                          rep.nClones * 4 +
68                          ((rep.nameLength + 3) & ~3));
69
70     /*
71      * first we must compute how much space to allocate for
72      * randr library's use; we'll allocate the structures in a single
73      * allocation, on cleanlyness grounds.
74      */
75
76     rbytes = (sizeof (XRROutputInfo) +
77               rep.nCrtcs * sizeof (RRCrtc) +
78               rep.nModes * sizeof (RRMode) +
79               rep.nClones * sizeof (RROutput) +
80               rep.nameLength + 1);          /* '\0' terminate name */
81
82     xoi = (XRROutputInfo *) Xmalloc(rbytes);
83     if (xoi == NULL) {
84         _XEatData (dpy, (unsigned long) nbytes);
85         UnlockDisplay (dpy);
86         SyncHandle ();
87         return NULL;
88     }
89
90     xoi->timestamp = rep.timestamp;
91     xoi->crtc = rep.crtc;
92     xoi->mm_width = rep.mmWidth;
93     xoi->mm_height = rep.mmHeight;
94     xoi->connection = rep.connection;
95     xoi->subpixel_order = rep.subpixelOrder;
96     xoi->ncrtc = rep.nCrtcs;
97     xoi->crtcs = (RRCrtc *) (xoi + 1);
98     xoi->nmode = rep.nModes;
99     xoi->npreferred = rep.nPreferred;
100     xoi->modes = (RRMode *) (xoi->crtcs + rep.nCrtcs);
101     xoi->nclone = rep.nClones;
102     xoi->clones = (RROutput *) (xoi->modes + rep.nModes);
103     xoi->name = (char *) (xoi->clones + rep.nClones);
104
105     _XRead32 (dpy, xoi->crtcs, rep.nCrtcs << 2);
106     _XRead32 (dpy, xoi->modes, rep.nModes << 2);
107     _XRead32 (dpy, xoi->clones, rep.nClones << 2);
108
109     /*
110      * Read name and '\0' terminate
111      */
112     _XReadPad (dpy, xoi->name, rep.nameLength);
113     xoi->name[rep.nameLength] = '\0';
114     xoi->nameLen = rep.nameLength;
115
116     /*
117      * Skip any extra data
118      */
119     if (nbytes > nbytesRead)
120         _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
121
122     UnlockDisplay (dpy);
123     SyncHandle ();
124     return (XRROutputInfo *) xoi;
125 }
126
127 void
128 XRRFreeOutputInfo (XRROutputInfo *outputInfo)
129 {
130     Xfree (outputInfo);
131 }
132
133 static Bool
134 _XRRHasOutputPrimary (int major, int minor)
135 {
136     return major > 1 || (major == 1 && minor >= 3);
137 }
138
139 void
140 XRRSetOutputPrimary(Display *dpy, Window window, RROutput output)
141 {
142     XExtDisplayInfo         *info = XRRFindDisplay(dpy);
143     xRRSetOutputPrimaryReq  *req;
144     int                     major_version, minor_version;
145
146     RRSimpleCheckExtension (dpy, info);
147
148     if (!XRRQueryVersion (dpy, &major_version, &minor_version) ||
149         !_XRRHasOutputPrimary (major_version, minor_version))
150         return;
151
152     LockDisplay(dpy);
153     GetReq (RRSetOutputPrimary, req);
154     req->reqType       = info->codes->major_opcode;
155     req->randrReqType  = X_RRSetOutputPrimary;
156     req->window        = window;
157     req->output        = output;
158
159     UnlockDisplay (dpy);
160     SyncHandle ();
161 }
162
163 RROutput
164 XRRGetOutputPrimary(Display *dpy, Window window)
165 {
166     XExtDisplayInfo         *info = XRRFindDisplay(dpy);
167     xRRGetOutputPrimaryReq  *req;
168     xRRGetOutputPrimaryReply rep;
169     int                     major_version, minor_version;
170
171     RRCheckExtension (dpy, info, 0);
172
173     if (!XRRQueryVersion (dpy, &major_version, &minor_version) ||
174         !_XRRHasOutputPrimary (major_version, minor_version))
175         return None;
176
177     LockDisplay(dpy);
178     GetReq (RRGetOutputPrimary, req);
179     req->reqType        = info->codes->major_opcode;
180     req->randrReqType   = X_RRGetOutputPrimary;
181     req->window         = window;
182
183     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
184         rep.output = None;
185
186     UnlockDisplay(dpy);
187     SyncHandle();
188
189     return rep.output;
190 }