1a241306cSmrg/*
2a241306cSmrg * Copyright 2006 by VMware, Inc.
3a241306cSmrg *
4a241306cSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5a241306cSmrg * copy of this software and associated documentation files (the "Software"),
6a241306cSmrg * to deal in the Software without restriction, including without limitation
7a241306cSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a241306cSmrg * and/or sell copies of the Software, and to permit persons to whom the
9a241306cSmrg * Software is furnished to do so, subject to the following conditions:
10a241306cSmrg *
11a241306cSmrg * The above copyright notice and this permission notice shall be included in
12a241306cSmrg * all copies or substantial portions of the Software.
13a241306cSmrg *
14a241306cSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15a241306cSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16a241306cSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17a241306cSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18a241306cSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19a241306cSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20a241306cSmrg * OTHER DEALINGS IN THE SOFTWARE.
21a241306cSmrg *
22a241306cSmrg * Except as contained in this notice, the name of the copyright holder(s)
23a241306cSmrg * and author(s) shall not be used in advertising or otherwise to promote
24a241306cSmrg * the sale, use or other dealings in this Software without prior written
25a241306cSmrg * authorization from the copyright holder(s) and author(s).
26a241306cSmrg */
27a241306cSmrg
28a241306cSmrg/*
29a241306cSmrg * libvmwarectrl.c --
30a241306cSmrg *
31a241306cSmrg *      The VMWARE_CTRL client library.
32a241306cSmrg */
33a241306cSmrg
34a241306cSmrg
35a241306cSmrg#include <X11/Xlibint.h>
36a241306cSmrg#include "libvmwarectrl.h"
37a241306cSmrg#include "vmwarectrlproto.h"
38a241306cSmrg#include <X11/extensions/Xext.h>
39a241306cSmrg#include <X11/extensions/extutil.h>
40a241306cSmrg
41a241306cSmrg
42a241306cSmrg/*
43a241306cSmrg * Static data and functions.
44a241306cSmrg */
45a241306cSmrg
46a241306cSmrgstatic XExtensionInfo _vmwarectrl_info_data;
47a241306cSmrgstatic XExtensionInfo *vmwarectrl_info = &_vmwarectrl_info_data;
48a241306cSmrgstatic char *vmwarectrl_extension_name = VMWARE_CTRL_PROTOCOL_NAME;
49a241306cSmrg
50a241306cSmrg#define VMwareCtrlCheckExtension(dpy, i, val) \
51a241306cSmrg  XextCheckExtension(dpy, i, vmwarectrl_extension_name, val)
52a241306cSmrg
53a241306cSmrgstatic int close_display(Display *dpy, XExtCodes *codes);
54a241306cSmrg
55a241306cSmrgstatic /* const */ XExtensionHooks vmwarectrl_extension_hooks = {
56a241306cSmrg    NULL,          /* create_gc */
57a241306cSmrg    NULL,          /* copy_gc */
58a241306cSmrg    NULL,          /* flush_gc */
59a241306cSmrg    NULL,          /* free_gc */
60a241306cSmrg    NULL,          /* create_font */
61a241306cSmrg    NULL,          /* free_font */
62a241306cSmrg    close_display, /* close_display */
63a241306cSmrg    NULL,          /* wire_to_event */
64a241306cSmrg    NULL,          /* event_to_wire */
65a241306cSmrg    NULL,          /* error */
66a241306cSmrg    NULL,          /* error_string */
67a241306cSmrg};
68a241306cSmrg
69a241306cSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, vmwarectrl_info)
70a241306cSmrg
71a241306cSmrgstatic XEXT_GENERATE_FIND_DISPLAY (find_display, vmwarectrl_info,
72a241306cSmrg				   vmwarectrl_extension_name,
73a241306cSmrg				   &vmwarectrl_extension_hooks,
74a241306cSmrg				   0, NULL)
75a241306cSmrg
76a241306cSmrg/*
77a241306cSmrg *----------------------------------------------------------------------------
78a241306cSmrg *
79a241306cSmrg * VMwareCtrl_QueryExtension --
80a241306cSmrg *
81a241306cSmrg *      Standard QueryExtension implementation. Not very interesting for
82a241306cSmrg *      VMWARE_CTRL as it doesn't define any events or errors.
83a241306cSmrg *
84a241306cSmrg * Results:
85a241306cSmrg *      True if information is successfully retrieved. False otherwise.
86a241306cSmrg *
87a241306cSmrg * Side effects:
88a241306cSmrg *      None.
89a241306cSmrg *
90a241306cSmrg *----------------------------------------------------------------------------
91a241306cSmrg */
92a241306cSmrg
93a241306cSmrgBool
94a241306cSmrgVMwareCtrl_QueryExtension(Display *dpy,     // IN:
95a241306cSmrg                          int *event_basep, // OUT:
96a241306cSmrg                          int *error_basep) // OUT:
97a241306cSmrg{
98a241306cSmrg   XExtDisplayInfo *info = find_display(dpy);
99a241306cSmrg
100a241306cSmrg   if (XextHasExtension(info)) {
101a241306cSmrg      *event_basep = info->codes->first_event;
102a241306cSmrg      *error_basep = info->codes->first_error;
103a241306cSmrg      return True;
104a241306cSmrg   } else {
105a241306cSmrg      return False;
106a241306cSmrg   }
107a241306cSmrg}
108a241306cSmrg
109a241306cSmrg
110a241306cSmrg/*
111a241306cSmrg *----------------------------------------------------------------------------
112a241306cSmrg *
113a241306cSmrg * VMwareCtrl_QueryVersion --
114a241306cSmrg *
115a241306cSmrg *      Send the QueryVersion command to the driver and return the results.
116a241306cSmrg *
117a241306cSmrg * Results:
118a241306cSmrg *      True if information is successfully retrieved. False otherwise.
119a241306cSmrg *
120a241306cSmrg * Side effects:
121a241306cSmrg *      None.
122a241306cSmrg *
123a241306cSmrg *----------------------------------------------------------------------------
124a241306cSmrg */
125a241306cSmrg
126a241306cSmrgBool
127a241306cSmrgVMwareCtrl_QueryVersion(Display *dpy,      // IN:
128a241306cSmrg                        int *majorVersion, // OUT:
129a241306cSmrg                        int *minorVersion) // OUT:
130a241306cSmrg{
131a241306cSmrg   xVMwareCtrlQueryVersionReply rep;
132a241306cSmrg   xVMwareCtrlQueryVersionReq *req;
133a241306cSmrg   XExtDisplayInfo *info = find_display(dpy);
134a241306cSmrg   Bool ret = False;
135a241306cSmrg
136a241306cSmrg   VMwareCtrlCheckExtension(dpy, info, False);
137a241306cSmrg   LockDisplay(dpy);
138a241306cSmrg
139a241306cSmrg   GetReq(VMwareCtrlQueryVersion, req);
140a241306cSmrg   req->reqType = info->codes->major_opcode;
141a241306cSmrg   req->VMwareCtrlReqType = X_VMwareCtrlQueryVersion;
142a241306cSmrg
143a241306cSmrg   if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
144a241306cSmrg      goto exit;
145a241306cSmrg   }
146a241306cSmrg   *majorVersion = rep.majorVersion;
147a241306cSmrg   *minorVersion = rep.minorVersion;
148a241306cSmrg
149a241306cSmrg   ret = True;
150a241306cSmrg
151a241306cSmrgexit:
152a241306cSmrg   UnlockDisplay(dpy);
153a241306cSmrg   SyncHandle();
154a241306cSmrg
155a241306cSmrg   return ret;
156a241306cSmrg}
157a241306cSmrg
158a241306cSmrg
159a241306cSmrg/*
160a241306cSmrg *----------------------------------------------------------------------------
161a241306cSmrg *
162a241306cSmrg * VMwareCtrl_SetRes --
163a241306cSmrg *
164a241306cSmrg *      Send the SetRes command to the driver.
165a241306cSmrg *
166a241306cSmrg * Results:
167a241306cSmrg *      True if the resolution was set. False otherwise.
168a241306cSmrg *
169a241306cSmrg * Side effects:
170a241306cSmrg *      None.
171a241306cSmrg *
172a241306cSmrg *----------------------------------------------------------------------------
173a241306cSmrg */
174a241306cSmrg
175a241306cSmrgBool
176a241306cSmrgVMwareCtrl_SetRes(Display *dpy, // IN:
177a241306cSmrg                  int screen,   // IN:
178a241306cSmrg                  int x,        // IN:
179a241306cSmrg                  int y)        // IN:
180a241306cSmrg{
181a241306cSmrg   xVMwareCtrlSetResReply rep;
182a241306cSmrg   xVMwareCtrlSetResReq *req;
183a241306cSmrg   XExtDisplayInfo *info = find_display(dpy);
184a241306cSmrg   Bool ret = False;
185a241306cSmrg
186a241306cSmrg   VMwareCtrlCheckExtension(dpy, info, False);
187a241306cSmrg   LockDisplay(dpy);
188a241306cSmrg
189a241306cSmrg   GetReq(VMwareCtrlSetRes, req);
190a241306cSmrg   req->reqType = info->codes->major_opcode;
191a241306cSmrg   req->VMwareCtrlReqType = X_VMwareCtrlSetRes;
192a241306cSmrg   req->screen = screen;
193a241306cSmrg   req->x = x;
194a241306cSmrg   req->y = y;
195a241306cSmrg
196a241306cSmrg   if (!_XReply(dpy, (xReply *)&rep,
197a241306cSmrg                (SIZEOF(xVMwareCtrlSetResReply) - SIZEOF(xReply)) >> 2,
198a241306cSmrg                xFalse)) {
199a241306cSmrg      goto exit;
200a241306cSmrg   }
201a241306cSmrg
202a241306cSmrg   ret = True;
203a241306cSmrg
204a241306cSmrgexit:
205a241306cSmrg   UnlockDisplay(dpy);
206a241306cSmrg   SyncHandle();
207a241306cSmrg
208a241306cSmrg   return ret;
209a241306cSmrg}
210a241306cSmrg
211a241306cSmrg
212a241306cSmrg/*
213a241306cSmrg *----------------------------------------------------------------------------
214a241306cSmrg *
215a241306cSmrg * VMwareCtrl_SetTopology --
216a241306cSmrg *
217a241306cSmrg *      Send the SetTopology command to the driver.
218a241306cSmrg *
219a241306cSmrg * Results:
220a241306cSmrg *      True if the resolution and xinerama topology were set. False otherwise.
221a241306cSmrg *
222a241306cSmrg * Side effects:
223a241306cSmrg *      None.
224a241306cSmrg *
225a241306cSmrg *----------------------------------------------------------------------------
226a241306cSmrg */
227a241306cSmrg
228a241306cSmrgBool
229a241306cSmrgVMwareCtrl_SetTopology(Display *dpy,          // IN:
230a241306cSmrg                       int screen,            // IN:
231a241306cSmrg                       xXineramaScreenInfo extents[], // IN:
232a241306cSmrg                       int number)            // IN:
233a241306cSmrg{
234a241306cSmrg   xVMwareCtrlSetTopologyReply rep;
235a241306cSmrg   xVMwareCtrlSetTopologyReq *req;
236a241306cSmrg   XExtDisplayInfo *info = find_display(dpy);
237a241306cSmrg   Bool ret = False;
238a241306cSmrg   long len;
239a241306cSmrg
240a241306cSmrg   VMwareCtrlCheckExtension(dpy, info, False);
241a241306cSmrg   LockDisplay(dpy);
242a241306cSmrg
243a241306cSmrg   GetReq(VMwareCtrlSetTopology, req);
244a241306cSmrg   req->reqType = info->codes->major_opcode;
245a241306cSmrg   req->VMwareCtrlReqType = X_VMwareCtrlSetTopology;
246a241306cSmrg   req->screen = screen;
247a241306cSmrg   req->number = number;
248a241306cSmrg
249a241306cSmrg   len = ((long) number) << 1;
250a241306cSmrg   SetReqLen(req, len, len);
251a241306cSmrg   len <<= 2;
252a241306cSmrg   _XSend(dpy, (char *)extents, len);
253a241306cSmrg
254a241306cSmrg   if (!_XReply(dpy, (xReply *)&rep,
255a241306cSmrg                (SIZEOF(xVMwareCtrlSetTopologyReply) - SIZEOF(xReply)) >> 2,
256a241306cSmrg                xFalse)) {
257a241306cSmrg      goto exit;
258a241306cSmrg   }
259a241306cSmrg
260a241306cSmrg   ret = True;
261a241306cSmrg
262a241306cSmrgexit:
263a241306cSmrg   UnlockDisplay(dpy);
264a241306cSmrg   SyncHandle();
265a241306cSmrg
266a241306cSmrg   return ret;
267a241306cSmrg}
268