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.
38 #include "dixstruct.h"
39 #include "extnsionst.h"
41 #include <X11/extensions/panoramiXproto.h>
43 #include "vmw_driver.h"
44 #include "vmwarectrlproto.h"
50 *----------------------------------------------------------------------------
52 * VMwareCtrlQueryVersion --
54 * Implementation of QueryVersion command handler. Initialises and
58 * Standard response codes.
61 * Writes reply to client
63 *----------------------------------------------------------------------------
67 VMwareCtrlQueryVersion(ClientPtr client
)
69 xVMwareCtrlQueryVersionReply rep
= { 0, };
72 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq
);
76 rep
.sequenceNumber
= client
->sequence
;
77 rep
.majorVersion
= VMWARE_CTRL_MAJOR_VERSION
;
78 rep
.minorVersion
= VMWARE_CTRL_MINOR_VERSION
;
79 if (client
->swapped
) {
80 swaps(&rep
.sequenceNumber
, n
);
81 swapl(&rep
.length
, n
);
82 swapl(&rep
.majorVersion
, n
);
83 swapl(&rep
.minorVersion
, n
);
85 WriteToClient(client
, sizeof(xVMwareCtrlQueryVersionReply
), (char *)&rep
);
87 return client
->noClientException
;
92 *----------------------------------------------------------------------------
94 * VMwareCtrlDoSetRes --
96 * Set the custom resolution into the mode list.
98 * This is done by alternately updating one of two dynamic modes. It is
99 * done this way because the server gets upset if you try to switch
100 * to a new resolution that has the same index as the current one.
103 * TRUE on success, FALSE otherwise.
106 * One dynamic mode will be updated if successful.
108 *----------------------------------------------------------------------------
112 VMwareCtrlDoSetRes(ScrnInfoPtr pScrn
,
116 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
117 struct vmw_rect rect
;
123 vmw_ioctl_update_layout(vmw
, 1, &rect
);
130 *----------------------------------------------------------------------------
132 * VMwareCtrlSetRes --
134 * Implementation of SetRes command handler. Initialises and sends a
138 * Standard response codes.
141 * Writes reply to client
143 *----------------------------------------------------------------------------
147 VMwareCtrlSetRes(ClientPtr client
)
149 REQUEST(xVMwareCtrlSetResReq
);
150 xVMwareCtrlSetResReply rep
= { 0, };
155 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq
);
157 if (!(ext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
161 pScrn
= ext
->extPrivate
;
162 if (pScrn
->scrnIndex
!= stuff
->screen
) {
166 if (!VMwareCtrlDoSetRes(pScrn
, stuff
->x
, stuff
->y
)) {
171 rep
.length
= (sizeof(xVMwareCtrlSetResReply
) - sizeof(xGenericReply
)) >> 2;
172 rep
.sequenceNumber
= client
->sequence
;
173 rep
.screen
= stuff
->screen
;
176 if (client
->swapped
) {
177 swaps(&rep
.sequenceNumber
, n
);
178 swapl(&rep
.length
, n
);
179 swapl(&rep
.screen
, n
);
183 WriteToClient(client
, sizeof(xVMwareCtrlSetResReply
), (char *)&rep
);
185 return client
->noClientException
;
190 *----------------------------------------------------------------------------
192 * VMwareCtrlDoSetTopology --
194 * Set the custom topology and set a dynamic mode to the bounding box
195 * of the passed topology. If a topology is already pending, then do
196 * nothing but do not return failure.
199 * TRUE on success, FALSE otherwise.
202 * One dynamic mode and the pending xinerama state will be updated if
205 *----------------------------------------------------------------------------
209 VMwareCtrlDoSetTopology(ScrnInfoPtr pScrn
,
210 xXineramaScreenInfo
*extents
,
211 unsigned long number
)
213 struct vmw_rect
*rects
;
214 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
217 rects
= xcalloc(number
, sizeof(*rects
));
221 for (i
= 0; i
< number
; i
++) {
222 rects
[i
].x
= extents
[i
].x_org
;
223 rects
[i
].y
= extents
[i
].y_org
;
224 rects
[i
].w
= extents
[i
].width
;
225 rects
[i
].h
= extents
[i
].height
;
228 vmw_ioctl_update_layout(vmw
, number
, rects
);
236 *----------------------------------------------------------------------------
238 * VMwareCtrlSetTopology --
240 * Implementation of SetTopology command handler. Initialises and sends a
244 * Standard response codes.
247 * Writes reply to client
249 *----------------------------------------------------------------------------
253 VMwareCtrlSetTopology(ClientPtr client
)
255 REQUEST(xVMwareCtrlSetTopologyReq
);
256 xVMwareCtrlSetTopologyReply rep
= { 0, };
260 xXineramaScreenInfo
*extents
;
262 REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq
);
264 if (!(ext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
268 pScrn
= ext
->extPrivate
;
269 if (pScrn
->scrnIndex
!= stuff
->screen
) {
273 extents
= (xXineramaScreenInfo
*)(stuff
+ 1);
274 if (!VMwareCtrlDoSetTopology(pScrn
, extents
, stuff
->number
)) {
279 rep
.length
= (sizeof(xVMwareCtrlSetTopologyReply
) - sizeof(xGenericReply
)) >> 2;
280 rep
.sequenceNumber
= client
->sequence
;
281 rep
.screen
= stuff
->screen
;
282 if (client
->swapped
) {
283 swaps(&rep
.sequenceNumber
, n
);
284 swapl(&rep
.length
, n
);
285 swapl(&rep
.screen
, n
);
287 WriteToClient(client
, sizeof(xVMwareCtrlSetTopologyReply
), (char *)&rep
);
289 return client
->noClientException
;
294 *----------------------------------------------------------------------------
296 * VMwareCtrlDispatch --
298 * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for
302 * Standard response codes.
305 * Side effects of individual command handlers.
307 *----------------------------------------------------------------------------
311 VMwareCtrlDispatch(ClientPtr client
)
315 switch(stuff
->data
) {
316 case X_VMwareCtrlQueryVersion
:
317 return VMwareCtrlQueryVersion(client
);
318 case X_VMwareCtrlSetRes
:
319 return VMwareCtrlSetRes(client
);
320 case X_VMwareCtrlSetTopology
:
321 return VMwareCtrlSetTopology(client
);
328 *----------------------------------------------------------------------------
330 * SVMwareCtrlQueryVersion --
332 * Wrapper for QueryVersion handler that handles input from other-endian
336 * Standard response codes.
339 * Side effects of unswapped implementation.
341 *----------------------------------------------------------------------------
345 SVMwareCtrlQueryVersion(ClientPtr client
)
349 REQUEST(xVMwareCtrlQueryVersionReq
);
350 REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq
);
352 swaps(&stuff
->length
, n
);
354 return VMwareCtrlQueryVersion(client
);
359 *----------------------------------------------------------------------------
361 * SVMwareCtrlSetRes --
363 * Wrapper for SetRes handler that handles input from other-endian
367 * Standard response codes.
370 * Side effects of unswapped implementation.
372 *----------------------------------------------------------------------------
376 SVMwareCtrlSetRes(ClientPtr client
)
380 REQUEST(xVMwareCtrlSetResReq
);
381 REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq
);
383 swaps(&stuff
->length
, n
);
384 swapl(&stuff
->screen
, n
);
388 return VMwareCtrlSetRes(client
);
393 *----------------------------------------------------------------------------
395 * SVMwareCtrlSetTopology --
397 * Wrapper for SetTopology handler that handles input from other-endian
401 * Standard response codes.
404 * Side effects of unswapped implementation.
406 *----------------------------------------------------------------------------
410 SVMwareCtrlSetTopology(ClientPtr client
)
414 REQUEST(xVMwareCtrlSetTopologyReq
);
415 REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq
);
417 swaps(&stuff
->length
, n
);
418 swapl(&stuff
->screen
, n
);
419 swapl(&stuff
->number
, n
);
420 /* Each extent is a struct of shorts. */
423 return VMwareCtrlSetTopology(client
);
428 *----------------------------------------------------------------------------
430 * SVMwareCtrlDispatch --
432 * Wrapper for dispatcher that handles input from other-endian clients.
435 * Standard response codes.
438 * Side effects of individual command handlers.
440 *----------------------------------------------------------------------------
444 SVMwareCtrlDispatch(ClientPtr client
)
448 switch(stuff
->data
) {
449 case X_VMwareCtrlQueryVersion
:
450 return SVMwareCtrlQueryVersion(client
);
451 case X_VMwareCtrlSetRes
:
452 return SVMwareCtrlSetRes(client
);
453 case X_VMwareCtrlSetTopology
:
454 return SVMwareCtrlSetTopology(client
);
461 *----------------------------------------------------------------------------
463 * VMwareCtrlResetProc --
465 * Cleanup handler called when the extension is removed.
473 *----------------------------------------------------------------------------
477 VMwareCtrlResetProc(ExtensionEntry
* extEntry
)
479 /* Currently, no cleanup is necessary. */
484 *----------------------------------------------------------------------------
486 * VMwareCtrl_ExitInit --
488 * Initialiser for the VMWARE_CTRL protocol extension.
494 * Protocol extension will be registered if successful.
496 *----------------------------------------------------------------------------
500 vmw_ctrl_ext_init(struct vmw_customizer
*vmw
)
502 ExtensionEntry
*myext
;
503 ScrnInfoPtr pScrn
= vmw
->pScrn
;
505 if (!(myext
= CheckExtension(VMWARE_CTRL_PROTOCOL_NAME
))) {
506 if (!(myext
= AddExtension(VMWARE_CTRL_PROTOCOL_NAME
, 0, 0,
510 StandardMinorOpcode
))) {
511 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
512 "Failed to add VMWARE_CTRL extension\n");
517 * For now, only support one screen as that's all the virtual
520 myext
->extPrivate
= pScrn
;
522 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
523 "Initialized VMWARE_CTRL extension version %d.%d\n",
524 VMWARE_CTRL_MAJOR_VERSION
, VMWARE_CTRL_MINOR_VERSION
);