VirtualBox

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

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

crOpenGL: add option to force fbo usage for 3d over rdp

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 41.8 KB
Line 
1/* $Id: crservice.cpp 35969 2011-02-15 09:46:49Z 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/vmm/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/vmm/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#include <iprt/thread.h>
61#include <iprt/critsect.h>
62#include <iprt/semaphore.h>
63#include <iprt/asm.h>
64
65#include "cr_mem.h"
66
67PVBOXHGCMSVCHELPERS g_pHelpers;
68static IConsole* g_pConsole = NULL;
69static PVM g_pVM = NULL;
70#ifdef VBOX_WITH_CRHGSMI
71static uint8_t* g_pvVRamBase;
72#endif
73
74#ifndef RT_OS_WINDOWS
75# define DWORD int
76# define WINAPI
77#endif
78
79static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
80
81/* Used to process guest calls exceeding maximum allowed HGCM call size in a sequence of smaller calls */
82typedef struct _CRVBOXSVCBUFFER_t {
83 uint32_t uiId;
84 uint32_t uiSize;
85 void* pData;
86 _CRVBOXSVCBUFFER_t *pNext, *pPrev;
87} CRVBOXSVCBUFFER_t;
88
89static CRVBOXSVCBUFFER_t *g_pCRVBoxSVCBuffers = NULL;
90static uint32_t g_CRVBoxSVCBufferID = 0;
91
92/* svcPresentFBO related data */
93typedef struct _CRVBOXSVCPRESENTFBOCMD_t {
94 void *pData;
95 int32_t screenId, x, y, w, h;
96 _CRVBOXSVCPRESENTFBOCMD_t *pNext;
97} CRVBOXSVCPRESENTFBOCMD_t, *PCRVBOXSVCPRESENTFBOCMD_t;
98
99typedef struct _CRVBOXSVCPRESENTFBO_t {
100 PCRVBOXSVCPRESENTFBOCMD_t pQueueHead, pQueueTail; /* Head/Tail of FIFO cmds queue */
101 RTCRITSECT hQueueLock; /* Queue lock */
102 RTTHREAD hWorkerThread; /* Worker thread */
103 bool volatile bShutdownWorker; /* Shutdown flag */
104 RTSEMEVENT hEventProcess; /* Signalled when worker thread should process data or exit */
105} CRVBOXSVCPRESENTFBO_t;
106
107static CRVBOXSVCPRESENTFBO_t g_SvcPresentFBO;
108
109/* Schedule a call to a separate worker thread to avoid deadlock on EMT thread when the screen configuration changes
110 and we're processing crServerPresentFBO caused by guest application command.
111 To avoid unnecessary memcpy, worker thread frees the data passed.
112*/
113static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
114{
115 PCRVBOXSVCPRESENTFBOCMD_t pCmd;
116
117 pCmd = (PCRVBOXSVCPRESENTFBOCMD_t) RTMemAlloc(sizeof(CRVBOXSVCPRESENTFBOCMD_t));
118 if (!pCmd)
119 {
120 LogRel(("SHARED_CROPENGL svcPresentFBO: not enough memory (%d)\n", sizeof(CRVBOXSVCPRESENTFBOCMD_t)));
121 return;
122 }
123 pCmd->pData = data;
124 pCmd->screenId = screenId;
125 pCmd->x = x;
126 pCmd->y = y;
127 pCmd->w = w;
128 pCmd->h = h;
129 pCmd->pNext = NULL;
130
131 RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
132
133 if (g_SvcPresentFBO.pQueueTail)
134 {
135 g_SvcPresentFBO.pQueueTail->pNext = pCmd;
136 }
137 else
138 {
139 Assert(!g_SvcPresentFBO.pQueueHead);
140 g_SvcPresentFBO.pQueueHead = pCmd;
141 }
142 g_SvcPresentFBO.pQueueTail = pCmd;
143
144 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
145
146 RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
147}
148
149static DECLCALLBACK(int) svcPresentFBOWorkerThreadProc(RTTHREAD ThreadSelf, void *pvUser)
150{
151 int rc = VINF_SUCCESS;
152 PCRVBOXSVCPRESENTFBOCMD_t pCmd;
153
154 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc started\n"));
155
156 for (;;)
157 {
158 rc = RTSemEventWait(g_SvcPresentFBO.hEventProcess, RT_INDEFINITE_WAIT);
159 AssertRCReturn(rc, rc);
160
161 if (g_SvcPresentFBO.bShutdownWorker)
162 {
163 break;
164 }
165
166 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
167 AssertRCReturn(rc, rc);
168
169 pCmd = g_SvcPresentFBO.pQueueHead;
170 while (pCmd)
171 {
172 ComPtr<IDisplay> pDisplay;
173
174 /*remove from queue*/
175 g_SvcPresentFBO.pQueueHead = pCmd->pNext;
176 if (!g_SvcPresentFBO.pQueueHead)
177 {
178 g_SvcPresentFBO.pQueueTail = NULL;
179 }
180
181 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
182
183 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
184
185 CHECK_ERROR_RET(pDisplay, DrawToScreen(pCmd->screenId, (BYTE*)pCmd->pData, pCmd->x, pCmd->y, pCmd->w, pCmd->h), rc);
186
187 crFree(pCmd->pData);
188 RTMemFree(pCmd);
189
190 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
191 AssertRCReturn(rc, rc);
192 pCmd = g_SvcPresentFBO.pQueueHead;
193 }
194
195 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
196 }
197
198 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc finished\n"));
199
200 return rc;
201}
202
203static int svcPresentFBOInit(void)
204{
205 int rc = VINF_SUCCESS;
206
207 g_SvcPresentFBO.pQueueHead = NULL;
208 g_SvcPresentFBO.pQueueTail = NULL;
209 g_SvcPresentFBO.bShutdownWorker = false;
210
211 rc = RTCritSectInit(&g_SvcPresentFBO.hQueueLock);
212 AssertRCReturn(rc, rc);
213
214 rc = RTSemEventCreate(&g_SvcPresentFBO.hEventProcess);
215 AssertRCReturn(rc, rc);
216
217 rc = RTThreadCreate(&g_SvcPresentFBO.hWorkerThread, svcPresentFBOWorkerThreadProc, NULL, 0,
218 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "OpenGLWorker");
219 AssertRCReturn(rc, rc);
220
221 crVBoxServerSetPresentFBOCB(svcPresentFBO);
222
223 return rc;
224}
225
226static int svcPresentFBOTearDown(void)
227{
228 int rc = VINF_SUCCESS;
229 PCRVBOXSVCPRESENTFBOCMD_t pQueue, pTmp;
230
231 ASMAtomicWriteBool(&g_SvcPresentFBO.bShutdownWorker, true);
232 RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
233 rc = RTThreadWait(g_SvcPresentFBO.hWorkerThread, 5000, NULL);
234 AssertRCReturn(rc, rc);
235
236 RTCritSectDelete(&g_SvcPresentFBO.hQueueLock);
237 RTSemEventDestroy(g_SvcPresentFBO.hEventProcess);
238
239 pQueue = g_SvcPresentFBO.pQueueHead;
240 while (pQueue)
241 {
242 pTmp = pQueue->pNext;
243 crFree(pQueue->pData);
244 RTMemFree(pQueue);
245 pQueue = pTmp;
246 }
247 g_SvcPresentFBO.pQueueHead = NULL;
248 g_SvcPresentFBO.pQueueTail = NULL;
249
250 return rc;
251}
252
253static DECLCALLBACK(int) svcUnload (void *)
254{
255 int rc = VINF_SUCCESS;
256
257 Log(("SHARED_CROPENGL svcUnload\n"));
258
259 crVBoxServerTearDown();
260
261 svcPresentFBOTearDown();
262
263 return rc;
264}
265
266static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
267{
268 int rc = VINF_SUCCESS;
269
270 NOREF(pvClient);
271
272 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
273
274 rc = crVBoxServerAddClient(u32ClientID);
275
276 return rc;
277}
278
279static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
280{
281 int rc = VINF_SUCCESS;
282
283 NOREF(pvClient);
284
285 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
286
287 crVBoxServerRemoveClient(u32ClientID);
288
289 return rc;
290}
291
292static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
293{
294 int rc = VINF_SUCCESS;
295
296 NOREF(pvClient);
297
298 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
299
300 /* Start*/
301 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
302 AssertRCReturn(rc, rc);
303
304 /* Version */
305 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
306 AssertRCReturn(rc, rc);
307
308 /* The state itself */
309 rc = crVBoxServerSaveState(pSSM);
310 AssertRCReturn(rc, rc);
311
312 /* Save svc buffers info */
313 {
314 CRVBOXSVCBUFFER_t *pBuffer = g_pCRVBoxSVCBuffers;
315
316 rc = SSMR3PutU32(pSSM, g_CRVBoxSVCBufferID);
317 AssertRCReturn(rc, rc);
318
319 while (pBuffer)
320 {
321 rc = SSMR3PutU32(pSSM, pBuffer->uiId);
322 AssertRCReturn(rc, rc);
323
324 rc = SSMR3PutU32(pSSM, pBuffer->uiSize);
325 AssertRCReturn(rc, rc);
326
327 rc = SSMR3PutMem(pSSM, pBuffer->pData, pBuffer->uiSize);
328 AssertRCReturn(rc, rc);
329
330 pBuffer = pBuffer->pNext;
331 }
332
333 rc = SSMR3PutU32(pSSM, 0);
334 AssertRCReturn(rc, rc);
335 }
336
337 /* End */
338 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
339 AssertRCReturn(rc, rc);
340
341 return VINF_SUCCESS;
342}
343
344static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
345{
346 int rc = VINF_SUCCESS;
347
348 NOREF(pvClient);
349
350 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
351
352 char psz[2000];
353 uint32_t ui32;
354
355 /* Start of data */
356 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
357 AssertRCReturn(rc, rc);
358 if (strcmp(gszVBoxOGLSSMMagic, psz))
359 return VERR_SSM_UNEXPECTED_DATA;
360
361 /* Version */
362 rc = SSMR3GetU32(pSSM, &ui32);
363 AssertRCReturn(rc, rc);
364
365 /* The state itself */
366#if SHCROGL_SSM_VERSION==24
367 if (ui32==23)
368 {
369 rc = crVBoxServerLoadState(pSSM, 24);
370 }
371 else
372#endif
373 rc = crVBoxServerLoadState(pSSM, ui32);
374
375 if (rc==VERR_SSM_DATA_UNIT_FORMAT_CHANGED && ui32!=SHCROGL_SSM_VERSION)
376 {
377 LogRel(("SHARED_CROPENGL svcLoadState: unsupported save state version %d\n", ui32));
378
379 /*@todo ugly hack, as we don't know size of stored opengl data try to read untill end of opengl data marker*/
380 /*VboxSharedCrOpenGL isn't last hgcm service now, so can't use SSMR3SkipToEndOfUnit*/
381 {
382 const char *pMatch = &gszVBoxOGLSSMMagic[0];
383 char current;
384
385 while (*pMatch)
386 {
387 rc = SSMR3GetS8(pSSM, (int8_t*)&current);
388 AssertRCReturn(rc, rc);
389
390 if (current==*pMatch)
391 {
392 pMatch++;
393 }
394 else
395 {
396 pMatch = &gszVBoxOGLSSMMagic[0];
397 }
398 }
399 }
400
401 return VINF_SUCCESS;
402 }
403 AssertRCReturn(rc, rc);
404
405 /* Load svc buffers info */
406 if (ui32>=24)
407 {
408 uint32_t uiId;
409
410 rc = SSMR3GetU32(pSSM, &g_CRVBoxSVCBufferID);
411 AssertRCReturn(rc, rc);
412
413 rc = SSMR3GetU32(pSSM, &uiId);
414 AssertRCReturn(rc, rc);
415
416 while (uiId)
417 {
418 CRVBOXSVCBUFFER_t *pBuffer = (CRVBOXSVCBUFFER_t *) RTMemAlloc(sizeof(CRVBOXSVCBUFFER_t));
419 if (!pBuffer)
420 {
421 return VERR_NO_MEMORY;
422 }
423 pBuffer->uiId = uiId;
424
425 rc = SSMR3GetU32(pSSM, &pBuffer->uiSize);
426 AssertRCReturn(rc, rc);
427
428 pBuffer->pData = RTMemAlloc(pBuffer->uiSize);
429 if (!pBuffer->pData)
430 {
431 RTMemFree(pBuffer);
432 return VERR_NO_MEMORY;
433 }
434
435 rc = SSMR3GetMem(pSSM, pBuffer->pData, pBuffer->uiSize);
436 AssertRCReturn(rc, rc);
437
438 pBuffer->pNext = g_pCRVBoxSVCBuffers;
439 pBuffer->pPrev = NULL;
440 if (g_pCRVBoxSVCBuffers)
441 {
442 g_pCRVBoxSVCBuffers->pPrev = pBuffer;
443 }
444 g_pCRVBoxSVCBuffers = pBuffer;
445
446 rc = SSMR3GetU32(pSSM, &uiId);
447 AssertRCReturn(rc, rc);
448 }
449 }
450
451 /* End of data */
452 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
453 AssertRCReturn(rc, rc);
454 if (strcmp(gszVBoxOGLSSMMagic, psz))
455 return VERR_SSM_UNEXPECTED_DATA;
456
457 return VINF_SUCCESS;
458}
459
460static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
461{
462 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
463
464 /*MS's opengl32 tries to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
465 static int shown = 0;
466
467 if (g_pVM && !shown)
468 {
469 VMSetRuntimeError(g_pVM, VMSETRTERR_FLAGS_NO_WAIT, "3DSupportIncompatibleAdditions",
470 "An attempt by the virtual machine to use hardware 3D acceleration failed. "
471 "The version of the Guest Additions installed in the virtual machine does not match the "
472 "version of VirtualBox on the host. Please install appropriate Guest Additions to fix this issue");
473 shown = 1;
474 }
475}
476
477static CRVBOXSVCBUFFER_t* svcGetBuffer(uint32_t iBuffer, uint32_t cbBufferSize)
478{
479 CRVBOXSVCBUFFER_t* pBuffer;
480
481 if (iBuffer)
482 {
483 pBuffer = g_pCRVBoxSVCBuffers;
484 while (pBuffer)
485 {
486 if (pBuffer->uiId == iBuffer)
487 {
488 return pBuffer;
489 }
490 pBuffer = pBuffer->pNext;
491 }
492 return NULL;
493 }
494 else /*allocate new buffer*/
495 {
496 pBuffer = (CRVBOXSVCBUFFER_t*) RTMemAlloc(sizeof(CRVBOXSVCBUFFER_t));
497 if (pBuffer)
498 {
499 pBuffer->pData = RTMemAlloc(cbBufferSize);
500 if (!pBuffer->pData)
501 {
502 LogRel(("SHARED_CROPENGL svcGetBuffer: not enough memory (%d)\n", cbBufferSize));
503 RTMemFree(pBuffer);
504 return NULL;
505 }
506 pBuffer->uiId = ++g_CRVBoxSVCBufferID;
507 if (!pBuffer->uiId)
508 {
509 pBuffer->uiId = ++g_CRVBoxSVCBufferID;
510 }
511 Assert(pBuffer->uiId);
512 pBuffer->uiSize = cbBufferSize;
513 pBuffer->pPrev = NULL;
514 pBuffer->pNext = g_pCRVBoxSVCBuffers;
515 if (g_pCRVBoxSVCBuffers)
516 {
517 g_pCRVBoxSVCBuffers->pPrev = pBuffer;
518 }
519 g_pCRVBoxSVCBuffers = pBuffer;
520 }
521 else
522 {
523 LogRel(("SHARED_CROPENGL svcGetBuffer: not enough memory (%d)\n", sizeof(CRVBOXSVCBUFFER_t)));
524 }
525 return pBuffer;
526 }
527}
528
529static void svcFreeBuffer(CRVBOXSVCBUFFER_t* pBuffer)
530{
531 Assert(pBuffer);
532
533 if (pBuffer->pPrev)
534 {
535 pBuffer->pPrev->pNext = pBuffer->pNext;
536 }
537 else
538 {
539 Assert(pBuffer==g_pCRVBoxSVCBuffers);
540 g_pCRVBoxSVCBuffers = pBuffer->pNext;
541 }
542
543 if (pBuffer->pNext)
544 {
545 pBuffer->pNext->pPrev = pBuffer->pPrev;
546 }
547
548 RTMemFree(pBuffer->pData);
549 RTMemFree(pBuffer);
550}
551
552static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
553{
554 int rc = VINF_SUCCESS;
555
556 NOREF(pvClient);
557
558 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
559
560#ifdef DEBUG
561 uint32_t i;
562
563 for (i = 0; i < cParms; i++)
564 {
565 /** @todo parameters other than 32 bit */
566 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
567 }
568#endif
569
570 switch (u32Function)
571 {
572 case SHCRGL_GUEST_FN_WRITE:
573 {
574 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
575
576 /* Verify parameter count and types. */
577 if (cParms != SHCRGL_CPARMS_WRITE)
578 {
579 rc = VERR_INVALID_PARAMETER;
580 }
581 else
582 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
583 )
584 {
585 rc = VERR_INVALID_PARAMETER;
586 }
587 else
588 {
589 /* Fetch parameters. */
590 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
591 uint32_t cbBuffer = paParms[0].u.pointer.size;
592
593 /* Execute the function. */
594 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
595 if (!RT_SUCCESS(rc))
596 {
597 Assert(VERR_NOT_SUPPORTED==rc);
598 svcClientVersionUnsupported(0, 0);
599 }
600
601 }
602 break;
603 }
604
605 case SHCRGL_GUEST_FN_INJECT:
606 {
607 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
608
609 /* Verify parameter count and types. */
610 if (cParms != SHCRGL_CPARMS_INJECT)
611 {
612 rc = VERR_INVALID_PARAMETER;
613 }
614 else
615 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* u32ClientID */
616 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
617 )
618 {
619 rc = VERR_INVALID_PARAMETER;
620 }
621 else
622 {
623 /* Fetch parameters. */
624 uint32_t u32InjectClientID = paParms[0].u.uint32;
625 uint8_t *pBuffer = (uint8_t *)paParms[1].u.pointer.addr;
626 uint32_t cbBuffer = paParms[1].u.pointer.size;
627
628 /* Execute the function. */
629 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
630 if (!RT_SUCCESS(rc))
631 {
632 if (VERR_NOT_SUPPORTED==rc)
633 {
634 svcClientVersionUnsupported(0, 0);
635 }
636 else
637 {
638 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
639 }
640 }
641 }
642 break;
643 }
644
645 case SHCRGL_GUEST_FN_READ:
646 {
647 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
648
649 /* Verify parameter count and types. */
650 if (cParms != SHCRGL_CPARMS_READ)
651 {
652 rc = VERR_INVALID_PARAMETER;
653 }
654 else
655 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
656 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
657 )
658 {
659 rc = VERR_INVALID_PARAMETER;
660 }
661
662 /* Fetch parameters. */
663 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
664 uint32_t cbBuffer = paParms[0].u.pointer.size;
665
666 /* Execute the function. */
667 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
668
669 if (RT_SUCCESS(rc))
670 {
671 /* Update parameters.*/
672 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
673 } else if (VERR_NOT_SUPPORTED==rc)
674 {
675 svcClientVersionUnsupported(0, 0);
676 }
677
678 /* Return the required buffer size always */
679 paParms[1].u.uint32 = cbBuffer;
680
681 break;
682 }
683
684 case SHCRGL_GUEST_FN_WRITE_READ:
685 {
686 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
687
688 /* Verify parameter count and types. */
689 if (cParms != SHCRGL_CPARMS_WRITE_READ)
690 {
691 rc = VERR_INVALID_PARAMETER;
692 }
693 else
694 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
695 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
696 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
697 )
698 {
699 rc = VERR_INVALID_PARAMETER;
700 }
701 else
702 {
703 /* Fetch parameters. */
704 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
705 uint32_t cbBuffer = paParms[0].u.pointer.size;
706
707 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
708 uint32_t cbWriteback = paParms[1].u.pointer.size;
709
710 /* Execute the function. */
711 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
712 if (!RT_SUCCESS(rc))
713 {
714 Assert(VERR_NOT_SUPPORTED==rc);
715 svcClientVersionUnsupported(0, 0);
716 }
717
718 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
719
720 if (RT_SUCCESS(rc))
721 {
722 /* Update parameters.*/
723 paParms[1].u.pointer.size = cbWriteback;
724 }
725 /* Return the required buffer size always */
726 paParms[2].u.uint32 = cbWriteback;
727 }
728
729 break;
730 }
731
732 case SHCRGL_GUEST_FN_SET_VERSION:
733 {
734 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
735
736 /* Verify parameter count and types. */
737 if (cParms != SHCRGL_CPARMS_SET_VERSION)
738 {
739 rc = VERR_INVALID_PARAMETER;
740 }
741 else
742 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
743 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
744 )
745 {
746 rc = VERR_INVALID_PARAMETER;
747 }
748 else
749 {
750 /* Fetch parameters. */
751 uint32_t vMajor = paParms[0].u.uint32;
752 uint32_t vMinor = paParms[1].u.uint32;
753
754 /* Execute the function. */
755 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
756
757 if (!RT_SUCCESS(rc))
758 {
759 svcClientVersionUnsupported(vMajor, vMinor);
760 }
761 }
762
763 break;
764 }
765
766 case SHCRGL_GUEST_FN_SET_PID:
767 {
768 Log(("svcCall: SHCRGL_GUEST_FN_SET_PID\n"));
769
770 /* Verify parameter count and types. */
771 if (cParms != SHCRGL_CPARMS_SET_PID)
772 {
773 rc = VERR_INVALID_PARAMETER;
774 }
775 else
776 if (paParms[0].type != VBOX_HGCM_SVC_PARM_64BIT)
777 {
778 rc = VERR_INVALID_PARAMETER;
779 }
780 else
781 {
782 /* Fetch parameters. */
783 uint64_t pid = paParms[0].u.uint64;
784
785 /* Execute the function. */
786 rc = crVBoxServerClientSetPID(u32ClientID, pid);
787 }
788
789 break;
790 }
791
792 case SHCRGL_GUEST_FN_WRITE_BUFFER:
793 {
794 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_BUFFER\n"));
795 /* Verify parameter count and types. */
796 if (cParms != SHCRGL_CPARMS_WRITE_BUFFER)
797 {
798 rc = VERR_INVALID_PARAMETER;
799 }
800 else
801 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /*iBufferID*/
802 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /*cbBufferSize*/
803 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /*ui32Offset*/
804 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /*pBuffer*/
805 )
806 {
807 rc = VERR_INVALID_PARAMETER;
808 }
809 else
810 {
811 /* Fetch parameters. */
812 uint32_t iBuffer = paParms[0].u.uint32;
813 uint32_t cbBufferSize = paParms[1].u.uint32;
814 uint32_t ui32Offset = paParms[2].u.uint32;
815 uint8_t *pBuffer = (uint8_t *)paParms[3].u.pointer.addr;
816 uint32_t cbBuffer = paParms[3].u.pointer.size;
817
818 /* Execute the function. */
819 CRVBOXSVCBUFFER_t *pSvcBuffer = svcGetBuffer(iBuffer, cbBufferSize);
820 if (!pSvcBuffer || ui32Offset+cbBuffer>cbBufferSize)
821 {
822 rc = VERR_INVALID_PARAMETER;
823 }
824 else
825 {
826 memcpy((void*)((uintptr_t)pSvcBuffer->pData+ui32Offset), pBuffer, cbBuffer);
827
828 /* Return the buffer id */
829 paParms[0].u.uint32 = pSvcBuffer->uiId;
830 }
831 }
832
833 break;
834 }
835
836 case SHCRGL_GUEST_FN_WRITE_READ_BUFFERED:
837 {
838 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ_BUFFERED\n"));
839
840 /* Verify parameter count and types. */
841 if (cParms != SHCRGL_CPARMS_WRITE_READ_BUFFERED)
842 {
843 rc = VERR_INVALID_PARAMETER;
844 }
845 else
846 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* iBufferID */
847 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
848 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
849 || !paParms[0].u.uint32 /*iBufferID can't be 0 here*/
850 )
851 {
852 rc = VERR_INVALID_PARAMETER;
853 }
854 else
855 {
856 /* Fetch parameters. */
857 uint32_t iBuffer = paParms[0].u.uint32;
858 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
859 uint32_t cbWriteback = paParms[1].u.pointer.size;
860
861 CRVBOXSVCBUFFER_t *pSvcBuffer = svcGetBuffer(iBuffer, 0);
862 if (!pSvcBuffer)
863 {
864 LogRel(("SHARED_CROPENGL svcCall(WRITE_READ_BUFFERED): invalid buffer (%d)\n", iBuffer));
865 rc = VERR_INVALID_PARAMETER;
866 break;
867 }
868
869 uint8_t *pBuffer = (uint8_t *)pSvcBuffer->pData;
870 uint32_t cbBuffer = pSvcBuffer->uiSize;
871
872 /* Execute the function. */
873 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
874 if (!RT_SUCCESS(rc))
875 {
876 Assert(VERR_NOT_SUPPORTED==rc);
877 svcClientVersionUnsupported(0, 0);
878 }
879
880 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
881
882 if (RT_SUCCESS(rc))
883 {
884 /* Update parameters.*/
885 paParms[1].u.pointer.size = cbWriteback;
886 }
887 /* Return the required buffer size always */
888 paParms[2].u.uint32 = cbWriteback;
889
890 svcFreeBuffer(pSvcBuffer);
891 }
892
893 break;
894 }
895
896 default:
897 {
898 rc = VERR_NOT_IMPLEMENTED;
899 }
900 }
901
902
903 LogFlow(("svcCall: rc = %Rrc\n", rc));
904
905 g_pHelpers->pfnCallComplete (callHandle, rc);
906}
907
908#ifdef VBOX_WITH_CRHGSMI
909static int vboxCrHgsmiCtl(PVBOXVDMACMD_CHROMIUM_CTL pCtl)
910{
911 int rc;
912
913 switch (pCtl->enmType)
914 {
915 case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP:
916 {
917 PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
918 g_pvVRamBase = (uint8_t*)pSetup->pvRamBase;
919 rc = VINF_SUCCESS;
920 } break;
921 case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN:
922 case VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END:
923 rc = VINF_SUCCESS;
924 break;
925 default:
926 Assert(0);
927 rc = VERR_INVALID_PARAMETER;
928 }
929
930 return rc;
931}
932
933#define VBOXCRHGSMI_PTR(_off, _t) ((_t*)(g_pvVRamBase + (_off)))
934static int vboxCrHgsmiCmd(PVBOXVDMACMD_CHROMIUM_CMD pCmd)
935{
936 int rc;
937 uint32_t cBuffers = pCmd->cBuffers;
938 uint32_t cParams;
939
940 if (!g_pvVRamBase)
941 {
942 Assert(0);
943 return VERR_INVALID_STATE;
944 }
945
946 if (!cBuffers)
947 {
948 Assert(0);
949 return VERR_INVALID_PARAMETER;
950 }
951
952 cParams = cBuffers-1;
953
954 CRVBOXHGSMIHDR *pHdr = VBOXCRHGSMI_PTR(pCmd->aBuffers[0].offBuffer, CRVBOXHGSMIHDR);
955 uint32_t u32Function = pHdr->u32Function;
956 uint32_t u32ClientID = pHdr->u32ClientID;
957 /* now we compile HGCM params out of HGSMI
958 * @todo: can we avoid this ? */
959 switch (u32Function)
960 {
961
962 case SHCRGL_GUEST_FN_WRITE:
963 {
964 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
965
966 CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
967
968 /* @todo: Verify */
969 if (cParams == 1)
970 {
971 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
972 /* Fetch parameters. */
973 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
974 uint32_t cbBuffer = pBuf->cbBuffer;
975
976 /* Execute the function. */
977 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
978 if (!RT_SUCCESS(rc))
979 {
980 Assert(VERR_NOT_SUPPORTED==rc);
981 svcClientVersionUnsupported(0, 0);
982 }
983 }
984 else
985 {
986 Assert(0);
987 rc = VERR_INVALID_PARAMETER;
988 }
989 break;
990 }
991
992 case SHCRGL_GUEST_FN_INJECT:
993 {
994 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
995
996 CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
997
998 /* @todo: Verify */
999 if (cParams == 1)
1000 {
1001 /* Fetch parameters. */
1002 uint32_t u32InjectClientID = pFnCmd->u32ClientID;
1003 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
1004 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
1005 uint32_t cbBuffer = pBuf->cbBuffer;
1006
1007 /* Execute the function. */
1008 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
1009 if (!RT_SUCCESS(rc))
1010 {
1011 if (VERR_NOT_SUPPORTED==rc)
1012 {
1013 svcClientVersionUnsupported(0, 0);
1014 }
1015 else
1016 {
1017 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
1018 }
1019 }
1020 }
1021 else
1022 {
1023 Assert(0);
1024 rc = VERR_INVALID_PARAMETER;
1025 }
1026 break;
1027 }
1028
1029 case SHCRGL_GUEST_FN_READ:
1030 {
1031 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
1032
1033 /* @todo: Verify */
1034 if (cParams == 1)
1035 {
1036 CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
1037 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
1038 /* Fetch parameters. */
1039 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
1040 uint32_t cbBuffer = pBuf->cbBuffer;
1041
1042 /* Execute the function. */
1043 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
1044
1045 if (RT_SUCCESS(rc))
1046 {
1047 /* Update parameters.*/
1048// paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
1049 } else if (VERR_NOT_SUPPORTED==rc)
1050 {
1051 svcClientVersionUnsupported(0, 0);
1052 }
1053
1054 /* Return the required buffer size always */
1055 pFnCmd->cbBuffer = cbBuffer;
1056 }
1057 else
1058 {
1059 Assert(0);
1060 rc = VERR_INVALID_PARAMETER;
1061 }
1062
1063 break;
1064 }
1065
1066 case SHCRGL_GUEST_FN_WRITE_READ:
1067 {
1068 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
1069
1070 /* @todo: Verify */
1071 if (cParams == 2)
1072 {
1073 CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
1074 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
1075 VBOXVDMACMD_CHROMIUM_BUFFER *pWbBuf = &pCmd->aBuffers[2];
1076
1077 /* Fetch parameters. */
1078 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
1079 uint32_t cbBuffer = pBuf->cbBuffer;
1080
1081 uint8_t *pWriteback = VBOXCRHGSMI_PTR(pWbBuf->offBuffer, uint8_t);
1082 uint32_t cbWriteback = pWbBuf->cbBuffer;
1083
1084 /* Execute the function. */
1085 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
1086 if (!RT_SUCCESS(rc))
1087 {
1088 Assert(VERR_NOT_SUPPORTED==rc);
1089 svcClientVersionUnsupported(0, 0);
1090 }
1091
1092 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
1093
1094// if (RT_SUCCESS(rc))
1095// {
1096// /* Update parameters.*/
1097// paParms[1].u.pointer.size = cbWriteback;
1098// }
1099 /* Return the required buffer size always */
1100 pFnCmd->cbWriteback = cbWriteback;
1101 }
1102 else
1103 {
1104 Assert(0);
1105 rc = VERR_INVALID_PARAMETER;
1106 }
1107
1108 break;
1109 }
1110
1111 case SHCRGL_GUEST_FN_SET_VERSION:
1112 {
1113 Assert(0);
1114 rc = VERR_NOT_IMPLEMENTED;
1115 break;
1116 }
1117
1118 case SHCRGL_GUEST_FN_SET_PID:
1119 {
1120 Assert(0);
1121 rc = VERR_NOT_IMPLEMENTED;
1122 break;
1123 }
1124
1125 default:
1126 {
1127 Assert(0);
1128 rc = VERR_NOT_IMPLEMENTED;
1129 }
1130
1131 }
1132
1133 pHdr->result = rc;
1134
1135 return VINF_SUCCESS;
1136}
1137#endif
1138
1139/*
1140 * We differentiate between a function handler for the guest and one for the host.
1141 */
1142static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
1143{
1144 int rc = VINF_SUCCESS;
1145
1146 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
1147
1148#ifdef DEBUG
1149 uint32_t i;
1150
1151 for (i = 0; i < cParms; i++)
1152 {
1153 /** @todo parameters other than 32 bit */
1154 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
1155 }
1156#endif
1157
1158 switch (u32Function)
1159 {
1160#ifdef VBOX_WITH_CRHGSMI
1161 case SHCRGL_HOST_FN_CRHGSMI_CMD:
1162 {
1163 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
1164 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
1165 rc = vboxCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr);
1166 else
1167 rc = VERR_INVALID_PARAMETER;
1168 } break;
1169 case SHCRGL_HOST_FN_CRHGSMI_CTL:
1170 {
1171 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
1172 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
1173 rc = vboxCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr);
1174 else
1175 rc = VERR_INVALID_PARAMETER;
1176 } break;
1177#endif
1178 case SHCRGL_HOST_FN_SET_CONSOLE:
1179 {
1180 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
1181
1182 /* Verify parameter count and types. */
1183 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
1184 {
1185 rc = VERR_INVALID_PARAMETER;
1186 }
1187 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
1188 {
1189 rc = VERR_INVALID_PARAMETER;
1190 }
1191 else
1192 {
1193 /* Fetch parameters. */
1194 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
1195 uint32_t cbData = paParms[0].u.pointer.size;
1196
1197 /* Verify parameters values. */
1198 if (cbData != sizeof (IConsole*))
1199 {
1200 rc = VERR_INVALID_PARAMETER;
1201 }
1202 else if (!pConsole)
1203 {
1204 rc = VERR_INVALID_PARAMETER;
1205 }
1206 else /* Execute the function. */
1207 {
1208 ComPtr<IMachine> pMachine;
1209 ComPtr<IDisplay> pDisplay;
1210 ComPtr<IFramebuffer> pFramebuffer;
1211 LONG xo, yo;
1212 LONG64 winId = 0;
1213 ULONG monitorCount, i, w, h;
1214
1215 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
1216 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
1217 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
1218
1219 rc = crVBoxServerSetScreenCount(monitorCount);
1220 AssertRCReturn(rc, rc);
1221
1222 for (i=0; i<monitorCount; ++i)
1223 {
1224 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
1225
1226 if (!pDisplay)
1227 {
1228 rc = crVBoxServerUnmapScreen(i);
1229 AssertRCReturn(rc, rc);
1230 }
1231 else
1232 {
1233 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
1234 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
1235 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
1236
1237 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
1238 AssertRCReturn(rc, rc);
1239 }
1240 }
1241
1242 g_pConsole = pConsole;
1243
1244 /*rc = crVBoxServerSetOffscreenRendering(GL_TRUE);*/
1245 rc = VINF_SUCCESS;
1246 }
1247 }
1248 break;
1249 }
1250 case SHCRGL_HOST_FN_SET_VM:
1251 {
1252 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
1253
1254 /* Verify parameter count and types. */
1255 if (cParms != SHCRGL_CPARMS_SET_VM)
1256 {
1257 rc = VERR_INVALID_PARAMETER;
1258 }
1259 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
1260 {
1261 rc = VERR_INVALID_PARAMETER;
1262 }
1263 else
1264 {
1265 /* Fetch parameters. */
1266 PVM pVM = (PVM)paParms[0].u.pointer.addr;
1267 uint32_t cbData = paParms[0].u.pointer.size;
1268
1269 /* Verify parameters values. */
1270 if (cbData != sizeof (PVM))
1271 {
1272 rc = VERR_INVALID_PARAMETER;
1273 }
1274 else
1275 {
1276 /* Execute the function. */
1277 g_pVM = pVM;
1278 rc = VINF_SUCCESS;
1279 }
1280 }
1281 break;
1282 }
1283 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
1284 {
1285 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
1286
1287 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
1288 {
1289 rc = VERR_INVALID_PARAMETER;
1290 break;
1291 }
1292
1293 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
1294 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
1295 )
1296 {
1297 rc = VERR_INVALID_PARAMETER;
1298 break;
1299 }
1300
1301 Assert(sizeof(RTRECT)==4*sizeof(GLint));
1302
1303 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
1304 break;
1305 }
1306 case SHCRGL_HOST_FN_SCREEN_CHANGED:
1307 {
1308 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
1309
1310 /* Verify parameter count and types. */
1311 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
1312 {
1313 rc = VERR_INVALID_PARAMETER;
1314 }
1315 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
1316 {
1317 rc = VERR_INVALID_PARAMETER;
1318 }
1319 else
1320 {
1321 /* Fetch parameters. */
1322 uint32_t screenId = paParms[0].u.uint32;
1323
1324 /* Execute the function. */
1325 ComPtr<IDisplay> pDisplay;
1326 ComPtr<IFramebuffer> pFramebuffer;
1327 LONG xo, yo;
1328 LONG64 winId = 0;
1329 ULONG w, h;
1330
1331 Assert(g_pConsole);
1332 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
1333 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
1334
1335 if (!pFramebuffer)
1336 {
1337 rc = crVBoxServerUnmapScreen(screenId);
1338 AssertRCReturn(rc, rc);
1339 }
1340 else
1341 {
1342 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
1343 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
1344 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
1345
1346 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
1347 AssertRCReturn(rc, rc);
1348 }
1349
1350 rc = VINF_SUCCESS;
1351 }
1352 break;
1353 }
1354 default:
1355 rc = VERR_NOT_IMPLEMENTED;
1356 break;
1357 }
1358
1359 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
1360 return rc;
1361}
1362
1363extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1364{
1365 int rc = VINF_SUCCESS;
1366
1367 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
1368
1369 if (!ptable)
1370 {
1371 rc = VERR_INVALID_PARAMETER;
1372 }
1373 else
1374 {
1375 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
1376
1377 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1378 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1379 {
1380 rc = VERR_INVALID_PARAMETER;
1381 }
1382 else
1383 {
1384 g_pHelpers = ptable->pHelpers;
1385
1386 ptable->cbClient = sizeof (void*);
1387
1388 ptable->pfnUnload = svcUnload;
1389 ptable->pfnConnect = svcConnect;
1390 ptable->pfnDisconnect = svcDisconnect;
1391 ptable->pfnCall = svcCall;
1392 ptable->pfnHostCall = svcHostCall;
1393 ptable->pfnSaveState = svcSaveState;
1394 ptable->pfnLoadState = svcLoadState;
1395 ptable->pvService = NULL;
1396
1397 if (!crVBoxServerInit())
1398 return VERR_NOT_SUPPORTED;
1399
1400 rc = svcPresentFBOInit();
1401 }
1402 }
1403
1404 return rc;
1405}
1406
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