VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp@ 33309

Last change on this file since 33309 was 33309, checked in by vboxsync, 14 years ago

crOpenGL: up saved state version

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 28.2 KB
Line 
1/* $Id: crservice.cpp 33309 2010-10-21 14:14:38Z vboxsync $ */
2
3/** @file
4 * VBox crOpenGL: Host service entry points.
5 */
6
7/*
8 * Copyright (C) 2006-2008 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#define __STDC_CONSTANT_MACROS /* needed for a definition in iprt/string.h */
20
21#ifdef RT_OS_WINDOWS
22#include <iprt/alloc.h>
23#include <iprt/string.h>
24#include <iprt/assert.h>
25#include <iprt/stream.h>
26#include <VBox/ssm.h>
27#include <VBox/hgcmsvc.h>
28#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
29#include "cr_server.h"
30#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
31#include <VBox/log.h>
32
33#include <VBox/com/com.h>
34#include <VBox/com/string.h>
35#include <VBox/com/array.h>
36#include <VBox/com/Guid.h>
37#include <VBox/com/ErrorInfo.h>
38#include <VBox/com/EventQueue.h>
39#include <VBox/com/VirtualBox.h>
40#include <VBox/com/assert.h>
41
42#else
43#include <VBox/com/VirtualBox.h>
44#include <iprt/assert.h>
45#include <VBox/ssm.h>
46#include <VBox/hgcmsvc.h>
47#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
48
49#include "cr_server.h"
50#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
51#include <VBox/log.h>
52#include <VBox/com/ErrorInfo.h>
53#endif /* RT_OS_WINDOWS */
54
55#ifdef VBOX_WITH_CRHGSMI
56#include <VBox/VBoxVideo.h>
57#endif
58
59#include <VBox/com/errorprint.h>
60
61PVBOXHGCMSVCHELPERS g_pHelpers;
62static IConsole* g_pConsole = NULL;
63static PVM g_pVM = NULL;
64#ifdef VBOX_WITH_CRHGSMI
65static uint8_t* g_pvVRamBase;
66#endif
67
68#ifndef RT_OS_WINDOWS
69#define DWORD int
70#define WINAPI
71#endif
72
73static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
74#define SHCROGL_SSM_VERSION 21
75
76static DECLCALLBACK(int) svcUnload (void *)
77{
78 int rc = VINF_SUCCESS;
79
80 Log(("SHARED_CROPENGL svcUnload\n"));
81
82 crVBoxServerTearDown();
83
84 return rc;
85}
86
87static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
88{
89 int rc = VINF_SUCCESS;
90
91 NOREF(pvClient);
92
93 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
94
95 rc = crVBoxServerAddClient(u32ClientID);
96
97 return rc;
98}
99
100static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
101{
102 int rc = VINF_SUCCESS;
103
104 NOREF(pvClient);
105
106 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
107
108 crVBoxServerRemoveClient(u32ClientID);
109
110 return rc;
111}
112
113static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
114{
115 int rc = VINF_SUCCESS;
116
117 NOREF(pvClient);
118
119 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
120
121 /* Start*/
122 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
123 AssertRCReturn(rc, rc);
124
125 /* Version */
126 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
127 AssertRCReturn(rc, rc);
128
129 /* The state itself */
130 rc = crVBoxServerSaveState(pSSM);
131 AssertRCReturn(rc, rc);
132
133 /* End */
134 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
135 AssertRCReturn(rc, rc);
136
137 return VINF_SUCCESS;
138}
139
140static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
141{
142 int rc = VINF_SUCCESS;
143
144 NOREF(pvClient);
145
146 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
147
148 char psz[2000];
149 uint32_t ui32;
150
151 /* Start of data */
152 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
153 AssertRCReturn(rc, rc);
154 if (strcmp(gszVBoxOGLSSMMagic, psz))
155 return VERR_SSM_UNEXPECTED_DATA;
156
157 /* Version */
158 rc = SSMR3GetU32(pSSM, &ui32);
159 AssertRCReturn(rc, rc);
160 if ((SHCROGL_SSM_VERSION != ui32)
161 && ((SHCROGL_SSM_VERSION!=4) || (3!=ui32)))
162 {
163 /*@todo: add some warning here*/
164 /*@todo: in many cases saved states would be made without any opengl guest app running.
165 * that means we could safely restore the default context.
166 */
167 rc = SSMR3SkipToEndOfUnit(pSSM);
168 return rc;
169 }
170
171 /* The state itself */
172 rc = crVBoxServerLoadState(pSSM, ui32);
173 AssertRCReturn(rc, rc);
174
175 /* End of data */
176 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
177 AssertRCReturn(rc, rc);
178 if (strcmp(gszVBoxOGLSSMMagic, psz))
179 return VERR_SSM_UNEXPECTED_DATA;
180
181 return VINF_SUCCESS;
182}
183
184static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
185{
186 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
187
188 /*MS's opengl32 tryes to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
189 static int shown = 0;
190
191 if (g_pVM && !shown)
192 {
193 VMSetRuntimeError(g_pVM, VMSETRTERR_FLAGS_NO_WAIT, "3DSupportIncompatibleAdditions",
194 "An attempt by the virtual machine to use hardware 3D acceleration failed. "
195 "The version of the Guest Additions installed in the virtual machine does not match the "
196 "version of VirtualBox on the host. Please install appropriate Guest Additions to fix this issue");
197 shown = 1;
198 }
199}
200
201static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
202{
203#if 0
204 ComPtr<IDisplay> pDisplay;
205 BYTE *data;
206 int i,j;
207 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
208
209 data = (BYTE*) RTMemTmpAllocZ(100*100*4);
210
211 for (i=0; i<100; i+=2)
212 {
213 for (j=0; j<100; ++j)
214 {
215 *(data+i*100*4+j*4+0) = 0xFF;
216 *(data+i*100*4+j*4+1) = 0xFF;
217 *(data+i*100*4+j*4+2) = 0xFF;
218 *(data+i*100*4+j*4+3) = 0xFF;
219 }
220 }
221
222 CHECK_ERROR(pDisplay, DrawToScreen(screenId, data, 0, 0, 100, 100));
223
224 RTMemTmpFree(data);
225#endif
226 HRESULT rc;
227 ComPtr<IDisplay> pDisplay;
228
229 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
230 CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h));
231}
232
233static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
234{
235 int rc = VINF_SUCCESS;
236
237 NOREF(pvClient);
238
239 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
240
241#ifdef DEBUG
242 uint32_t i;
243
244 for (i = 0; i < cParms; i++)
245 {
246 /** @todo parameters other than 32 bit */
247 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
248 }
249#endif
250
251 switch (u32Function)
252 {
253 case SHCRGL_GUEST_FN_WRITE:
254 {
255 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
256
257 /* Verify parameter count and types. */
258 if (cParms != SHCRGL_CPARMS_WRITE)
259 {
260 rc = VERR_INVALID_PARAMETER;
261 }
262 else
263 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
264 )
265 {
266 rc = VERR_INVALID_PARAMETER;
267 }
268 else
269 {
270 /* Fetch parameters. */
271 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
272 uint32_t cbBuffer = paParms[0].u.pointer.size;
273
274 /* Execute the function. */
275 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
276 if (!RT_SUCCESS(rc))
277 {
278 Assert(VERR_NOT_SUPPORTED==rc);
279 svcClientVersionUnsupported(0, 0);
280 }
281
282 }
283 break;
284 }
285
286 case SHCRGL_GUEST_FN_INJECT:
287 {
288 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
289
290 /* Verify parameter count and types. */
291 if (cParms != SHCRGL_CPARMS_INJECT)
292 {
293 rc = VERR_INVALID_PARAMETER;
294 }
295 else
296 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* u32ClientID */
297 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
298 )
299 {
300 rc = VERR_INVALID_PARAMETER;
301 }
302 else
303 {
304 /* Fetch parameters. */
305 uint32_t u32InjectClientID = paParms[0].u.uint32;
306 uint8_t *pBuffer = (uint8_t *)paParms[1].u.pointer.addr;
307 uint32_t cbBuffer = paParms[1].u.pointer.size;
308
309 /* Execute the function. */
310 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
311 if (!RT_SUCCESS(rc))
312 {
313 if (VERR_NOT_SUPPORTED==rc)
314 {
315 svcClientVersionUnsupported(0, 0);
316 }
317 else
318 {
319 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
320 }
321 }
322 }
323 break;
324 }
325
326 case SHCRGL_GUEST_FN_READ:
327 {
328 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
329
330 /* Verify parameter count and types. */
331 if (cParms != SHCRGL_CPARMS_READ)
332 {
333 rc = VERR_INVALID_PARAMETER;
334 }
335 else
336 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
337 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
338 )
339 {
340 rc = VERR_INVALID_PARAMETER;
341 }
342
343 /* Fetch parameters. */
344 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
345 uint32_t cbBuffer = paParms[0].u.pointer.size;
346
347 /* Execute the function. */
348 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
349
350 if (RT_SUCCESS(rc))
351 {
352 /* Update parameters.*/
353 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
354 } else if (VERR_NOT_SUPPORTED==rc)
355 {
356 svcClientVersionUnsupported(0, 0);
357 }
358
359 /* Return the required buffer size always */
360 paParms[1].u.uint32 = cbBuffer;
361
362 break;
363 }
364
365 case SHCRGL_GUEST_FN_WRITE_READ:
366 {
367 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
368
369 /* Verify parameter count and types. */
370 if (cParms != SHCRGL_CPARMS_WRITE_READ)
371 {
372 rc = VERR_INVALID_PARAMETER;
373 }
374 else
375 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
376 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
377 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
378 )
379 {
380 rc = VERR_INVALID_PARAMETER;
381 }
382 else
383 {
384 /* Fetch parameters. */
385 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
386 uint32_t cbBuffer = paParms[0].u.pointer.size;
387
388 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
389 uint32_t cbWriteback = paParms[1].u.pointer.size;
390
391 /* Execute the function. */
392 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
393 if (!RT_SUCCESS(rc))
394 {
395 Assert(VERR_NOT_SUPPORTED==rc);
396 svcClientVersionUnsupported(0, 0);
397 }
398
399 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
400
401 if (RT_SUCCESS(rc))
402 {
403 /* Update parameters.*/
404 paParms[1].u.pointer.size = cbWriteback;
405 }
406 /* Return the required buffer size always */
407 paParms[2].u.uint32 = cbWriteback;
408 }
409
410 break;
411 }
412
413 case SHCRGL_GUEST_FN_SET_VERSION:
414 {
415 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
416
417 /* Verify parameter count and types. */
418 if (cParms != SHCRGL_CPARMS_SET_VERSION)
419 {
420 rc = VERR_INVALID_PARAMETER;
421 }
422 else
423 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
424 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
425 )
426 {
427 rc = VERR_INVALID_PARAMETER;
428 }
429 else
430 {
431 /* Fetch parameters. */
432 uint32_t vMajor = paParms[0].u.uint32;
433 uint32_t vMinor = paParms[1].u.uint32;
434
435 /* Execute the function. */
436 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
437
438 if (!RT_SUCCESS(rc))
439 {
440 svcClientVersionUnsupported(vMajor, vMinor);
441 }
442 }
443
444 break;
445 }
446
447 default:
448 {
449 rc = VERR_NOT_IMPLEMENTED;
450 }
451 }
452
453
454 LogFlow(("svcCall: rc = %Rrc\n", rc));
455
456 g_pHelpers->pfnCallComplete (callHandle, rc);
457}
458
459#ifdef VBOX_WITH_CRHGSMI
460static int vboxCrHgsmiCtl(PVBOXVDMACMD_CHROMIUM_CTL pCtl)
461{
462 int rc;
463
464 switch (pCtl->enmType)
465 {
466 case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP:
467 {
468 PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
469 g_pvVRamBase = (uint8_t*)pSetup->pvRamBase;
470 rc = VINF_SUCCESS;
471 } break;
472 default:
473 Assert(0);
474 rc = VERR_INVALID_PARAMETER;
475 }
476
477 return rc;
478}
479
480#define VBOXCRHGSMI_PTR(_off, _t) ((_t*)(g_pvVRamBase + (_off)))
481static int vboxCrHgsmiCmd(PVBOXVDMACMD_CHROMIUM_CMD pCmd)
482{
483 int rc;
484 uint32_t cBuffers = pCmd->cBuffers;
485 uint32_t cParams;
486
487 if (!g_pvVRamBase)
488 {
489 Assert(0);
490 return VERR_INVALID_STATE;
491 }
492
493 if (!cBuffers)
494 {
495 Assert(0);
496 return VERR_INVALID_PARAMETER;
497 }
498
499 cParams = cBuffers-1;
500
501 CRVBOXHGSMIHDR *pHdr = VBOXCRHGSMI_PTR(pCmd->aBuffers[0].offBuffer, CRVBOXHGSMIHDR);
502 uint32_t u32Function = pHdr->u32Function;
503 uint32_t u32ClientID = pHdr->u32ClientID;
504 /* now we compile HGCM params out of HGSMI
505 * @todo: can we avoid this ? */
506 switch (u32Function)
507 {
508
509 case SHCRGL_GUEST_FN_WRITE:
510 {
511 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
512
513 CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
514
515 /* @todo: Verify */
516 if (cParams == 1)
517 {
518 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
519 /* Fetch parameters. */
520 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
521 uint32_t cbBuffer = pBuf->cbBuffer;
522
523 /* Execute the function. */
524 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
525 if (!RT_SUCCESS(rc))
526 {
527 Assert(VERR_NOT_SUPPORTED==rc);
528 svcClientVersionUnsupported(0, 0);
529 }
530 }
531 else
532 {
533 Assert(0);
534 rc = VERR_INVALID_PARAMETER;
535 }
536 break;
537 }
538
539 case SHCRGL_GUEST_FN_INJECT:
540 {
541 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
542
543 CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
544
545 /* @todo: Verify */
546 if (cParams == 1)
547 {
548 /* Fetch parameters. */
549 uint32_t u32InjectClientID = pFnCmd->u32ClientID;
550 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
551 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
552 uint32_t cbBuffer = pBuf->cbBuffer;
553
554 /* Execute the function. */
555 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
556 if (!RT_SUCCESS(rc))
557 {
558 if (VERR_NOT_SUPPORTED==rc)
559 {
560 svcClientVersionUnsupported(0, 0);
561 }
562 else
563 {
564 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
565 }
566 }
567 }
568 else
569 {
570 Assert(0);
571 rc = VERR_INVALID_PARAMETER;
572 }
573 break;
574 }
575
576 case SHCRGL_GUEST_FN_READ:
577 {
578 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
579
580 /* @todo: Verify */
581 if (cParams == 1)
582 {
583 CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
584 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
585 /* Fetch parameters. */
586 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
587 uint32_t cbBuffer = pBuf->cbBuffer;
588
589 /* Execute the function. */
590 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
591
592 if (RT_SUCCESS(rc))
593 {
594 /* Update parameters.*/
595// paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
596 } else if (VERR_NOT_SUPPORTED==rc)
597 {
598 svcClientVersionUnsupported(0, 0);
599 }
600
601 /* Return the required buffer size always */
602 pFnCmd->cbBuffer = cbBuffer;
603 }
604 else
605 {
606 Assert(0);
607 rc = VERR_INVALID_PARAMETER;
608 }
609
610 break;
611 }
612
613 case SHCRGL_GUEST_FN_WRITE_READ:
614 {
615 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
616
617 /* @todo: Verify */
618 if (cParams == 2)
619 {
620 CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
621 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
622 VBOXVDMACMD_CHROMIUM_BUFFER *pWbBuf = &pCmd->aBuffers[2];
623
624 /* Fetch parameters. */
625 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
626 uint32_t cbBuffer = pBuf->cbBuffer;
627
628 uint8_t *pWriteback = VBOXCRHGSMI_PTR(pWbBuf->offBuffer, uint8_t);
629 uint32_t cbWriteback = pWbBuf->cbBuffer;
630
631 /* Execute the function. */
632 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
633 if (!RT_SUCCESS(rc))
634 {
635 Assert(VERR_NOT_SUPPORTED==rc);
636 svcClientVersionUnsupported(0, 0);
637 }
638
639 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
640
641// if (RT_SUCCESS(rc))
642// {
643// /* Update parameters.*/
644// paParms[1].u.pointer.size = cbWriteback;
645// }
646 /* Return the required buffer size always */
647 pFnCmd->cbWriteback = cbWriteback;
648 }
649 else
650 {
651 Assert(0);
652 rc = VERR_INVALID_PARAMETER;
653 }
654
655 break;
656 }
657
658 case SHCRGL_GUEST_FN_SET_VERSION:
659 {
660 Assert(0);
661 rc = VERR_NOT_IMPLEMENTED;
662 break;
663 }
664
665 default:
666 {
667 Assert(0);
668 rc = VERR_NOT_IMPLEMENTED;
669 }
670
671 }
672
673 pHdr->result = rc;
674
675 return VINF_SUCCESS;
676}
677#endif
678
679/*
680 * We differentiate between a function handler for the guest and one for the host.
681 */
682static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
683{
684 int rc = VINF_SUCCESS;
685
686 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
687
688#ifdef DEBUG
689 uint32_t i;
690
691 for (i = 0; i < cParms; i++)
692 {
693 /** @todo parameters other than 32 bit */
694 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
695 }
696#endif
697
698 switch (u32Function)
699 {
700#ifdef VBOX_WITH_CRHGSMI
701 case SHCRGL_HOST_FN_CRHGSMI_CMD:
702 {
703 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
704 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
705 rc = vboxCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr);
706 else
707 rc = VERR_INVALID_PARAMETER;
708 } break;
709 case SHCRGL_HOST_FN_CRHGSMI_CTL:
710 {
711 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
712 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
713 rc = vboxCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr);
714 else
715 rc = VERR_INVALID_PARAMETER;
716 } break;
717#endif
718 case SHCRGL_HOST_FN_SET_CONSOLE:
719 {
720 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
721
722 /* Verify parameter count and types. */
723 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
724 {
725 rc = VERR_INVALID_PARAMETER;
726 }
727 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
728 {
729 rc = VERR_INVALID_PARAMETER;
730 }
731 else
732 {
733 /* Fetch parameters. */
734 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
735 uint32_t cbData = paParms[0].u.pointer.size;
736
737 /* Verify parameters values. */
738 if (cbData != sizeof (IConsole*))
739 {
740 rc = VERR_INVALID_PARAMETER;
741 }
742 else if (!pConsole)
743 {
744 rc = VERR_INVALID_PARAMETER;
745 }
746 else /* Execute the function. */
747 {
748 ComPtr<IMachine> pMachine;
749 ComPtr<IDisplay> pDisplay;
750 ComPtr<IFramebuffer> pFramebuffer;
751 LONG xo, yo;
752 LONG64 winId = 0;
753 ULONG monitorCount, i, w, h;
754
755 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
756 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
757 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
758
759 rc = crVBoxServerSetScreenCount(monitorCount);
760 AssertRCReturn(rc, rc);
761
762 for (i=0; i<monitorCount; ++i)
763 {
764 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
765
766 if (!pDisplay)
767 {
768 rc = crVBoxServerUnmapScreen(i);
769 AssertRCReturn(rc, rc);
770 }
771 else
772 {
773 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
774 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
775 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
776
777 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
778 AssertRCReturn(rc, rc);
779 }
780 }
781
782 g_pConsole = pConsole;
783 rc = VINF_SUCCESS;
784 }
785 }
786 break;
787 }
788 case SHCRGL_HOST_FN_SET_VM:
789 {
790 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
791
792 /* Verify parameter count and types. */
793 if (cParms != SHCRGL_CPARMS_SET_VM)
794 {
795 rc = VERR_INVALID_PARAMETER;
796 }
797 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
798 {
799 rc = VERR_INVALID_PARAMETER;
800 }
801 else
802 {
803 /* Fetch parameters. */
804 PVM pVM = (PVM)paParms[0].u.pointer.addr;
805 uint32_t cbData = paParms[0].u.pointer.size;
806
807 /* Verify parameters values. */
808 if (cbData != sizeof (PVM))
809 {
810 rc = VERR_INVALID_PARAMETER;
811 }
812 else
813 {
814 /* Execute the function. */
815 g_pVM = pVM;
816 rc = VINF_SUCCESS;
817 }
818 }
819 break;
820 }
821 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
822 {
823 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
824
825 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
826 {
827 rc = VERR_INVALID_PARAMETER;
828 break;
829 }
830
831 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
832 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
833 )
834 {
835 rc = VERR_INVALID_PARAMETER;
836 break;
837 }
838
839 Assert(sizeof(RTRECT)==4*sizeof(GLint));
840
841 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
842 break;
843 }
844 case SHCRGL_HOST_FN_SCREEN_CHANGED:
845 {
846 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
847
848 /* Verify parameter count and types. */
849 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
850 {
851 rc = VERR_INVALID_PARAMETER;
852 }
853 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
854 {
855 rc = VERR_INVALID_PARAMETER;
856 }
857 else
858 {
859 /* Fetch parameters. */
860 uint32_t screenId = paParms[0].u.uint32;
861
862 /* Execute the function. */
863 ComPtr<IDisplay> pDisplay;
864 ComPtr<IFramebuffer> pFramebuffer;
865 LONG xo, yo;
866 LONG64 winId = 0;
867 ULONG w, h;
868
869 Assert(g_pConsole);
870 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
871 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
872
873 if (!pFramebuffer)
874 {
875 rc = crVBoxServerUnmapScreen(screenId);
876 AssertRCReturn(rc, rc);
877 }
878 else
879 {
880 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
881 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
882 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
883
884 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
885 AssertRCReturn(rc, rc);
886 }
887
888 rc = VINF_SUCCESS;
889 }
890 break;
891 }
892 default:
893 rc = VERR_NOT_IMPLEMENTED;
894 break;
895 }
896
897 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
898 return rc;
899}
900
901extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
902{
903 int rc = VINF_SUCCESS;
904
905 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
906
907 if (!ptable)
908 {
909 rc = VERR_INVALID_PARAMETER;
910 }
911 else
912 {
913 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
914
915 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
916 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
917 {
918 rc = VERR_INVALID_PARAMETER;
919 }
920 else
921 {
922 g_pHelpers = ptable->pHelpers;
923
924 ptable->cbClient = sizeof (void*);
925
926 ptable->pfnUnload = svcUnload;
927 ptable->pfnConnect = svcConnect;
928 ptable->pfnDisconnect = svcDisconnect;
929 ptable->pfnCall = svcCall;
930 ptable->pfnHostCall = svcHostCall;
931 ptable->pfnSaveState = svcSaveState;
932 ptable->pfnLoadState = svcLoadState;
933 ptable->pvService = NULL;
934
935 if (!crVBoxServerInit())
936 return VERR_NOT_SUPPORTED;
937
938 crVBoxServerSetPresentFBOCB(svcPresentFBO);
939 }
940 }
941
942 return rc;
943}
944
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette