VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c@ 37472

最後變更 在這個檔案從37472是 36843,由 vboxsync 提交於 14 年 前

3D for VRDP: initial commit (xTracker 5565).

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 10.0 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "server.h"
8#include "server_dispatch.h"
9#include "cr_mem.h"
10#include "cr_rand.h"
11#include "cr_string.h"
12
13GLint SERVER_DISPATCH_APIENTRY
14crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
15{
16 return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
17}
18
19
20GLint
21crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
22{
23 CRMuralInfo *mural;
24 GLint windowID = -1;
25 GLint spuWindow;
26 GLint dims[2];
27 CRCreateInfo_t *pCreateInfo;
28
29 if (cr_server.sharedWindows) {
30 int pos, j;
31
32 /* find empty position in my (curclient) windowList */
33 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
34 if (cr_server.curClient->windowList[pos] == 0) {
35 break;
36 }
37 }
38 if (pos == CR_MAX_WINDOWS) {
39 crWarning("Too many windows in crserver!");
40 return -1;
41 }
42
43 /* Look if any other client has a window for this slot */
44 for (j = 0; j < cr_server.numClients; j++) {
45 if (cr_server.clients[j]->windowList[pos] != 0) {
46 /* use that client's window */
47 windowID = cr_server.clients[j]->windowList[pos];
48 cr_server.curClient->windowList[pos] = windowID;
49 crServerReturnValue( &windowID, sizeof(windowID) ); /* real return value */
50 crDebug("CRServer: client %p sharing window %d",
51 cr_server.curClient, windowID);
52 return windowID;
53 }
54 }
55 }
56
57 /*
58 * Have first SPU make a new window.
59 */
60 spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits );
61 if (spuWindow < 0) {
62 crServerReturnValue( &spuWindow, sizeof(spuWindow) );
63 return spuWindow;
64 }
65
66 /* get initial window size */
67 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
68
69 /*
70 * Create a new mural for the new window.
71 */
72 mural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
73 if (mural) {
74 CRMuralInfo *defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
75 CRASSERT(defaultMural);
76 mural->gX = 0;
77 mural->gY = 0;
78 mural->width = dims[0];
79 mural->height = dims[1];
80
81 mural->spuWindow = spuWindow;
82 mural->screenId = 0;
83 mural->bVisible = GL_FALSE;
84 mural->bUseFBO = GL_FALSE;
85
86 mural->cVisibleRects = 0;
87 mural->pVisibleRects = NULL;
88 mural->bReceivedRects = GL_FALSE;
89
90 mural->pvOutputRedirectInstance = NULL;
91
92 /* generate ID for this new window/mural (special-case for file conns) */
93 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
94 windowID = spuWindow;
95 else
96 windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
97 crHashtableAdd(cr_server.muralTable, windowID, mural);
98
99 pCreateInfo = (CRCreateInfo_t *) crAlloc(sizeof(CRCreateInfo_t));
100 pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
101 pCreateInfo->visualBits = visBits;
102 crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
103
104 crServerSetupOutputRedirect(mural);
105 }
106
107 crDebug("CRServer: client %p created new window %d (SPU window %d)",
108 cr_server.curClient, windowID, spuWindow);
109
110 if (windowID != -1 && !cr_server.bIsInLoadingState) {
111 int pos;
112 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
113 if (cr_server.curClient->windowList[pos] == 0) {
114 cr_server.curClient->windowList[pos] = windowID;
115 break;
116 }
117 }
118 }
119
120 crServerReturnValue( &windowID, sizeof(windowID) );
121 return windowID;
122}
123
124static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
125{
126 int pos;
127
128 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
129 {
130 if (pClient->windowList[pos] == window)
131 {
132 pClient->windowList[pos] = 0;
133 return true;
134 }
135 }
136
137 return false;
138}
139
140void SERVER_DISPATCH_APIENTRY
141crServerDispatchWindowDestroy( GLint window )
142{
143 CRMuralInfo *mural;
144 int32_t client;
145 CRClientNode *pNode;
146 int found=false;
147
148 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
149 if (!mural) {
150 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
151 return;
152 }
153
154 if (mural->pvOutputRedirectInstance)
155 {
156 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
157 mural->pvOutputRedirectInstance = NULL;
158 }
159
160 if (cr_server.currentWindow == window)
161 {
162 cr_server.currentWindow = -1;
163 crServerRedirMuralFBO(mural, GL_FALSE);
164 crServerDeleteMuralFBO(mural);
165 }
166
167 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
168 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
169
170 if (cr_server.curClient)
171 {
172 if (cr_server.curClient->currentMural == mural)
173 {
174 cr_server.curClient->currentMural = NULL;
175 cr_server.curClient->currentWindow = -1;
176 }
177
178 found = crServerRemoveClientWindow(cr_server.curClient, window);
179
180 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
181 if (!found)
182 {
183 for (client=0; client<cr_server.numClients; ++client)
184 {
185 if (cr_server.clients[client]==cr_server.curClient)
186 continue;
187
188 found = crServerRemoveClientWindow(cr_server.clients[client], window);
189
190 if (found) break;
191 }
192 }
193
194 if (!found)
195 {
196 pNode=cr_server.pCleanupClient;
197
198 while (pNode && !found)
199 {
200 found = crServerRemoveClientWindow(pNode->pClient, window);
201 pNode = pNode->next;
202 }
203 }
204
205 CRASSERT(found);
206 }
207
208 /*Make sure this window isn't active in other clients*/
209 for (client=0; client<cr_server.numClients; ++client)
210 {
211 if (cr_server.clients[client]->currentMural == mural)
212 {
213 cr_server.clients[client]->currentMural = NULL;
214 cr_server.clients[client]->currentWindow = -1;
215 }
216 }
217
218 pNode=cr_server.pCleanupClient;
219 while (pNode)
220 {
221 if (pNode->pClient->currentMural == mural)
222 {
223 pNode->pClient->currentMural = NULL;
224 pNode->pClient->currentWindow = -1;
225 }
226 pNode = pNode->next;
227 }
228
229 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
230
231 if (mural->pVisibleRects)
232 {
233 crFree(mural->pVisibleRects);
234 }
235 crHashtableDelete(cr_server.muralTable, window, crFree);
236}
237
238void SERVER_DISPATCH_APIENTRY
239crServerDispatchWindowSize( GLint window, GLint width, GLint height )
240{
241 CRMuralInfo *mural;
242
243 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
244 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
245 if (!mural) {
246#if EXTRA_WARN
247 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
248#endif
249 return;
250 }
251 mural->width = width;
252 mural->height = height;
253
254 crServerCheckMuralGeometry(mural);
255
256 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
257}
258
259
260void SERVER_DISPATCH_APIENTRY
261crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
262{
263 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
264 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
265 if (!mural) {
266#if EXTRA_WARN
267 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
268#endif
269 return;
270 }
271 mural->gX = x;
272 mural->gY = y;
273
274 crServerCheckMuralGeometry(mural);
275}
276
277void SERVER_DISPATCH_APIENTRY
278crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
279{
280 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
281 if (!mural) {
282#if EXTRA_WARN
283 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
284#endif
285 return;
286 }
287
288 if (mural->pVisibleRects)
289 {
290 crFree(mural->pVisibleRects);
291 mural->pVisibleRects = NULL;
292 }
293
294 mural->cVisibleRects = cRects;
295 mural->bReceivedRects = GL_TRUE;
296 if (cRects)
297 {
298 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
299 if (!mural->pVisibleRects)
300 {
301 crError("Out of memory in crServerDispatchWindowVisibleRegion");
302 }
303 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
304 }
305
306 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
307
308 if (mural->pvOutputRedirectInstance)
309 {
310 /* @todo the code assumes that RTRECT == four GLInts. */
311 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
312 cRects, (RTRECT *)pRects);
313 }
314}
315
316
317
318void SERVER_DISPATCH_APIENTRY
319crServerDispatchWindowShow( GLint window, GLint state )
320{
321 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
322 if (!mural) {
323#if EXTRA_WARN
324 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
325#endif
326 return;
327 }
328
329 if (!mural->bUseFBO)
330 {
331 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
332 }
333
334 mural->bVisible = state;
335}
336
337
338GLint
339crServerSPUWindowID(GLint serverWindow)
340{
341 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
342 if (!mural) {
343#if EXTRA_WARN
344 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
345 serverWindow);
346#endif
347 return -1;
348 }
349 return mural->spuWindow;
350}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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