VirtualBox

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

Last change on this file since 41258 was 41258, checked in by vboxsync, 13 years ago

crOpenGL: fix VRDP+3D for Intel graphics, more VRDP+3D fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.9 KB
Line 
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 crStateGetCurrent()->buffer.width = mural->width;
107 crStateGetCurrent()->buffer.height = mural->height;
108 }
109
110 crDebug("CRServer: client %p created new window %d (SPU window %d)",
111 cr_server.curClient, windowID, spuWindow);
112
113 if (windowID != -1 && !cr_server.bIsInLoadingState) {
114 int pos;
115 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
116 if (cr_server.curClient->windowList[pos] == 0) {
117 cr_server.curClient->windowList[pos] = windowID;
118 break;
119 }
120 }
121 }
122
123 crServerReturnValue( &windowID, sizeof(windowID) );
124 return windowID;
125}
126
127static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
128{
129 int pos;
130
131 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
132 {
133 if (pClient->windowList[pos] == window)
134 {
135 pClient->windowList[pos] = 0;
136 return true;
137 }
138 }
139
140 return false;
141}
142
143void SERVER_DISPATCH_APIENTRY
144crServerDispatchWindowDestroy( GLint window )
145{
146 CRMuralInfo *mural;
147 int32_t client;
148 CRClientNode *pNode;
149 int found=false;
150
151 if (!window)
152 {
153 crWarning("Unexpected attempt to delete default mural, ignored!");
154 return;
155 }
156
157 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
158 if (!mural) {
159 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
160 return;
161 }
162
163 if (mural->pvOutputRedirectInstance)
164 {
165 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
166 mural->pvOutputRedirectInstance = NULL;
167 }
168
169 if (cr_server.currentWindow == window)
170 {
171 cr_server.currentWindow = -1;
172 crServerRedirMuralFBO(mural, GL_FALSE);
173 crServerDeleteMuralFBO(mural);
174 }
175
176 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
177 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
178
179 if (cr_server.curClient)
180 {
181 if (cr_server.curClient->currentMural == mural)
182 {
183 cr_server.curClient->currentMural = NULL;
184 cr_server.curClient->currentWindow = -1;
185 }
186
187 found = crServerRemoveClientWindow(cr_server.curClient, window);
188
189 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
190 if (!found)
191 {
192 for (client=0; client<cr_server.numClients; ++client)
193 {
194 if (cr_server.clients[client]==cr_server.curClient)
195 continue;
196
197 found = crServerRemoveClientWindow(cr_server.clients[client], window);
198
199 if (found) break;
200 }
201 }
202
203 if (!found)
204 {
205 pNode=cr_server.pCleanupClient;
206
207 while (pNode && !found)
208 {
209 found = crServerRemoveClientWindow(pNode->pClient, window);
210 pNode = pNode->next;
211 }
212 }
213
214 CRASSERT(found);
215 }
216
217 /*Make sure this window isn't active in other clients*/
218 for (client=0; client<cr_server.numClients; ++client)
219 {
220 if (cr_server.clients[client]->currentMural == mural)
221 {
222 cr_server.clients[client]->currentMural = NULL;
223 cr_server.clients[client]->currentWindow = -1;
224 }
225 }
226
227 pNode=cr_server.pCleanupClient;
228 while (pNode)
229 {
230 if (pNode->pClient->currentMural == mural)
231 {
232 pNode->pClient->currentMural = NULL;
233 pNode->pClient->currentWindow = -1;
234 }
235 pNode = pNode->next;
236 }
237
238 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
239
240 if (mural->pVisibleRects)
241 {
242 crFree(mural->pVisibleRects);
243 }
244 crHashtableDelete(cr_server.muralTable, window, crFree);
245}
246
247void SERVER_DISPATCH_APIENTRY
248crServerDispatchWindowSize( GLint window, GLint width, GLint height )
249{
250 CRMuralInfo *mural;
251
252 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
253 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
254 if (!mural) {
255#if EXTRA_WARN
256 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
257#endif
258 return;
259 }
260
261 mural->width = width;
262 mural->height = height;
263
264 crStateGetCurrent()->buffer.width = mural->width;
265 crStateGetCurrent()->buffer.height = mural->height;
266
267 if (!width || !height)
268 {
269 crServerDispatchWindowVisibleRegion(window, 0, NULL);
270 return;
271 }
272
273 crServerCheckMuralGeometry(mural);
274
275 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
276
277 /* Work-around Intel driver bug */
278 CRASSERT(cr_server.curClient->currentMural == mural);
279 if (cr_server.curClient->currentMural == mural)
280 {
281 CRContextInfo * ctxInfo = cr_server.currentCtxInfo;
282 CRASSERT(ctxInfo);
283 crServerDispatchMakeCurrent(mural->spuWindow, 0, ctxInfo->CreateInfo.externalID);
284 }
285}
286
287
288void SERVER_DISPATCH_APIENTRY
289crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
290{
291 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
292 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
293 if (!mural) {
294#if EXTRA_WARN
295 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
296#endif
297 return;
298 }
299 mural->gX = x;
300 mural->gY = y;
301
302 if (!mural->width || !mural->height)
303 return;
304
305 crServerCheckMuralGeometry(mural);
306}
307
308void SERVER_DISPATCH_APIENTRY
309crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
310{
311 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
312 if (!mural) {
313#if EXTRA_WARN
314 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
315#endif
316 return;
317 }
318
319 if (mural->pVisibleRects)
320 {
321 crFree(mural->pVisibleRects);
322 mural->pVisibleRects = NULL;
323 }
324
325 mural->cVisibleRects = cRects;
326 mural->bReceivedRects = GL_TRUE;
327 if (cRects)
328 {
329 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
330 if (!mural->pVisibleRects)
331 {
332 crError("Out of memory in crServerDispatchWindowVisibleRegion");
333 }
334 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
335 }
336
337 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
338
339 if (mural->pvOutputRedirectInstance)
340 {
341 /* @todo the code assumes that RTRECT == four GLInts. */
342 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
343 cRects, (RTRECT *)pRects);
344 }
345}
346
347
348
349void SERVER_DISPATCH_APIENTRY
350crServerDispatchWindowShow( GLint window, GLint state )
351{
352 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
353 if (!mural) {
354#if EXTRA_WARN
355 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
356#endif
357 return;
358 }
359
360 if (!mural->bUseFBO)
361 {
362 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
363 }
364
365 mural->bVisible = state;
366}
367
368
369GLint
370crServerSPUWindowID(GLint serverWindow)
371{
372 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
373 if (!mural) {
374#if EXTRA_WARN
375 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
376 serverWindow);
377#endif
378 return -1;
379 }
380 return mural->spuWindow;
381}
Note: See TracBrowser for help on using the repository browser.

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