VirtualBox

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

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

crOpenGL: more new present mechanism

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.4 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
19GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID)
20{
21 CRMuralInfo *defaultMural;
22 GLint dims[2];
23 GLint windowID = -1;
24 /*
25 * Have first SPU make a new window.
26 */
27 GLint spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, visBits );
28 if (spuWindow < 0) {
29 crServerReturnValue( &spuWindow, sizeof(spuWindow) );
30 return spuWindow;
31 }
32
33 /* get initial window size */
34 cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, spuWindow, GL_INT, 2, dims);
35
36 defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
37 CRASSERT(defaultMural);
38 mural->gX = 0;
39 mural->gY = 0;
40 mural->width = dims[0];
41 mural->height = dims[1];
42
43 mural->spuWindow = spuWindow;
44 mural->screenId = 0;
45 mural->bVisible = GL_FALSE;
46 mural->bUseFBO = GL_FALSE;
47
48 mural->cVisibleRects = 0;
49 mural->pVisibleRects = NULL;
50 mural->bReceivedRects = GL_FALSE;
51
52 mural->pvOutputRedirectInstance = NULL;
53
54 /* generate ID for this new window/mural (special-case for file conns) */
55 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
56 windowID = spuWindow;
57 else
58 windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
59
60 crServerSetupOutputRedirect(mural);
61
62 return windowID;
63}
64
65GLint
66crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID)
67{
68 CRMuralInfo *mural;
69 GLint windowID = -1;
70 CRCreateInfo_t *pCreateInfo;
71
72 if (cr_server.sharedWindows) {
73 int pos, j;
74
75 /* find empty position in my (curclient) windowList */
76 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
77 if (cr_server.curClient->windowList[pos] == 0) {
78 break;
79 }
80 }
81 if (pos == CR_MAX_WINDOWS) {
82 crWarning("Too many windows in crserver!");
83 return -1;
84 }
85
86 /* Look if any other client has a window for this slot */
87 for (j = 0; j < cr_server.numClients; j++) {
88 if (cr_server.clients[j]->windowList[pos] != 0) {
89 /* use that client's window */
90 windowID = cr_server.clients[j]->windowList[pos];
91 cr_server.curClient->windowList[pos] = windowID;
92 crServerReturnValue( &windowID, sizeof(windowID) ); /* real return value */
93 crDebug("CRServer: client %p sharing window %d",
94 cr_server.curClient, windowID);
95 return windowID;
96 }
97 }
98 }
99
100
101 /*
102 * Create a new mural for the new window.
103 */
104 mural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
105 if (!mural)
106 {
107 crWarning("crCalloc failed!");
108 return -1;
109 }
110
111 windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID);
112 if (windowID < 0)
113 {
114 crWarning("crServerMuralInit failed!");
115 crFree(mural);
116 return windowID;
117 }
118
119 crHashtableAdd(cr_server.muralTable, windowID, mural);
120
121 pCreateInfo = (CRCreateInfo_t *) crAlloc(sizeof(CRCreateInfo_t));
122 pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
123 pCreateInfo->visualBits = visBits;
124 crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
125
126 crDebug("CRServer: client %p created new window %d (SPU window %d)",
127 cr_server.curClient, windowID, mural->spuWindow);
128
129 if (windowID != -1 && !cr_server.bIsInLoadingState) {
130 int pos;
131 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
132 if (cr_server.curClient->windowList[pos] == 0) {
133 cr_server.curClient->windowList[pos] = windowID;
134 break;
135 }
136 }
137 }
138
139 crServerReturnValue( &windowID, sizeof(windowID) );
140 return windowID;
141}
142
143static int crServerRemoveClientWindow(CRClient *pClient, GLint window)
144{
145 int pos;
146
147 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
148 {
149 if (pClient->windowList[pos] == window)
150 {
151 pClient->windowList[pos] = 0;
152 return true;
153 }
154 }
155
156 return false;
157}
158
159void crServerMuralTerm(CRMuralInfo *mural)
160{
161 if (mural->pvOutputRedirectInstance)
162 {
163 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
164 mural->pvOutputRedirectInstance = NULL;
165 }
166
167 crServerRedirMuralFBO(mural, GL_FALSE);
168 crServerDeleteMuralFBO(mural);
169
170 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
171
172 if (mural->pVisibleRects)
173 {
174 crFree(mural->pVisibleRects);
175 }
176}
177
178void SERVER_DISPATCH_APIENTRY
179crServerDispatchWindowDestroy( GLint window )
180{
181 CRMuralInfo *mural;
182 int32_t client;
183 CRClientNode *pNode;
184 int found=false;
185
186 if (!window)
187 {
188 crWarning("Unexpected attempt to delete default mural, ignored!");
189 return;
190 }
191
192 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
193 if (!mural) {
194 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
195 return;
196 }
197
198 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
199
200 crServerMuralTerm(mural);
201
202 if (cr_server.currentWindow == window)
203 {
204 cr_server.currentWindow = -1;
205 CRASSERT(cr_server.currentMural == mural);
206 cr_server.currentMural = NULL;
207 }
208 else
209 {
210 CRASSERT(cr_server.currentMural != mural);
211 }
212
213 if (cr_server.curClient)
214 {
215 if (cr_server.curClient->currentMural == mural)
216 {
217 cr_server.curClient->currentMural = NULL;
218 cr_server.curClient->currentWindow = -1;
219 }
220
221 found = crServerRemoveClientWindow(cr_server.curClient, window);
222
223 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
224 if (!found)
225 {
226 for (client=0; client<cr_server.numClients; ++client)
227 {
228 if (cr_server.clients[client]==cr_server.curClient)
229 continue;
230
231 found = crServerRemoveClientWindow(cr_server.clients[client], window);
232
233 if (found) break;
234 }
235 }
236
237 if (!found)
238 {
239 pNode=cr_server.pCleanupClient;
240
241 while (pNode && !found)
242 {
243 found = crServerRemoveClientWindow(pNode->pClient, window);
244 pNode = pNode->next;
245 }
246 }
247
248 CRASSERT(found);
249 }
250
251 /*Make sure this window isn't active in other clients*/
252 for (client=0; client<cr_server.numClients; ++client)
253 {
254 if (cr_server.clients[client]->currentMural == mural)
255 {
256 cr_server.clients[client]->currentMural = NULL;
257 cr_server.clients[client]->currentWindow = -1;
258 }
259 }
260
261 pNode=cr_server.pCleanupClient;
262 while (pNode)
263 {
264 if (pNode->pClient->currentMural == mural)
265 {
266 pNode->pClient->currentMural = NULL;
267 pNode->pClient->currentWindow = -1;
268 }
269 pNode = pNode->next;
270 }
271
272 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
273
274 crHashtableDelete(cr_server.muralTable, window, crFree);
275}
276
277void crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height)
278{
279 mural->width = width;
280 mural->height = height;
281
282 if (cr_server.curClient && cr_server.curClient->currentMural == mural)
283 {
284 crStateGetCurrent()->buffer.width = mural->width;
285 crStateGetCurrent()->buffer.height = mural->height;
286 }
287
288 crServerCheckMuralGeometry(mural);
289
290 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
291}
292
293void SERVER_DISPATCH_APIENTRY
294crServerDispatchWindowSize( GLint window, GLint width, GLint height )
295{
296 CRMuralInfo *mural;
297
298 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
299 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
300 if (!mural) {
301#if EXTRA_WARN
302 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
303#endif
304 return;
305 }
306
307 crServerMuralSize(mural, width, height);
308
309 /* Work-around Intel driver bug */
310 CRASSERT(!cr_server.curClient
311 || !cr_server.curClient->currentMural
312 || cr_server.curClient->currentMural == mural);
313 if (cr_server.curClient && cr_server.curClient->currentMural == mural)
314 {
315 CRContextInfo * ctxInfo = cr_server.currentCtxInfo;
316 CRASSERT(ctxInfo);
317 crServerDispatchMakeCurrent(window, 0, ctxInfo->CreateInfo.externalID);
318 }
319}
320
321
322void SERVER_DISPATCH_APIENTRY
323crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
324{
325 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
326 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
327 if (!mural) {
328#if EXTRA_WARN
329 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
330#endif
331 return;
332 }
333 mural->gX = x;
334 mural->gY = y;
335
336 crServerCheckMuralGeometry(mural);
337}
338
339void SERVER_DISPATCH_APIENTRY
340crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
341{
342 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
343 if (!mural) {
344#if EXTRA_WARN
345 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
346#endif
347 return;
348 }
349
350 if (mural->pVisibleRects)
351 {
352 crFree(mural->pVisibleRects);
353 mural->pVisibleRects = NULL;
354 }
355
356 mural->cVisibleRects = cRects;
357 mural->bReceivedRects = GL_TRUE;
358 if (cRects)
359 {
360 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
361 if (!mural->pVisibleRects)
362 {
363 crError("Out of memory in crServerDispatchWindowVisibleRegion");
364 }
365 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
366 }
367
368 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
369
370 if (mural->pvOutputRedirectInstance)
371 {
372 /* @todo the code assumes that RTRECT == four GLInts. */
373 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
374 cRects, (RTRECT *)pRects);
375 }
376}
377
378
379
380void SERVER_DISPATCH_APIENTRY
381crServerDispatchWindowShow( GLint window, GLint state )
382{
383 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
384 if (!mural) {
385#if EXTRA_WARN
386 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
387#endif
388 return;
389 }
390
391 if (!mural->bUseFBO)
392 {
393 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
394 }
395
396 mural->bVisible = state;
397}
398
399
400GLint
401crServerSPUWindowID(GLint serverWindow)
402{
403 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
404 if (!mural) {
405#if EXTRA_WARN
406 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
407 serverWindow);
408#endif
409 return -1;
410 }
411 return mural->spuWindow;
412}
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