1 | /* $Id: ogl_hgcm.c 15532 2008-12-15 18:53:11Z vboxsync $ */
|
---|
2 |
|
---|
3 | /** @file
|
---|
4 | * VBox OpenGL hgcm related functions
|
---|
5 | */
|
---|
6 |
|
---|
7 | /*
|
---|
8 | * Copyright (C) 2006-2008 Sun Microsystems, Inc.
|
---|
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 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
---|
19 | * Clara, CA 95054 USA or visit http://www.sun.com if you need
|
---|
20 | * additional information or have any questions.
|
---|
21 | */
|
---|
22 |
|
---|
23 | #include "ogl_hgcm.h"
|
---|
24 | #include <VBox/VBoxGuest.h>
|
---|
25 | #include <stdio.h>
|
---|
26 |
|
---|
27 | static DWORD dwOGLTlsIndex = TLS_OUT_OF_INDEXES;
|
---|
28 | static VBOX_OGL_CTX vboxOGLCtx = {0};
|
---|
29 |
|
---|
30 | /**
|
---|
31 | * Initialize the OpenGL guest-host communication channel
|
---|
32 | *
|
---|
33 | * @return success or failure (boolean)
|
---|
34 | * @param hDllInst Dll instance handle
|
---|
35 | */
|
---|
36 | BOOL VBoxOGLInit()
|
---|
37 | {
|
---|
38 | dwOGLTlsIndex = TlsAlloc();
|
---|
39 | if (dwOGLTlsIndex == TLS_OUT_OF_INDEXES)
|
---|
40 | {
|
---|
41 | DbgPrintf(("TlsAlloc failed with %d\n", GetLastError()));
|
---|
42 | return FALSE;
|
---|
43 | }
|
---|
44 | DbgPrintf(("VBoxOGLInit TLS index=%d\n", dwOGLTlsIndex));
|
---|
45 |
|
---|
46 | /* open VBox guest driver */
|
---|
47 | vboxOGLCtx.hGuestDrv = CreateFile(VBOXGUEST_DEVICE_NAME,
|
---|
48 | GENERIC_READ | GENERIC_WRITE,
|
---|
49 | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
---|
50 | NULL,
|
---|
51 | OPEN_EXISTING,
|
---|
52 | FILE_ATTRIBUTE_NORMAL,
|
---|
53 | NULL);
|
---|
54 | if (vboxOGLCtx.hGuestDrv == INVALID_HANDLE_VALUE)
|
---|
55 | {
|
---|
56 | DbgPrintf(("VBoxService: could not open VBox Guest Additions driver! rc = %d\n", GetLastError()));
|
---|
57 | return FALSE;
|
---|
58 | }
|
---|
59 |
|
---|
60 | VBoxOGLThreadAttach();
|
---|
61 | return TRUE;
|
---|
62 | }
|
---|
63 |
|
---|
64 | /**
|
---|
65 | * Destroy the OpenGL guest-host communication channel
|
---|
66 | *
|
---|
67 | * @return success or failure (boolean)
|
---|
68 | */
|
---|
69 | BOOL VBoxOGLExit()
|
---|
70 | {
|
---|
71 | DbgPrintf(("VBoxOGLExit\n"));
|
---|
72 | VBoxOGLThreadDetach();
|
---|
73 | CloseHandle(vboxOGLCtx.hGuestDrv);
|
---|
74 |
|
---|
75 | return TRUE;
|
---|
76 | }
|
---|
77 |
|
---|
78 | /**
|
---|
79 | * Initialize new thread
|
---|
80 | *
|
---|
81 | * @return success or failure (boolean)
|
---|
82 | */
|
---|
83 | BOOL VBoxOGLThreadAttach()
|
---|
84 | {
|
---|
85 | PVBOX_OGL_THREAD_CTX pCtx;
|
---|
86 | VBoxGuestHGCMConnectInfo info;
|
---|
87 | DWORD cbReturned;
|
---|
88 |
|
---|
89 | DbgPrintf(("VBoxOGLThreadAttach id=%x\n", GetCurrentThreadId()));
|
---|
90 |
|
---|
91 | pCtx = (PVBOX_OGL_THREAD_CTX)malloc(sizeof(*pCtx));
|
---|
92 | AssertReturn(pCtx, FALSE);
|
---|
93 | if (!pCtx)
|
---|
94 | return FALSE;
|
---|
95 |
|
---|
96 | VBoxOGLSetThreadCtx(pCtx);
|
---|
97 |
|
---|
98 | memset (&info, 0, sizeof (info));
|
---|
99 |
|
---|
100 | info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
|
---|
101 |
|
---|
102 | strcpy (info.Loc.u.host.achName, "VBoxSharedCrOpenGL");
|
---|
103 |
|
---|
104 | if (DeviceIoControl(vboxOGLCtx.hGuestDrv,
|
---|
105 | VBOXGUEST_IOCTL_HGCM_CONNECT,
|
---|
106 | &info, sizeof (info),
|
---|
107 | &info, sizeof (info),
|
---|
108 | &cbReturned,
|
---|
109 | NULL))
|
---|
110 | {
|
---|
111 | if (info.result == VINF_SUCCESS)
|
---|
112 | {
|
---|
113 | pCtx->u32ClientID = info.u32ClientID;
|
---|
114 | DbgPrintf(("HGCM connect was successful: client id =%x\n", pCtx->u32ClientID));
|
---|
115 | }
|
---|
116 | else DbgPrintf(("HGCM connect failed with rc=%x\n", info.result));
|
---|
117 | }
|
---|
118 | else
|
---|
119 | {
|
---|
120 | DbgPrintf(("HGCM connect failed with rc=%x\n", GetLastError()));
|
---|
121 | return FALSE;
|
---|
122 | }
|
---|
123 |
|
---|
124 | return TRUE;
|
---|
125 | }
|
---|
126 |
|
---|
127 | /**
|
---|
128 | * Clean up for terminating thread
|
---|
129 | *
|
---|
130 | * @return success or failure (boolean)
|
---|
131 | */
|
---|
132 | BOOL VBoxOGLThreadDetach()
|
---|
133 | {
|
---|
134 | PVBOX_OGL_THREAD_CTX pCtx;
|
---|
135 | VBoxGuestHGCMDisconnectInfo info;
|
---|
136 | DWORD cbReturned;
|
---|
137 | BOOL bRet;
|
---|
138 |
|
---|
139 | DbgPrintf(("VBoxOGLThreadDetach id=%x\n", GetCurrentThreadId()));
|
---|
140 |
|
---|
141 | pCtx = VBoxOGLGetThreadCtx();
|
---|
142 | if (pCtx && pCtx->u32ClientID)
|
---|
143 | {
|
---|
144 | memset (&info, 0, sizeof (info));
|
---|
145 |
|
---|
146 | info.u32ClientID = pCtx->u32ClientID;
|
---|
147 |
|
---|
148 | bRet = DeviceIoControl(vboxOGLCtx.hGuestDrv,
|
---|
149 | VBOXGUEST_IOCTL_HGCM_DISCONNECT,
|
---|
150 | &info, sizeof (info),
|
---|
151 | &info, sizeof (info),
|
---|
152 | &cbReturned,
|
---|
153 | NULL);
|
---|
154 |
|
---|
155 | if (!bRet)
|
---|
156 | {
|
---|
157 | DbgPrintf(("Disconnect failed with %x\n", GetLastError()));
|
---|
158 | }
|
---|
159 | }
|
---|
160 | if (pCtx)
|
---|
161 | {
|
---|
162 | free(pCtx);
|
---|
163 | VBoxOGLSetThreadCtx(NULL);
|
---|
164 | }
|
---|
165 |
|
---|
166 | return TRUE;
|
---|
167 | }
|
---|
168 |
|
---|
169 | /**
|
---|
170 | * Set the thread local OpenGL context
|
---|
171 | *
|
---|
172 | * @param pCtx thread local OpenGL context ptr
|
---|
173 | */
|
---|
174 | void VBoxOGLSetThreadCtx(PVBOX_OGL_THREAD_CTX pCtx)
|
---|
175 | {
|
---|
176 | BOOL ret;
|
---|
177 |
|
---|
178 | ret = TlsSetValue(dwOGLTlsIndex, pCtx);
|
---|
179 | Assert(ret);
|
---|
180 | }
|
---|
181 |
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * Return the thread local OpenGL context
|
---|
185 | *
|
---|
186 | * @return thread local OpenGL context ptr or NULL if failure
|
---|
187 | */
|
---|
188 | PVBOX_OGL_THREAD_CTX VBoxOGLGetThreadCtx()
|
---|
189 | {
|
---|
190 | PVBOX_OGL_THREAD_CTX pCtx;
|
---|
191 |
|
---|
192 | pCtx = (PVBOX_OGL_THREAD_CTX)TlsGetValue(dwOGLTlsIndex);
|
---|
193 | if (!pCtx)
|
---|
194 | {
|
---|
195 | /* lazy init */
|
---|
196 | VBoxOGLThreadAttach();
|
---|
197 | pCtx = (PVBOX_OGL_THREAD_CTX)TlsGetValue(dwOGLTlsIndex);
|
---|
198 | }
|
---|
199 | Assert(pCtx);
|
---|
200 | return pCtx;
|
---|
201 | }
|
---|
202 |
|
---|
203 | #ifdef DEBUG
|
---|
204 | /**
|
---|
205 | * Log to the debug output device
|
---|
206 | *
|
---|
207 | * @param pszFormat Format string
|
---|
208 | * @param ... Variable parameters
|
---|
209 | */
|
---|
210 | void VBoxDbgLog(char *pszFormat, ...)
|
---|
211 | {
|
---|
212 | va_list va;
|
---|
213 | CHAR Buffer[10240];
|
---|
214 |
|
---|
215 | va_start(va, pszFormat);
|
---|
216 |
|
---|
217 | if (strlen(pszFormat) < 512)
|
---|
218 | {
|
---|
219 | vsprintf (Buffer, pszFormat, va);
|
---|
220 |
|
---|
221 | printf(Buffer);
|
---|
222 | // OutputDebugStringA(Buffer);
|
---|
223 | }
|
---|
224 |
|
---|
225 | va_end (va);
|
---|
226 | }
|
---|
227 | #endif
|
---|