VirtualBox

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

Last change on this file since 33223 was 30011, checked in by vboxsync, 15 years ago

crOpenGL: fix host assertion for some guest mt apps (#5236)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.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
89 /* generate ID for this new window/mural (special-case for file conns) */
90 if (cr_server.curClient && cr_server.curClient->conn->type == CR_FILE)
91 windowID = spuWindow;
92 else
93 windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
94 crHashtableAdd(cr_server.muralTable, windowID, mural);
95
96 pCreateInfo = (CRCreateInfo_t *) crAlloc(sizeof(CRCreateInfo_t));
97 pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
98 pCreateInfo->visualBits = visBits;
99 crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
100 }
101
102 crDebug("CRServer: client %p created new window %d (SPU window %d)",
103 cr_server.curClient, windowID, spuWindow);
104
105 if (windowID != -1 && !cr_server.bIsInLoadingState) {
106 int pos;
107 for (pos = 0; pos < CR_MAX_WINDOWS; pos++) {
108 if (cr_server.curClient->windowList[pos] == 0) {
109 cr_server.curClient->windowList[pos] = windowID;
110 break;
111 }
112 }
113 }
114
115 crServerReturnValue( &windowID, sizeof(windowID) );
116 return windowID;
117}
118
119void SERVER_DISPATCH_APIENTRY
120crServerDispatchWindowDestroy( GLint window )
121{
122 CRMuralInfo *mural;
123 int32_t client;
124 int pos;
125
126 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
127 if (!mural) {
128 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
129 return;
130 }
131
132 if (cr_server.currentWindow == window)
133 {
134 cr_server.currentWindow = -1;
135 crServerRedirMuralFBO(mural, GL_FALSE);
136 crServerDeleteMuralFBO(mural);
137 }
138
139 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
140 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
141
142 if (cr_server.curClient)
143 {
144 if (cr_server.curClient->currentMural == mural)
145 {
146 cr_server.curClient->currentMural = NULL;
147 cr_server.curClient->currentWindow = -1;
148 }
149
150 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
151 if (cr_server.curClient->windowList[pos] == window)
152 {
153 cr_server.curClient->windowList[pos] = 0;
154 break;
155 }
156
157 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
158 if (CR_MAX_WINDOWS==pos)
159 {
160 for (client=0; client<cr_server.numClients; ++client)
161 {
162 if (cr_server.clients[client]==cr_server.curClient)
163 continue;
164
165 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
166 if (cr_server.clients[client]->windowList[pos] == window)
167 {
168 cr_server.clients[client]->windowList[pos] = 0;
169 break;
170 }
171
172 if (pos<CR_MAX_WINDOWS)
173 {
174 if (cr_server.clients[client]->currentMural == mural)
175 {
176 cr_server.clients[client]->currentMural = NULL;
177 cr_server.clients[client]->currentWindow = -1;
178 }
179 break;
180 }
181 }
182 }
183
184 CRASSERT(pos<CR_MAX_WINDOWS);
185 }
186
187 /*Make sure this window isn't active in other clients*/
188 for (client=0; client<cr_server.numClients; ++client)
189 {
190 if (cr_server.clients[client]->currentMural == mural)
191 {
192 cr_server.clients[client]->currentMural = NULL;
193 cr_server.clients[client]->currentWindow = -1;
194 }
195 }
196
197 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
198
199 if (mural->pVisibleRects)
200 {
201 crFree(mural->pVisibleRects);
202 }
203 crHashtableDelete(cr_server.muralTable, window, crFree);
204}
205
206void SERVER_DISPATCH_APIENTRY
207crServerDispatchWindowSize( GLint window, GLint width, GLint height )
208{
209 CRMuralInfo *mural;
210
211 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
212 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
213 if (!mural) {
214#if EXTRA_WARN
215 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
216#endif
217 return;
218 }
219 mural->width = width;
220 mural->height = height;
221
222 crServerCheckMuralGeometry(mural);
223
224 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
225}
226
227
228void SERVER_DISPATCH_APIENTRY
229crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
230{
231 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
232 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
233 if (!mural) {
234#if EXTRA_WARN
235 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
236#endif
237 return;
238 }
239 mural->gX = x;
240 mural->gY = y;
241
242 crServerCheckMuralGeometry(mural);
243}
244
245void SERVER_DISPATCH_APIENTRY
246crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
247{
248 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
249 if (!mural) {
250#if EXTRA_WARN
251 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
252#endif
253 return;
254 }
255
256 if (mural->pVisibleRects)
257 {
258 crFree(mural->pVisibleRects);
259 mural->pVisibleRects = NULL;
260 }
261
262 mural->cVisibleRects = cRects;
263 if (cRects)
264 {
265 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
266 if (!mural->pVisibleRects)
267 {
268 crError("Out of memory in crServerDispatchWindowVisibleRegion");
269 }
270 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
271 }
272
273 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
274}
275
276
277
278void SERVER_DISPATCH_APIENTRY
279crServerDispatchWindowShow( GLint window, GLint state )
280{
281 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
282 if (!mural) {
283#if EXTRA_WARN
284 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
285#endif
286 return;
287 }
288
289 if (!mural->bUseFBO)
290 {
291 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
292 }
293
294 mural->bVisible = state;
295}
296
297
298GLint
299crServerSPUWindowID(GLint serverWindow)
300{
301 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
302 if (!mural) {
303#if EXTRA_WARN
304 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
305 serverWindow);
306#endif
307 return -1;
308 }
309 return mural->spuWindow;
310}
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