VirtualBox

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

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

crOpenGL: fix guest compiz clipping with forced fbo

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

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