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
= xcalloc(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
);