VirtualBox

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

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

crOpenGL: fix window size updates are lost if window is resized between monitors and then moved away

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.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
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 int pos;
124
125 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
126 if (!mural) {
127 crWarning("CRServer: invalid window %d passed to WindowDestroy()", window);
128 return;
129 }
130
131 crDebug("CRServer: Destroying window %d (spu window %d)", window, mural->spuWindow);
132 cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
133
134 if (cr_server.curClient)
135 {
136 if (cr_server.curClient->currentMural == mural)
137 {
138 cr_server.curClient->currentMural = NULL;
139 cr_server.curClient->currentWindow = -1;
140 }
141
142 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
143 if (cr_server.curClient->windowList[pos] == window)
144 {
145 cr_server.curClient->windowList[pos] = 0;
146 break;
147 }
148
149 /*Same as with contexts, some apps destroy it not in a thread where it was created*/
150 if (CR_MAX_WINDOWS==pos)
151 {
152 int32_t client;
153
154 for (client=0; client<cr_server.numClients; ++client)
155 {
156 if (cr_server.clients[client]==cr_server.curClient)
157 continue;
158
159 for (pos = 0; pos < CR_MAX_WINDOWS; ++pos)
160 if (cr_server.clients[client]->windowList[pos] == window)
161 {
162 cr_server.clients[client]->windowList[pos] = 0;
163 break;
164 }
165
166 if (pos<CR_MAX_WINDOWS)
167 {
168 if (cr_server.clients[client]->currentMural == mural)
169 {
170 cr_server.clients[client]->currentMural = NULL;
171 cr_server.clients[client]->currentWindow = -1;
172 }
173 break;
174 }
175 }
176 }
177
178 CRASSERT(pos<CR_MAX_WINDOWS);
179 }
180
181 if (cr_server.currentWindow == window)
182 {
183 cr_server.currentWindow = -1;
184 crServerRedirMuralFBO(mural, GL_FALSE);
185 crServerDeleteMuralFBO(mural);
186 }
187
188 crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
189
190 if (mural->pVisibleRects)
191 {
192 crFree(mural->pVisibleRects);
193 }
194 crHashtableDelete(cr_server.muralTable, window, crFree);
195}
196
197void SERVER_DISPATCH_APIENTRY
198crServerDispatchWindowSize( GLint window, GLint width, GLint height )
199{
200 CRMuralInfo *mural;
201
202 /* crDebug("CRServer: Window %d size %d x %d", window, width, height);*/
203 mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
204 if (!mural) {
205#if EXTRA_WARN
206 crWarning("CRServer: invalid window %d passed to WindowSize()", window);
207#endif
208 return;
209 }
210 mural->width = width;
211 mural->height = height;
212
213 crServerCheckMuralGeometry(mural);
214
215 cr_server.head_spu->dispatch_table.WindowSize(mural->spuWindow, width, height);
216}
217
218
219void SERVER_DISPATCH_APIENTRY
220crServerDispatchWindowPosition( GLint window, GLint x, GLint y )
221{
222 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
223 /* crDebug("CRServer: Window %d pos %d, %d", window, x, y);*/
224 if (!mural) {
225#if EXTRA_WARN
226 crWarning("CRServer: invalid window %d passed to WindowPosition()", window);
227#endif
228 return;
229 }
230 mural->gX = x;
231 mural->gY = y;
232
233 crServerCheckMuralGeometry(mural);
234}
235
236void SERVER_DISPATCH_APIENTRY
237crServerDispatchWindowVisibleRegion( GLint window, GLint cRects, GLint *pRects )
238{
239 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
240 if (!mural) {
241#if EXTRA_WARN
242 crWarning("CRServer: invalid window %d passed to WindowVisibleRegion()", window);
243#endif
244 return;
245 }
246
247 if (mural->pVisibleRects)
248 {
249 crFree(mural->pVisibleRects);
250 mural->pVisibleRects = NULL;
251 }
252
253 mural->cVisibleRects = cRects;
254 if (cRects)
255 {
256 mural->pVisibleRects = (GLint*) crAlloc(4*sizeof(GLint)*cRects);
257 if (!mural->pVisibleRects)
258 {
259 crError("Out of memory in crServerDispatchWindowVisibleRegion");
260 }
261 crMemcpy(mural->pVisibleRects, pRects, 4*sizeof(GLint)*cRects);
262 }
263
264 cr_server.head_spu->dispatch_table.WindowVisibleRegion(mural->spuWindow, cRects, pRects);
265}
266
267
268
269void SERVER_DISPATCH_APIENTRY
270crServerDispatchWindowShow( GLint window, GLint state )
271{
272 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
273 if (!mural) {
274#if EXTRA_WARN
275 crWarning("CRServer: invalid window %d passed to WindowShow()", window);
276#endif
277 return;
278 }
279
280 if (!mural->bUseFBO)
281 {
282 cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
283 }
284
285 mural->bVisible = state;
286}
287
288
289GLint
290crServerSPUWindowID(GLint serverWindow)
291{
292 CRMuralInfo *mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, serverWindow);
293 if (!mural) {
294#if EXTRA_WARN
295 crWarning("CRServer: invalid window %d passed to crServerSPUWindowID()",
296 serverWindow);
297#endif
298 return -1;
299 }
300 return mural->spuWindow;
301}
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