1b042e37fSmrg/*
2b042e37fSmrg * Copyright © 2006 Keith Packard
3b042e37fSmrg *
4b042e37fSmrg * Permission to use, copy, modify, distribute, and sell this software and its
5b042e37fSmrg * documentation for any purpose is hereby granted without fee, provided that
6b042e37fSmrg * the above copyright notice appear in all copies and that both that copyright
7b042e37fSmrg * notice and this permission notice appear in supporting documentation, and
8b042e37fSmrg * that the name of the copyright holders not be used in advertising or
9b042e37fSmrg * publicity pertaining to distribution of the software without specific,
10b042e37fSmrg * written prior permission.  The copyright holders make no representations
11b042e37fSmrg * about the suitability of this software for any purpose.  It is provided "as
12b042e37fSmrg * is" without express or implied warranty.
13b042e37fSmrg *
14b042e37fSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15b042e37fSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16b042e37fSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17b042e37fSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18b042e37fSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19b042e37fSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20b042e37fSmrg * OF THIS SOFTWARE.
21b042e37fSmrg */
22b042e37fSmrg
23b042e37fSmrg#ifdef HAVE_CONFIG_H
24b042e37fSmrg#include <config.h>
25b042e37fSmrg#endif
26b042e37fSmrg
27b042e37fSmrg#include <stdio.h>
28b042e37fSmrg#include <X11/Xlib.h>
29b042e37fSmrg/* we need to be able to manipulate the Display structure on events */
30b042e37fSmrg#include <X11/Xlibint.h>
31b042e37fSmrg#include <X11/extensions/render.h>
32b042e37fSmrg#include <X11/extensions/Xrender.h>
33b042e37fSmrg#include "Xrandrint.h"
34b042e37fSmrg
35b042e37fSmrgXRRModeInfo *
368bd17e5fSmrgXRRAllocModeInfo (_Xconst char *name, int nameLength)
37b042e37fSmrg{
38b042e37fSmrg    XRRModeInfo	*mode_info;
39b042e37fSmrg
40b042e37fSmrg    mode_info = Xmalloc (sizeof (XRRModeInfo) + nameLength + 1);
41b042e37fSmrg    if (!mode_info)
42b042e37fSmrg	return NULL;
43b042e37fSmrg    memset (mode_info, '\0', sizeof (XRRModeInfo));
44b042e37fSmrg    mode_info->nameLength = nameLength;
45b042e37fSmrg    mode_info->name = (char *) (mode_info + 1);
46b042e37fSmrg    memcpy (mode_info->name, name, nameLength);
47b042e37fSmrg    mode_info->name[nameLength] = '\0';
48b042e37fSmrg    return mode_info;
49b042e37fSmrg}
50b042e37fSmrg
51b042e37fSmrgRRMode
52b042e37fSmrgXRRCreateMode (Display *dpy, Window window, XRRModeInfo *mode_info)
53b042e37fSmrg{
54b042e37fSmrg    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
55b042e37fSmrg    xRRCreateModeReq	    *req;
56b042e37fSmrg    xRRCreateModeReply	    rep;
57b042e37fSmrg
588c4a8e55Smrg    RRCheckExtension (dpy, info, None);
59b042e37fSmrg
60b042e37fSmrg    LockDisplay(dpy);
61b042e37fSmrg    GetReq (RRCreateMode, req);
62b042e37fSmrg    req->reqType = info->codes->major_opcode;
63b042e37fSmrg    req->randrReqType = X_RRCreateMode;
64b042e37fSmrg    req->length += (mode_info->nameLength + 3) >> 2;
650597fb56Smrg
66b042e37fSmrg    req->window = window;
670597fb56Smrg
68b042e37fSmrg    req->modeInfo.id = 0;
69b042e37fSmrg    req->modeInfo.width = mode_info->width;
70b042e37fSmrg    req->modeInfo.height = mode_info->height;
71b042e37fSmrg    req->modeInfo.dotClock = mode_info->dotClock;
72b042e37fSmrg    req->modeInfo.hSyncStart = mode_info->hSyncStart;
73b042e37fSmrg    req->modeInfo.hSyncEnd = mode_info->hSyncEnd;
74b042e37fSmrg    req->modeInfo.hTotal = mode_info->hTotal;
75b042e37fSmrg    req->modeInfo.hSkew = mode_info->hSkew;
76b042e37fSmrg    req->modeInfo.vSyncStart = mode_info->vSyncStart;
77b042e37fSmrg    req->modeInfo.vSyncEnd = mode_info->vSyncEnd;
78b042e37fSmrg    req->modeInfo.vTotal = mode_info->vTotal;
79b042e37fSmrg    req->modeInfo.nameLength = mode_info->nameLength;
80b042e37fSmrg    req->modeInfo.modeFlags = mode_info->modeFlags;
810597fb56Smrg
82b042e37fSmrg    Data (dpy, mode_info->name, mode_info->nameLength);
83b042e37fSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
84b042e37fSmrg    {
85b042e37fSmrg	UnlockDisplay (dpy);
86b042e37fSmrg	SyncHandle ();
87b042e37fSmrg	return None;
88b042e37fSmrg    }
890597fb56Smrg
90b042e37fSmrg    UnlockDisplay (dpy);
91b042e37fSmrg    SyncHandle ();
92b042e37fSmrg    return rep.mode;
93b042e37fSmrg}
94b042e37fSmrg
95b042e37fSmrgvoid
96b042e37fSmrgXRRDestroyMode (Display *dpy, RRMode mode)
97b042e37fSmrg{
98b042e37fSmrg    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
99b042e37fSmrg    xRRDestroyModeReq	    *req;
100b042e37fSmrg    RRSimpleCheckExtension (dpy, info);
101b042e37fSmrg
102b042e37fSmrg    LockDisplay(dpy);
103b042e37fSmrg    GetReq (RRDestroyMode, req);
104b042e37fSmrg    req->reqType = info->codes->major_opcode;
105b042e37fSmrg    req->randrReqType = X_RRDestroyMode;
106b042e37fSmrg    req->mode = mode;
107b042e37fSmrg    UnlockDisplay (dpy);
108b042e37fSmrg    SyncHandle ();
109b042e37fSmrg}
110b042e37fSmrg
111b042e37fSmrgvoid
112b042e37fSmrgXRRAddOutputMode (Display *dpy, RROutput output, RRMode mode)
113b042e37fSmrg{
114b042e37fSmrg    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
115b042e37fSmrg    xRRAddOutputModeReq	    *req;
116b042e37fSmrg    RRSimpleCheckExtension (dpy, info);
117b042e37fSmrg
118b042e37fSmrg    LockDisplay(dpy);
119b042e37fSmrg    GetReq (RRAddOutputMode, req);
120b042e37fSmrg    req->reqType = info->codes->major_opcode;
121b042e37fSmrg    req->randrReqType = X_RRAddOutputMode;
122b042e37fSmrg    req->output = output;
123b042e37fSmrg    req->mode = mode;
124b042e37fSmrg    UnlockDisplay (dpy);
125b042e37fSmrg    SyncHandle ();
126b042e37fSmrg}
127b042e37fSmrg
128b042e37fSmrgvoid
129b042e37fSmrgXRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode)
130b042e37fSmrg{
131b042e37fSmrg    XExtDisplayInfo	    *info = XRRFindDisplay(dpy);
132b042e37fSmrg    xRRDeleteOutputModeReq  *req;
133b042e37fSmrg    RRSimpleCheckExtension (dpy, info);
134b042e37fSmrg
135b042e37fSmrg    LockDisplay(dpy);
136b042e37fSmrg    GetReq (RRDeleteOutputMode, req);
137b042e37fSmrg    req->reqType = info->codes->major_opcode;
138b042e37fSmrg    req->randrReqType = X_RRDeleteOutputMode;
139b042e37fSmrg    req->output = output;
140b042e37fSmrg    req->mode = mode;
141b042e37fSmrg    UnlockDisplay (dpy);
142b042e37fSmrg    SyncHandle ();
143b042e37fSmrg}
144b042e37fSmrg
145b042e37fSmrgvoid
146b042e37fSmrgXRRFreeModeInfo (XRRModeInfo *modeInfo)
147b042e37fSmrg{
148b042e37fSmrg    Xfree (modeInfo);
149b042e37fSmrg}
150