2 * Copyright 2006 by VMware, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Except as contained in this notice, the name of the copyright holder(s)
23 * and author(s) shall not be used in advertising or otherwise to promote
24 * the sale, use or other dealings in this Software without prior written
25 * authorization from the copyright holder(s) and author(s).
31 * The implementation of the VMWARE_CTRL protocol extension that
32 * allows X clients to communicate with the driver.
35 #include <xorg-server.h>
36 #include "dixstruct.h"
37 #include "extnsionst.h"
39 #include <X11/extensions/panoramiXproto.h>
41 #include "vmw_driver.h"
42 #include "vmwarectrlproto.h"
48 *----------------------------------------------------------------------------
50 * VMwareCtrlQueryVersion --
52 * Implementation of QueryVersion command handler. Initialises and
56 * Standard response codes.
59 * Writes reply to client
61 *----------------------------------------------------------------------------
65 VMwareCtrlQueryVersion(ClientPtr client)
67 xVMwareCtrlQueryVersionReply rep = { 0, };
70 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
74 rep.sequenceNumber = client->sequence;
75 rep.majorVersion = VMWARE_CTRL_MAJOR_VERSION;
76 rep.minorVersion = VMWARE_CTRL_MINOR_VERSION;
77 if (client->swapped) {
78 swaps(&rep.sequenceNumber, n);
79 swapl(&rep.length, n);
80 swapl(&rep.majorVersion, n);
81 swapl(&rep.minorVersion, n);
83 WriteToClient(client, sizeof(xVMwareCtrlQueryVersionReply), (char *)&rep);
85 return client->noClientException;
90 *----------------------------------------------------------------------------
92 * VMwareCtrlDoSetRes --
94 * Set the custom resolution into the mode list.
96 * This is done by alternately updating one of two dynamic modes. It is
97 * done this way because the server gets upset if you try to switch
98 * to a new resolution that has the same index as the current one.
101 * TRUE on success, FALSE otherwise.
104 * One dynamic mode will be updated if successful.
106 *----------------------------------------------------------------------------
110 VMwareCtrlDoSetRes(ScrnInfoPtr pScrn,
114 struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
115 struct vmw_rect rect;
121 vmw_ioctl_update_layout(vmw, 1, &rect);
128 *----------------------------------------------------------------------------
130 * VMwareCtrlSetRes --
132 * Implementation of SetRes command handler. Initialises and sends a
136 * Standard response codes.
139 * Writes reply to client
141 *----------------------------------------------------------------------------
145 VMwareCtrlSetRes(ClientPtr client)
147 REQUEST(xVMwareCtrlSetResReq);
148 xVMwareCtrlSetResReply rep = { 0, };
153 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
155 if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
159 pScrn = ext->extPrivate;
160 if (pScrn->scrnIndex != stuff->screen) {
164 if (!VMwareCtrlDoSetRes(pScrn, stuff->x, stuff->y)) {
169 rep.length = (sizeof(xVMwareCtrlSetResReply) - sizeof(xGenericReply)) >> 2;
170 rep.sequenceNumber = client->sequence;
171 rep.screen = stuff->screen;
174 if (client->swapped) {
175 swaps(&rep.sequenceNumber, n);
176 swapl(&rep.length, n);
177 swapl(&rep.screen, n);
181 WriteToClient(client, sizeof(xVMwareCtrlSetResReply), (char *)&rep);
183 return client->noClientException;
188 *----------------------------------------------------------------------------
190 * VMwareCtrlDoSetTopology --
192 * Set the custom topology and set a dynamic mode to the bounding box
193 * of the passed topology. If a topology is already pending, then do
194 * nothing but do not return failure.
197 * TRUE on success, FALSE otherwise.
200 * One dynamic mode and the pending xinerama state will be updated if
203 *----------------------------------------------------------------------------
207 VMwareCtrlDoSetTopology(ScrnInfoPtr pScrn,
208 xXineramaScreenInfo *extents,
209 unsigned long number)
211 struct vmw_rect *rects;
212 struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
215 rects = calloc(number, sizeof(*rects));
219 for (i = 0; i < number; i++) {
220 rects[i].x = extents[i].x_org;
221 rects[i].y = extents[i].y_org;
222 rects[i].w = extents[i].width;
223 rects[i].h = extents[i].height;
226 vmw_ioctl_update_layout(vmw, number, rects);
234 *----------------------------------------------------------------------------
236 * VMwareCtrlSetTopology --
238 * Implementation of SetTopology command handler. Initialises and sends a
242 * Standard response codes.
245 * Writes reply to client
247 *----------------------------------------------------------------------------
251 VMwareCtrlSetTopology(ClientPtr client)
253 REQUEST(xVMwareCtrlSetTopologyReq);
254 xVMwareCtrlSetTopologyReply rep = { 0, };
258 xXineramaScreenInfo *extents;
260 REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq);
262 if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
266 pScrn = ext->extPrivate;
267 if (pScrn->scrnIndex != stuff->screen) {
271 extents = (xXineramaScreenInfo *)(stuff + 1);
272 if (!VMwareCtrlDoSetTopology(pScrn, extents, stuff->number)) {
277 rep.length = (sizeof(xVMwareCtrlSetTopologyReply) - sizeof(xGenericReply)) >> 2;
278 rep.sequenceNumber = client->sequence;
279 rep.screen = stuff->screen;
280 if (client->swapped) {
281 swaps(&rep.sequenceNumber, n);
282 swapl(&rep.length, n);
283 swapl(&rep.screen, n);
285 WriteToClient(client, sizeof(xVMwareCtrlSetTopologyReply), (char *)&rep);
287 return client->noClientException;
292 *----------------------------------------------------------------------------
294 * VMwareCtrlDispatch --
296 * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for
300 * Standard response codes.
303 * Side effects of individual command handlers.
305 *----------------------------------------------------------------------------
309 VMwareCtrlDispatch(ClientPtr client)
313 switch(stuff->data) {
314 case X_VMwareCtrlQueryVersion:
315 return VMwareCtrlQueryVersion(client);
316 case X_VMwareCtrlSetRes:
317 return VMwareCtrlSetRes(client);
318 case X_VMwareCtrlSetTopology:
319 return VMwareCtrlSetTopology(client);
326 *----------------------------------------------------------------------------
328 * SVMwareCtrlQueryVersion --
330 * Wrapper for QueryVersion handler that handles input from other-endian
334 * Standard response codes.
337 * Side effects of unswapped implementation.
339 *----------------------------------------------------------------------------
343 SVMwareCtrlQueryVersion(ClientPtr client)
347 REQUEST(xVMwareCtrlQueryVersionReq);
348 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
350 swaps(&stuff->length, n);
352 return VMwareCtrlQueryVersion(client);
357 *----------------------------------------------------------------------------
359 * SVMwareCtrlSetRes --
361 * Wrapper for SetRes handler that handles input from other-endian
365 * Standard response codes.
368 * Side effects of unswapped implementation.
370 *----------------------------------------------------------------------------
374 SVMwareCtrlSetRes(ClientPtr client)
378 REQUEST(xVMwareCtrlSetResReq);
379 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
381 swaps(&stuff->length, n);
382 swapl(&stuff->screen, n);
386 return VMwareCtrlSetRes(client);
391 *----------------------------------------------------------------------------
393 * SVMwareCtrlSetTopology --
395 * Wrapper for SetTopology handler that handles input from other-endian
399 * Standard response codes.
402 * Side effects of unswapped implementation.
404 *----------------------------------------------------------------------------
408 SVMwareCtrlSetTopology(ClientPtr client)
412 REQUEST(xVMwareCtrlSetTopologyReq);
413 REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq);
415 swaps(&stuff->length, n);
416 swapl(&stuff->screen, n);
417 swapl(&stuff->number, n);
418 /* Each extent is a struct of shorts. */
421 return VMwareCtrlSetTopology(client);
426 *----------------------------------------------------------------------------
428 * SVMwareCtrlDispatch --
430 * Wrapper for dispatcher that handles input from other-endian clients.
433 * Standard response codes.
436 * Side effects of individual command handlers.
438 *----------------------------------------------------------------------------
442 SVMwareCtrlDispatch(ClientPtr client)
446 switch(stuff->data) {
447 case X_VMwareCtrlQueryVersion:
448 return SVMwareCtrlQueryVersion(client);
449 case X_VMwareCtrlSetRes:
450 return SVMwareCtrlSetRes(client);
451 case X_VMwareCtrlSetTopology:
452 return SVMwareCtrlSetTopology(client);
459 *----------------------------------------------------------------------------
461 * VMwareCtrlResetProc --
463 * Cleanup handler called when the extension is removed.
471 *----------------------------------------------------------------------------
475 VMwareCtrlResetProc(ExtensionEntry* extEntry)
477 /* Currently, no cleanup is necessary. */
482 *----------------------------------------------------------------------------
484 * VMwareCtrl_ExitInit --
486 * Initialiser for the VMWARE_CTRL protocol extension.
492 * Protocol extension will be registered if successful.
494 *----------------------------------------------------------------------------
498 vmw_ctrl_ext_init(struct vmw_customizer *vmw)
500 ExtensionEntry *myext;
501 ScrnInfoPtr pScrn = vmw->pScrn;
503 if (!(myext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
504 if (!(myext = AddExtension(VMWARE_CTRL_PROTOCOL_NAME, 0, 0,
508 StandardMinorOpcode))) {
509 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
510 "Failed to add VMWARE_CTRL extension\n");
515 * For now, only support one screen as that's all the virtual
518 myext->extPrivate = pScrn;
520 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
521 "Initialized VMWARE_CTRL extension version %d.%d\n",
522 VMWARE_CTRL_MAJOR_VERSION, VMWARE_CTRL_MINOR_VERSION);