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 "dixstruct.h"
36 #include "extnsionst.h"
38 #include <X11/extensions/panoramiXproto.h>
40 #include "vmw_driver.h"
41 #include "vmwarectrlproto.h"
47 *----------------------------------------------------------------------------
49 * VMwareCtrlQueryVersion --
51 * Implementation of QueryVersion command handler. Initialises and
55 * Standard response codes.
58 * Writes reply to client
60 *----------------------------------------------------------------------------
64 VMwareCtrlQueryVersion(ClientPtr client
)
66 xVMwareCtrlQueryVersionReply rep
= { 0, };
69 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq
);
73 rep
.sequenceNumber
= client
->sequence
;
74 rep
.majorVersion
= VMWARE_CTRL_MAJOR_VERSION
;
75 rep
.minorVersion
= VMWARE_CTRL_MINOR_VERSION
;
76 if (client
->swapped
) {
77 swaps(&rep
.sequenceNumber
, n
);
78 swapl(&rep
.length
, n
);
79 swapl(&rep
.majorVersion
, n
);
80 swapl(&rep
.minorVersion
, n
);
82 WriteToClient(client
, sizeof(xVMwareCtrlQueryVersionReply
), (char *)&rep
);
84 return client
->noClientException
;
89 *----------------------------------------------------------------------------
91 * VMwareCtrlDoSetRes --
93 * Set the custom resolution into the mode list.
95 * This is done by alternately updating one of two dynamic modes. It is
96 * done this way because the server gets upset if you try to switch
97 * to a new resolution that has the same index as the current one.
100 * TRUE on success, FALSE otherwise.
103 * One dynamic mode will be updated if successful.
105 *----------------------------------------------------------------------------
109 VMwareCtrlDoSetRes(ScrnInfoPtr pScrn
,
113 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
114 struct vmw_rect rect
;
120 vmw_ioctl_update_layout(vmw
, 1, &rect
);
127 *----------------------------------------------------------------------------
129 * VMwareCtrlSetRes --
131 * Implementation of SetRes command handler. Initialises and sends a
135 * Standard response codes.
138 * Writes reply to client
140 *----------------------------------------------------------------------------
144 VMwareCtrlSetRes(ClientPtr client
)
146 REQUEST(xVMwareCtrlSetResReq
);
147 xVMwareCtrlSetResReply rep
= { 0, };
152 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq
);
154 if (!(ext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
158 pScrn
= ext
->extPrivate
;
159 if (pScrn
->scrnIndex
!= stuff
->screen
) {
163 if (!VMwareCtrlDoSetRes(pScrn
, stuff
->x
, stuff
->y
)) {
168 rep
.length
= (sizeof(xVMwareCtrlSetResReply
) - sizeof(xGenericReply
)) >> 2;
169 rep
.sequenceNumber
= client
->sequence
;
170 rep
.screen
= stuff
->screen
;
173 if (client
->swapped
) {
174 swaps(&rep
.sequenceNumber
, n
);
175 swapl(&rep
.length
, n
);
176 swapl(&rep
.screen
, n
);
180 WriteToClient(client
, sizeof(xVMwareCtrlSetResReply
), (char *)&rep
);
182 return client
->noClientException
;
187 *----------------------------------------------------------------------------
189 * VMwareCtrlDoSetTopology --
191 * Set the custom topology and set a dynamic mode to the bounding box
192 * of the passed topology. If a topology is already pending, then do
193 * nothing but do not return failure.
196 * TRUE on success, FALSE otherwise.
199 * One dynamic mode and the pending xinerama state will be updated if
202 *----------------------------------------------------------------------------
206 VMwareCtrlDoSetTopology(ScrnInfoPtr pScrn
,
207 xXineramaScreenInfo
*extents
,
208 unsigned long number
)
210 struct vmw_rect
*rects
;
211 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
214 rects
= xcalloc(number
, sizeof(*rects
));
218 for (i
= 0; i
< number
; i
++) {
219 rects
[i
].x
= extents
[i
].x_org
;
220 rects
[i
].y
= extents
[i
].y_org
;
221 rects
[i
].w
= extents
[i
].width
;
222 rects
[i
].h
= extents
[i
].height
;
225 vmw_ioctl_update_layout(vmw
, number
, rects
);
233 *----------------------------------------------------------------------------
235 * VMwareCtrlSetTopology --
237 * Implementation of SetTopology command handler. Initialises and sends a
241 * Standard response codes.
244 * Writes reply to client
246 *----------------------------------------------------------------------------
250 VMwareCtrlSetTopology(ClientPtr client
)
252 REQUEST(xVMwareCtrlSetTopologyReq
);
253 xVMwareCtrlSetTopologyReply rep
= { 0, };
257 xXineramaScreenInfo
*extents
;
259 REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq
);
261 if (!(ext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
265 pScrn
= ext
->extPrivate
;
266 if (pScrn
->scrnIndex
!= stuff
->screen
) {
270 extents
= (xXineramaScreenInfo
*)(stuff
+ 1);
271 if (!VMwareCtrlDoSetTopology(pScrn
, extents
, stuff
->number
)) {
276 rep
.length
= (sizeof(xVMwareCtrlSetTopologyReply
) - sizeof(xGenericReply
)) >> 2;
277 rep
.sequenceNumber
= client
->sequence
;
278 rep
.screen
= stuff
->screen
;
279 if (client
->swapped
) {
280 swaps(&rep
.sequenceNumber
, n
);
281 swapl(&rep
.length
, n
);
282 swapl(&rep
.screen
, n
);
284 WriteToClient(client
, sizeof(xVMwareCtrlSetTopologyReply
), (char *)&rep
);
286 return client
->noClientException
;
291 *----------------------------------------------------------------------------
293 * VMwareCtrlDispatch --
295 * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for
299 * Standard response codes.
302 * Side effects of individual command handlers.
304 *----------------------------------------------------------------------------
308 VMwareCtrlDispatch(ClientPtr client
)
312 switch(stuff
->data
) {
313 case X_VMwareCtrlQueryVersion
:
314 return VMwareCtrlQueryVersion(client
);
315 case X_VMwareCtrlSetRes
:
316 return VMwareCtrlSetRes(client
);
317 case X_VMwareCtrlSetTopology
:
318 return VMwareCtrlSetTopology(client
);
325 *----------------------------------------------------------------------------
327 * SVMwareCtrlQueryVersion --
329 * Wrapper for QueryVersion handler that handles input from other-endian
333 * Standard response codes.
336 * Side effects of unswapped implementation.
338 *----------------------------------------------------------------------------
342 SVMwareCtrlQueryVersion(ClientPtr client
)
346 REQUEST(xVMwareCtrlQueryVersionReq
);
347 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq
);
349 swaps(&stuff
->length
, n
);
351 return VMwareCtrlQueryVersion(client
);
356 *----------------------------------------------------------------------------
358 * SVMwareCtrlSetRes --
360 * Wrapper for SetRes handler that handles input from other-endian
364 * Standard response codes.
367 * Side effects of unswapped implementation.
369 *----------------------------------------------------------------------------
373 SVMwareCtrlSetRes(ClientPtr client
)
377 REQUEST(xVMwareCtrlSetResReq
);
378 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq
);
380 swaps(&stuff
->length
, n
);
381 swapl(&stuff
->screen
, n
);
385 return VMwareCtrlSetRes(client
);
390 *----------------------------------------------------------------------------
392 * SVMwareCtrlSetTopology --
394 * Wrapper for SetTopology handler that handles input from other-endian
398 * Standard response codes.
401 * Side effects of unswapped implementation.
403 *----------------------------------------------------------------------------
407 SVMwareCtrlSetTopology(ClientPtr client
)
411 REQUEST(xVMwareCtrlSetTopologyReq
);
412 REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq
);
414 swaps(&stuff
->length
, n
);
415 swapl(&stuff
->screen
, n
);
416 swapl(&stuff
->number
, n
);
417 /* Each extent is a struct of shorts. */
420 return VMwareCtrlSetTopology(client
);
425 *----------------------------------------------------------------------------
427 * SVMwareCtrlDispatch --
429 * Wrapper for dispatcher that handles input from other-endian clients.
432 * Standard response codes.
435 * Side effects of individual command handlers.
437 *----------------------------------------------------------------------------
441 SVMwareCtrlDispatch(ClientPtr client
)
445 switch(stuff
->data
) {
446 case X_VMwareCtrlQueryVersion
:
447 return SVMwareCtrlQueryVersion(client
);
448 case X_VMwareCtrlSetRes
:
449 return SVMwareCtrlSetRes(client
);
450 case X_VMwareCtrlSetTopology
:
451 return SVMwareCtrlSetTopology(client
);
458 *----------------------------------------------------------------------------
460 * VMwareCtrlResetProc --
462 * Cleanup handler called when the extension is removed.
470 *----------------------------------------------------------------------------
474 VMwareCtrlResetProc(ExtensionEntry
* extEntry
)
476 /* Currently, no cleanup is necessary. */
481 *----------------------------------------------------------------------------
483 * VMwareCtrl_ExitInit --
485 * Initialiser for the VMWARE_CTRL protocol extension.
491 * Protocol extension will be registered if successful.
493 *----------------------------------------------------------------------------
497 vmw_ctrl_ext_init(struct vmw_customizer
*vmw
)
499 ExtensionEntry
*myext
;
500 ScrnInfoPtr pScrn
= vmw
->pScrn
;
502 if (!(myext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
503 if (!(myext
= AddExtension(VMWARE_CTRL_PROTOCOL_NAME
, 0, 0,
507 StandardMinorOpcode
))) {
508 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
509 "Failed to add VMWARE_CTRL extension\n");
514 * For now, only support one screen as that's all the virtual
517 myext
->extPrivate
= pScrn
;
519 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
520 "Initialized VMWARE_CTRL extension version %d.%d\n",
521 VMWARE_CTRL_MAJOR_VERSION
, VMWARE_CTRL_MINOR_VERSION
);