crservice.cpp revision cb3515c46867acaaf4f72b61d7aa32aad27b6017
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * VBox crOpenGL: Host service entry points.
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * Copyright (C) 2006-2012 Oracle Corporation
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * This file is part of VirtualBox Open Source Edition (OSE), as
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * available from http://www.virtualbox.org. This file is free software;
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * you can redistribute it and/or modify it under the terms of the GNU
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * General Public License (GPL) as published by the Free Software
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * Foundation, in version 2 as it comes in the "COPYING" file of the
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8697518fc739fe6c563a212a175faaa28db32113Alin Brici * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
8697518fc739fe6c563a212a175faaa28db32113Alin Brici#define __STDC_CONSTANT_MACROS /* needed for a definition in iprt/string.h */
#include "cr_mem.h"
#include "cr_server.h"
#ifndef RT_OS_WINDOWS
# define DWORD int
# define WINAPI
/* Used to process guest calls exceeding maximum allowed HGCM call size in a sequence of smaller calls */
typedef struct _CRVBOXSVCBUFFER_t {
void* pData;
typedef struct _CRVBOXSVCPRESENTFBOCMD_t {
void *pData;
typedef struct _CRVBOXSVCPRESENTFBO_t {
/* Schedule a call to a separate worker thread to avoid deadlock on EMT thread when the screen configuration changes
static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
if (!pCmd)
LogRel(("SHARED_CROPENGL svcPresentFBO: not enough memory (%d)\n", sizeof(CRVBOXSVCPRESENTFBOCMD_t)));
pCmd->x = x;
pCmd->y = y;
pCmd->w = w;
pCmd->h = h;
// @todo use critsect only to fetch the list and update the g_SvcPresentFBO's pQueueHead and pQueueTail.
while (pCmd)
CHECK_ERROR_RET(pDisplay, DrawToScreen(pCmd->screenId, (BYTE*)pCmd->pData, pCmd->x, pCmd->y, pCmd->w, pCmd->h), rc);
return rc;
static int svcPresentFBOInit(void)
return rc;
static int svcPresentFBOTearDown(void)
while (pQueue)
return rc;
if (!g_pConsole)
if (!pFramebuffer)
return rc;
return rc;
return rc;
static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
while (pBuffer)
return VINF_SUCCESS;
static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
return VERR_SSM_UNEXPECTED_DATA;
/*@todo ugly hack, as we don't know size of stored opengl data try to read untill end of opengl data marker*/
char current;
while (*pMatch)
pMatch++;
return VINF_SUCCESS;
while (uiId)
if (!pBuffer)
return VERR_NO_MEMORY;
return VERR_NO_MEMORY;
if (g_pCRVBoxSVCBuffers)
return VERR_SSM_UNEXPECTED_DATA;
return VINF_SUCCESS;
/*MS's opengl32 tries to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
static int shown = 0;
if (iBuffer)
while (pBuffer)
static int shown=0;
shown++;
return NULL;
return pBuffer;
return NULL;
if (pBuffer)
return NULL;
if (g_pCRVBoxSVCBuffers)
return pBuffer;
static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
#ifdef DEBUG
uint32_t i;
for (i = 0; i < cParms; i++)
switch (u32Function)
case SHCRGL_GUEST_FN_WRITE:
svcClientVersionUnsupported(0, 0);
case SHCRGL_GUEST_FN_INJECT:
svcClientVersionUnsupported(0, 0);
crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
case SHCRGL_GUEST_FN_READ:
svcClientVersionUnsupported(0, 0);
svcClientVersionUnsupported(0, 0);
case SHCRGL_GUEST_FN_SET_PID:
if (!pSvcBuffer)
svcClientVersionUnsupported(0, 0);
case SHCRGL_GUEST_FN_GET_CAPS:
static void crScreenshotHandle(CRVBOXHGCMTAKESCREENSHOT *pScreenshot, uint32_t idScreen, uint64_t u64Now)
if (!pScreenshot->pfnScreenshotBegin || pScreenshot->pfnScreenshotBegin(pScreenshot->pvContext, idScreen, u64Now))
int rc = crServerVBoxScreenshotGet(idScreen, pScreenshot->u32Width, pScreenshot->u32Height, pScreenshot->u32Pitch, pScreenshot->pvBuffer, &Screenshot);
static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
#ifdef DEBUG
uint32_t i;
for (i = 0; i < cParms; i++)
switch (u32Function)
#ifdef VBOX_WITH_CRHGSMI
rc = crVBoxServerCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr, paParms[0].u.pointer.size);
svcClientVersionUnsupported(0, 0);
rc = crVBoxServerCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr, paParms[0].u.pointer.size);
else if (!pConsole)
for (i=0; i<monitorCount; ++i)
if (!pFramebuffer)
case SHCRGL_HOST_FN_SET_VM:
rc = crVBoxServerSetRootVisibleRegion(paParms[0].u.pointer.size / sizeof (RTRECT), (const RTRECT*)paParms[0].u.pointer.addr);
ULONG w, h;
if (!pFramebuffer)
if (!winId)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
for (int i = 0; i < SHCRGL_CPARMS_VIEWPORT_CHANGED; ++i)
return rc;
if (!ptable)
Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
if (!crVBoxServerInit())
return VERR_NOT_SUPPORTED;
return rc;
#ifdef RT_OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
(void) lpvReserved;
switch (fdwReason)
case DLL_THREAD_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_ATTACH:
return TRUE;