VirtualBox

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

Last change on this file since 37613 was 37613, checked in by vboxsync, 14 years ago

wddm/3d: fix snapshots with aero

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.2 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 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
152 if (!mural) {
153 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
154 return;
155 }
156
157 if (mural->pvOutputRedirectInstance)
158 {
159 cr_server.outputRedirect.CROREnd(mural->pvOutputRedirectInstance);
160 mural->pvOutputRedirectInstance = NULL;
161 }
162
163 if (cr_server.currentWindow == window)
164 {
165 cr_server.currentWindow = -1;
166 crServerRedirMuralFBO(mural, GL_FALSE);
167 crServerDeleteMuralFBO(mural);
168 }
169
170 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
171 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
172
173 if (cr_server.curClient)
174 {
175 if (cr_server.curClient->currentMural == mural)
176 {
177 cr_server.curClient->currentMural = NULL;
178 cr_server.curClient->currentWindow = -1;
179 }
180
181 found = crServerRemoveClientWindow(cr_server.curClient, window);
182
183 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
184 if (!found)
185 {
186 for (client=0; client<cr_server.numClients; ++client)
187 {
188 if (cr_server.clients[client]==cr_server.curClient)
189 continue;
190
191 found = crServerRemoveClientWindow(cr_server.clients[client], window);
192
193 if (found) break;
194 }
195 }
196
197 if (!found)
198 {
199 pNode=cr_server.pCleanupClient;
200
201 while (pNode && !found)
202 {
203 found = crServerRemoveClientWindow(pNode->pClient, window);
204 pNode = pNode->next;
205 }
206 }
207
208 CRASSERT(found);
209 }
210
211 /*Make sure this window isn't active in other clients*/
212 for (client=0; client<cr_server.numClients; ++client)
213 {
214 if (cr_server.clients[client]->currentMural == mural)
215 {
216 cr_server.clients[client]->currentMural = NULL;
217 cr_server.clients[client]->currentWindow = -1;
218 }
219 }
220
221 pNode=cr_server.pCleanupClient;
222 while (pNode)
223 {
224 if (pNode->pClient->currentMural == mural)
225 {
226 pNode->pClient->currentMural = NULL;
227 pNode->pClient->currentWindow = -1;
228 }
229 pNode = pNode->next;
230 }
231
232 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
233
234 if (mural->pVisibleRects)
235 {
236 crFree(mural->pVisibleRects);
237 }
238 crHashtableDelete(cr_server.muralTable, window, crFree);
239}
240
241void SERVER_DISPATCH_APIENTRY
242crServerDispatchWindowSize( GLint window, GLint width, GLint height )
243{
244 CRMuralInfo *mural;
245
246 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
247 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
248 if (!mural) {
249#if EXTRA_WARN
250 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
251#endif
252 return;
253 }
254 mural->width = width;
255 mural->height = height;
256
257 crStateGetCurrent()->buffer.width = mural->width;
258 crStateGetCurrent()->buffer.height = mural->height;
259
260 crServerCheckMuralGeometry(mural);
261
262 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
263}
264
265
266void SERVER_DISPATCH_APIENTRY
267crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
268{
269 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
270 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
271 if (!mural) {
272#if EXTRA_WARN
273 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
274#endif
275 return;
276 }
277 mural->gX = x;
278 mural->gY = y;
279
280 crServerCheckMuralGeometry(mural);
281}
282
283void SERVER_DISPATCH_APIENTRY
284crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
285{
286 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
287 if (!mural) {
288#if EXTRA_WARN
289 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
290#endif
291 return;
292 }
293
294 if (mural->pVisibleRects)
295 {
296 crFree(mural->pVisibleRects);
297 mural->pVisibleRects = NULL;
298 }
299
300 mural->cVisibleRects = cRects;
301 mural->bReceivedRects = GL_TRUE;
302 if (cRects)
303 {
304 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
305 if (!mural->pVisibleRects)
306 {
307 crError("Out of memory in crServerDispatchWindowVisibleRegion");
308 }
309 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
310 }
311
312 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
313
314 if (mural->pvOutputRedirectInstance)
315 {
316 /* @todo the code assumes that RTRECT == four GLInts. */
317 cr_server.outputRedirect.CRORVisibleRegion(mural->pvOutputRedirectInstance,
318 cRects, (RTRECT *)pRects);
319 }
320}
321
322
323
324void SERVER_DISPATCH_APIENTRY
325crServerDispatchWindowShow( GLint window, GLint state )
326{
327 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
328 if (!mural) {
329#if EXTRA_WARN
330 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
331#endif
332 return;
333 }
334
335 if (!mural->bUseFBO)
336 {
337 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
338 }
339
340 mural->bVisible = state;
341}
342
343
344GLint
345crServerSPUWindowID(GLint serverWindow)
346{
347 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
348 if (!mural) {
349#if EXTRA_WARN
350 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
351 serverWindow);
352#endif
353 return -1;
354 }
355 return mural->spuWindow;
356}
Note: See TracBrowser for help on using the repository browser.

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