[15532] | 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 "cr_spu.h"
|
---|
| 8 | #include "cr_error.h"
|
---|
| 9 | #include "cr_mem.h"
|
---|
| 10 | #include "stub.h"
|
---|
[30474] | 11 | #include <iprt/thread.h>
|
---|
[15532] | 12 |
|
---|
[30475] | 13 | #ifdef GLX
|
---|
[30474] | 14 | Display* stubGetWindowDisplay(WindowInfo *pWindow)
|
---|
| 15 | {
|
---|
[30475] | 16 | #if defined(CR_NEWWINTRACK)
|
---|
[32420] | 17 | if ((NIL_RTTHREAD!=stub.hSyncThread) && (RTThreadNativeSelf()==RTThreadGetNative(stub.hSyncThread)))
|
---|
[30474] | 18 | {
|
---|
| 19 | if (pWindow && pWindow->dpy && !pWindow->syncDpy)
|
---|
| 20 | {
|
---|
| 21 | crDebug("going to XOpenDisplay(%s)", pWindow->dpyName);
|
---|
| 22 | pWindow->syncDpy = XOpenDisplay(pWindow->dpyName);
|
---|
| 23 | if (!pWindow->syncDpy)
|
---|
| 24 | {
|
---|
| 25 | crWarning("Failed to open display %s", pWindow->dpyName);
|
---|
| 26 | }
|
---|
| 27 | return pWindow->syncDpy;
|
---|
| 28 | }
|
---|
| 29 | else
|
---|
| 30 | {
|
---|
| 31 | return pWindow ? pWindow->syncDpy:NULL;
|
---|
| 32 | }
|
---|
| 33 | }
|
---|
| 34 | else
|
---|
| 35 | #endif
|
---|
| 36 | {
|
---|
| 37 | return pWindow ? pWindow->dpy:NULL;
|
---|
| 38 | }
|
---|
| 39 | }
|
---|
[30475] | 40 | #endif
|
---|
[30474] | 41 |
|
---|
[15532] | 42 | /**
|
---|
| 43 | * Returns -1 on error
|
---|
| 44 | */
|
---|
[55626] | 45 | GLint APIENTRY crCreateContext(char *dpyName, GLint visBits)
|
---|
[15532] | 46 | {
|
---|
| 47 | ContextInfo *context;
|
---|
| 48 | stubInit();
|
---|
| 49 | /* XXX in Chromium 1.5 and earlier, the last parameter was UNDECIDED.
|
---|
| 50 | * That didn't seem right so it was changed to CHROMIUM. (Brian)
|
---|
| 51 | */
|
---|
[42499] | 52 | context = stubNewContext(dpyName, visBits, CHROMIUM, 0
|
---|
| 53 | #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
|
---|
| 54 | , NULL
|
---|
| 55 | #endif
|
---|
| 56 | );
|
---|
[15532] | 57 | return context ? (int) context->id : -1;
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | void APIENTRY crDestroyContext( GLint context )
|
---|
| 61 | {
|
---|
| 62 | stubDestroyContext(context);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | void APIENTRY crMakeCurrent( GLint window, GLint context )
|
---|
| 66 | {
|
---|
| 67 | WindowInfo *winInfo = (WindowInfo *)
|
---|
| 68 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 69 | ContextInfo *contextInfo = (ContextInfo *)
|
---|
| 70 | crHashtableSearch(stub.contextTable, context);
|
---|
| 71 | if (contextInfo && contextInfo->type == NATIVE) {
|
---|
| 72 | crWarning("Can't call crMakeCurrent with native GL context");
|
---|
| 73 | return;
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | stubMakeCurrent(winInfo, contextInfo);
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | GLint APIENTRY crGetCurrentContext( void )
|
---|
| 80 | {
|
---|
[39568] | 81 | ContextInfo *context;
|
---|
[15532] | 82 | stubInit();
|
---|
[39568] | 83 | context = stubGetCurrentContext();
|
---|
| 84 | if (context)
|
---|
| 85 | return (GLint) context->id;
|
---|
[15532] | 86 | else
|
---|
| 87 | return 0;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | GLint APIENTRY crGetCurrentWindow( void )
|
---|
| 91 | {
|
---|
[39568] | 92 | ContextInfo *context;
|
---|
[15532] | 93 | stubInit();
|
---|
[39568] | 94 | context = stubGetCurrentContext();
|
---|
| 95 | if (context && context->currentDrawable)
|
---|
| 96 | return context->currentDrawable->spuWindow;
|
---|
[15532] | 97 | else
|
---|
| 98 | return -1;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | void APIENTRY crSwapBuffers( GLint window, GLint flags )
|
---|
| 102 | {
|
---|
[30474] | 103 | WindowInfo *winInfo = (WindowInfo *)
|
---|
[15532] | 104 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 105 | if (winInfo)
|
---|
| 106 | stubSwapBuffers(winInfo, flags);
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | /**
|
---|
| 110 | * Returns -1 on error
|
---|
| 111 | */
|
---|
| 112 | GLint APIENTRY crWindowCreate( const char *dpyName, GLint visBits )
|
---|
| 113 | {
|
---|
| 114 | stubInit();
|
---|
| 115 | return stubNewWindow( dpyName, visBits );
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | void APIENTRY crWindowDestroy( GLint window )
|
---|
| 119 | {
|
---|
[42518] | 120 | stubDestroyWindow( 0, window );
|
---|
[15532] | 121 | }
|
---|
| 122 |
|
---|
| 123 | void APIENTRY crWindowSize( GLint window, GLint w, GLint h )
|
---|
| 124 | {
|
---|
| 125 | const WindowInfo *winInfo = (const WindowInfo *)
|
---|
| 126 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 127 | if (winInfo && winInfo->type == CHROMIUM)
|
---|
| 128 | {
|
---|
| 129 | crDebug("Dispatched crWindowSize (%i)", window);
|
---|
| 130 | stub.spu->dispatch_table.WindowSize( window, w, h );
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | void APIENTRY crWindowPosition( GLint window, GLint x, GLint y )
|
---|
| 135 | {
|
---|
| 136 | const WindowInfo *winInfo = (const WindowInfo *)
|
---|
| 137 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 138 | if (winInfo && winInfo->type == CHROMIUM)
|
---|
| 139 | {
|
---|
| 140 | crDebug("Dispatched crWindowPosition (%i)", window);
|
---|
| 141 | stub.spu->dispatch_table.WindowPosition( window, x, y );
|
---|
| 142 | }
|
---|
| 143 | }
|
---|
| 144 |
|
---|
[45132] | 145 | void APIENTRY crWindowVisibleRegion( GLint window, GLint cRects, const void *pRects )
|
---|
[15532] | 146 | {
|
---|
| 147 | const WindowInfo *winInfo = (const WindowInfo *)
|
---|
| 148 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 149 | if (winInfo && winInfo->type == CHROMIUM)
|
---|
| 150 | {
|
---|
| 151 | crDebug("Dispatched crWindowVisibleRegion (%i, cRects=%i)", window, cRects);
|
---|
| 152 | stub.spu->dispatch_table.WindowVisibleRegion( window, cRects, pRects );
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 |
|
---|
[45132] | 156 | void APIENTRY crVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, const GLint *pRects)
|
---|
[43888] | 157 | {
|
---|
[63204] | 158 | RT_NOREF(texture, cfg, xPos, yPos, cRects, pRects);
|
---|
[43888] | 159 | crError("not expected!");
|
---|
| 160 | }
|
---|
| 161 |
|
---|
[15532] | 162 | void APIENTRY crWindowShow( GLint window, GLint flag )
|
---|
| 163 | {
|
---|
| 164 | WindowInfo *winInfo = (WindowInfo *)
|
---|
| 165 | crHashtableSearch(stub.windowTable, (unsigned int) window);
|
---|
| 166 | if (winInfo && winInfo->type == CHROMIUM)
|
---|
| 167 | stub.spu->dispatch_table.WindowShow( window, flag );
|
---|
| 168 | winInfo->mapped = flag ? GL_TRUE : GL_FALSE;
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | void APIENTRY stub_GetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values )
|
---|
| 172 | {
|
---|
| 173 | char **ret;
|
---|
| 174 | switch( target )
|
---|
| 175 | {
|
---|
| 176 | case GL_HEAD_SPU_NAME_CR:
|
---|
| 177 | ret = (char **) values;
|
---|
| 178 | *ret = stub.spu->name;
|
---|
| 179 | return;
|
---|
| 180 | default:
|
---|
| 181 | stub.spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, values );
|
---|
| 182 | break;
|
---|
| 183 | }
|
---|
| 184 | }
|
---|
| 185 |
|
---|
| 186 | /*
|
---|
| 187 | * Updates geometry info for given spu window.
|
---|
[33540] | 188 | * Returns GL_TRUE if it changed since last call, GL_FALSE otherwise.
|
---|
[15532] | 189 | * bForceUpdate - forces dispatching of geometry info even if it's unchanged
|
---|
| 190 | */
|
---|
| 191 | GLboolean stubUpdateWindowGeometry(WindowInfo *pWindow, GLboolean bForceUpdate)
|
---|
| 192 | {
|
---|
| 193 | int winX, winY;
|
---|
| 194 | unsigned int winW, winH;
|
---|
| 195 | GLboolean res = GL_FALSE;
|
---|
| 196 |
|
---|
| 197 | CRASSERT(pWindow);
|
---|
| 198 |
|
---|
| 199 | stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
|
---|
| 200 |
|
---|
| 201 | /* @todo remove "if (winW && winH)"?*/
|
---|
| 202 | if (winW && winH) {
|
---|
| 203 | if (stub.trackWindowSize) {
|
---|
| 204 | if (bForceUpdate || winW != pWindow->width || winH != pWindow->height) {
|
---|
| 205 | crDebug("Dispatched WindowSize (%i)", pWindow->spuWindow);
|
---|
[41963] | 206 | #ifdef VBOX_WITH_WDDM
|
---|
| 207 | if (!stub.bRunningUnderWDDM || pWindow->mapped)
|
---|
| 208 | #endif
|
---|
| 209 | {
|
---|
| 210 | stub.spuDispatch.WindowSize(pWindow->spuWindow, winW, winH);
|
---|
| 211 | }
|
---|
[15532] | 212 | pWindow->width = winW;
|
---|
| 213 | pWindow->height = winH;
|
---|
| 214 | res = GL_TRUE;
|
---|
| 215 | }
|
---|
| 216 | }
|
---|
| 217 | if (stub.trackWindowPos) {
|
---|
| 218 | if (bForceUpdate || winX != pWindow->x || winY != pWindow->y) {
|
---|
| 219 | crDebug("Dispatched WindowPosition (%i)", pWindow->spuWindow);
|
---|
[41963] | 220 | #ifdef VBOX_WITH_WDDM
|
---|
| 221 | if (!stub.bRunningUnderWDDM || pWindow->mapped)
|
---|
| 222 | #endif
|
---|
| 223 | {
|
---|
| 224 | stub.spuDispatch.WindowPosition(pWindow->spuWindow, winX, winY);
|
---|
| 225 | }
|
---|
[15532] | 226 | pWindow->x = winX;
|
---|
| 227 | pWindow->y = winY;
|
---|
| 228 | res = GL_TRUE;
|
---|
| 229 | }
|
---|
| 230 | }
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 | return res;
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 | #ifdef WINDOWS
|
---|
| 237 | /*
|
---|
| 238 | * Updates visible regions for given spu window.
|
---|
[33540] | 239 | * Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
|
---|
[15532] | 240 | */
|
---|
| 241 | GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
|
---|
| 242 | {
|
---|
| 243 | HRGN hVisRgn;
|
---|
| 244 | HWND hwnd;
|
---|
| 245 | DWORD dwCount;
|
---|
| 246 | LPRGNDATA lpRgnData;
|
---|
| 247 | POINT pt;
|
---|
| 248 | int iret;
|
---|
| 249 |
|
---|
| 250 | if (!pWindow) return GL_FALSE;
|
---|
[34295] | 251 | hwnd = pWindow->hWnd;
|
---|
[15532] | 252 | if (!hwnd) return GL_FALSE;
|
---|
| 253 |
|
---|
[34295] | 254 | if (hwnd!=WindowFromDC(pWindow->drawable))
|
---|
| 255 | {
|
---|
| 256 | crWarning("Window(%i) DC is no longer valid", pWindow->spuWindow);
|
---|
| 257 | return GL_FALSE;
|
---|
| 258 | }
|
---|
[15532] | 259 |
|
---|
| 260 | hVisRgn = CreateRectRgn(0,0,0,0);
|
---|
| 261 | iret = GetRandomRgn(pWindow->drawable, hVisRgn, SYSRGN);
|
---|
| 262 |
|
---|
| 263 | if (iret==1)
|
---|
| 264 | {
|
---|
| 265 | /*@todo check win95/win98 here, as rects should be already in client space there*/
|
---|
| 266 | /* Convert screen related rectangles to client related rectangles */
|
---|
| 267 | pt.x = 0;
|
---|
| 268 | pt.y = 0;
|
---|
| 269 | ScreenToClient(hwnd, &pt);
|
---|
| 270 | OffsetRgn(hVisRgn, pt.x, pt.y);
|
---|
| 271 |
|
---|
| 272 | /*
|
---|
| 273 | dwCount = GetRegionData(hVisRgn, 0, NULL);
|
---|
| 274 | lpRgnData = crAlloc(dwCount);
|
---|
| 275 | crDebug("GetRandomRgn returned 1, dwCount=%d", dwCount);
|
---|
| 276 | GetRegionData(hVisRgn, dwCount, lpRgnData);
|
---|
| 277 | crDebug("Region consists of %d rects", lpRgnData->rdh.nCount);
|
---|
| 278 |
|
---|
| 279 | pRects = (RECT*) lpRgnData->Buffer;
|
---|
| 280 | for (i=0; i<lpRgnData->rdh.nCount; ++i)
|
---|
| 281 | {
|
---|
| 282 | crDebug("Rgn[%d] = (%d, %d, %d, %d)", i, pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
|
---|
| 283 | }
|
---|
| 284 | crFree(lpRgnData);
|
---|
| 285 | */
|
---|
| 286 |
|
---|
| 287 | if (pWindow->hVisibleRegion==INVALID_HANDLE_VALUE
|
---|
| 288 | || !EqualRgn(pWindow->hVisibleRegion, hVisRgn))
|
---|
| 289 | {
|
---|
| 290 | DeleteObject(pWindow->hVisibleRegion);
|
---|
| 291 | pWindow->hVisibleRegion = hVisRgn;
|
---|
| 292 |
|
---|
| 293 | dwCount = GetRegionData(hVisRgn, 0, NULL);
|
---|
| 294 | lpRgnData = crAlloc(dwCount);
|
---|
| 295 |
|
---|
| 296 | if (lpRgnData)
|
---|
| 297 | {
|
---|
| 298 | GetRegionData(hVisRgn, dwCount, lpRgnData);
|
---|
| 299 | crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, lpRgnData->rdh.nCount);
|
---|
| 300 | stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, lpRgnData->rdh.nCount, (GLint*) lpRgnData->Buffer);
|
---|
| 301 | crFree(lpRgnData);
|
---|
| 302 | return GL_TRUE;
|
---|
| 303 | }
|
---|
| 304 | else crWarning("GetRegionData failed, VisibleRegions update failed");
|
---|
| 305 | }
|
---|
| 306 | else
|
---|
| 307 | {
|
---|
| 308 | DeleteObject(hVisRgn);
|
---|
| 309 | }
|
---|
| 310 | }
|
---|
| 311 | else
|
---|
| 312 | {
|
---|
| 313 | crWarning("GetRandomRgn returned (%d) instead of (1), VisibleRegions update failed", iret);
|
---|
| 314 | DeleteObject(hVisRgn);
|
---|
| 315 | }
|
---|
| 316 |
|
---|
| 317 | return GL_FALSE;
|
---|
| 318 | }
|
---|
| 319 |
|
---|
[30440] | 320 | # ifndef CR_NEWWINTRACK
|
---|
[15532] | 321 | static void stubCBCheckWindowsInfo(unsigned long key, void *data1, void *data2)
|
---|
| 322 | {
|
---|
| 323 | WindowInfo *winInfo = (WindowInfo *) data1;
|
---|
| 324 | CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) data2;
|
---|
| 325 |
|
---|
| 326 | (void) key;
|
---|
| 327 |
|
---|
| 328 | if (winInfo && pMsgInfo && winInfo->type == CHROMIUM)
|
---|
| 329 | {
|
---|
| 330 | switch (pMsgInfo->message)
|
---|
| 331 | {
|
---|
| 332 | case WM_MOVING:
|
---|
| 333 | case WM_SIZING:
|
---|
| 334 | case WM_MOVE:
|
---|
| 335 | case WM_CREATE:
|
---|
| 336 | case WM_SIZE:
|
---|
| 337 | {
|
---|
| 338 | GLboolean changed = stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo);
|
---|
| 339 |
|
---|
| 340 | if (stubUpdateWindowGeometry(winInfo, GL_FALSE) || changed)
|
---|
| 341 | {
|
---|
[42518] | 342 | stubForcedFlush(0);
|
---|
[15532] | 343 | }
|
---|
| 344 | break;
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 | case WM_SHOWWINDOW:
|
---|
| 348 | case WM_ACTIVATEAPP:
|
---|
| 349 | case WM_PAINT:
|
---|
| 350 | case WM_NCPAINT:
|
---|
| 351 | case WM_NCACTIVATE:
|
---|
| 352 | case WM_ERASEBKGND:
|
---|
| 353 | {
|
---|
| 354 | if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
|
---|
| 355 | {
|
---|
[42518] | 356 | stubForcedFlush(0);
|
---|
[15532] | 357 | }
|
---|
| 358 | break;
|
---|
| 359 | }
|
---|
| 360 |
|
---|
| 361 | default:
|
---|
| 362 | {
|
---|
| 363 | if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
|
---|
| 364 | {
|
---|
| 365 | crDebug("Visibility info updated due to unknown hooked message (%d)", pMsgInfo->message);
|
---|
[42518] | 366 | stubForcedFlush(0);
|
---|
[15532] | 367 | }
|
---|
| 368 | break;
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 | }
|
---|
| 372 | }
|
---|
| 373 |
|
---|
| 374 | LRESULT CALLBACK stubCBWindowMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
---|
| 375 | {
|
---|
| 376 | CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) lParam;
|
---|
| 377 |
|
---|
| 378 | if (nCode>=0 && pMsgInfo)
|
---|
| 379 | {
|
---|
| 380 | switch (pMsgInfo->message)
|
---|
| 381 | {
|
---|
| 382 | case WM_MOVING:
|
---|
| 383 | case WM_SIZING:
|
---|
| 384 | case WM_MOVE:
|
---|
| 385 | case WM_ACTIVATEAPP:
|
---|
| 386 | case WM_NCPAINT:
|
---|
| 387 | case WM_NCACTIVATE:
|
---|
| 388 | case WM_ERASEBKGND:
|
---|
| 389 | case WM_CREATE:
|
---|
| 390 | case WM_SIZE:
|
---|
| 391 | case WM_SHOWWINDOW:
|
---|
| 392 | {
|
---|
| 393 | crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
|
---|
| 394 | break;
|
---|
| 395 | }
|
---|
| 396 |
|
---|
| 397 | /* @todo remove it*/
|
---|
| 398 | default:
|
---|
| 399 | {
|
---|
| 400 | /*crDebug("hook: unknown message (%d)", pMsgInfo->message);*/
|
---|
| 401 | crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
|
---|
| 402 | break;
|
---|
| 403 | }
|
---|
| 404 | }
|
---|
| 405 | }
|
---|
| 406 |
|
---|
| 407 | return CallNextHookEx(stub.hMessageHook, nCode, wParam, lParam);
|
---|
| 408 | }
|
---|
| 409 |
|
---|
| 410 | void stubInstallWindowMessageHook()
|
---|
| 411 | {
|
---|
| 412 | stub.hMessageHook = SetWindowsHookEx(WH_CALLWNDPROCRET, stubCBWindowMessageHookProc, 0, crThreadID());
|
---|
| 413 |
|
---|
| 414 | if (!stub.hMessageHook)
|
---|
| 415 | crWarning("Window message hook install failed! (not fatal)");
|
---|
| 416 | }
|
---|
| 417 |
|
---|
| 418 | void stubUninstallWindowMessageHook()
|
---|
| 419 | {
|
---|
| 420 | if (stub.hMessageHook)
|
---|
| 421 | UnhookWindowsHookEx(stub.hMessageHook);
|
---|
| 422 | }
|
---|
[30440] | 423 | # endif /*# ifndef CR_NEWWINTRACK*/
|
---|
| 424 |
|
---|
[16480] | 425 | #elif defined(GLX) //#ifdef WINDOWS
|
---|
[32420] | 426 | void stubCheckXExtensions(WindowInfo *pWindow)
|
---|
[16480] | 427 | {
|
---|
| 428 | int evb, erb, vmi=0, vma=0;
|
---|
[30486] | 429 | Display *dpy = stubGetWindowDisplay(pWindow);
|
---|
[16480] | 430 |
|
---|
[32420] | 431 | stub.bXExtensionsChecked = GL_TRUE;
|
---|
| 432 | stub.trackWindowVisibleRgn = 0;
|
---|
| 433 |
|
---|
[30486] | 434 | XLOCK(dpy);
|
---|
| 435 | if (XCompositeQueryExtension(dpy, &evb, &erb)
|
---|
| 436 | && XCompositeQueryVersion(dpy, &vma, &vmi)
|
---|
[16480] | 437 | && (vma>0 || vmi>=4))
|
---|
| 438 | {
|
---|
[32420] | 439 | stub.bHaveXComposite = GL_TRUE;
|
---|
[16480] | 440 | crDebug("XComposite %i.%i", vma, vmi);
|
---|
| 441 | vma=0;
|
---|
| 442 | vmi=0;
|
---|
[30486] | 443 | if (XFixesQueryExtension(dpy, &evb, &erb)
|
---|
| 444 | && XFixesQueryVersion(dpy, &vma, &vmi)
|
---|
[16480] | 445 | && vma>=2)
|
---|
| 446 | {
|
---|
| 447 | crDebug("XFixes %i.%i", vma, vmi);
|
---|
[32420] | 448 | stub.bHaveXFixes = GL_TRUE;
|
---|
| 449 | stub.trackWindowVisibleRgn = 1;
|
---|
[30486] | 450 | XUNLOCK(dpy);
|
---|
[32420] | 451 | return;
|
---|
[16480] | 452 | }
|
---|
| 453 | else
|
---|
| 454 | {
|
---|
| 455 | crWarning("XFixes not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
|
---|
| 456 | }
|
---|
| 457 | }
|
---|
| 458 | else
|
---|
| 459 | {
|
---|
| 460 | crWarning("XComposite not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
|
---|
| 461 | }
|
---|
[30486] | 462 | XUNLOCK(dpy);
|
---|
[32420] | 463 | return;
|
---|
[16480] | 464 | }
|
---|
| 465 |
|
---|
| 466 | /*
|
---|
| 467 | * Updates visible regions for given spu window.
|
---|
[33540] | 468 | * Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
|
---|
[16480] | 469 | */
|
---|
| 470 | GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
|
---|
| 471 | {
|
---|
| 472 | XserverRegion xreg;
|
---|
| 473 | int cRects, i;
|
---|
| 474 | XRectangle *pXRects;
|
---|
| 475 | GLint* pGLRects;
|
---|
[30474] | 476 | Display *dpy;
|
---|
[32420] | 477 | bool bNoUpdate = false;
|
---|
[16480] | 478 |
|
---|
[32420] | 479 | if (!stub.bXExtensionsChecked)
|
---|
[16480] | 480 | {
|
---|
[32420] | 481 | stubCheckXExtensions(pWindow);
|
---|
| 482 | if (!stub.trackWindowVisibleRgn)
|
---|
| 483 | {
|
---|
| 484 | return GL_FALSE;
|
---|
| 485 | }
|
---|
[16480] | 486 | }
|
---|
| 487 |
|
---|
[30474] | 488 | dpy = stubGetWindowDisplay(pWindow);
|
---|
| 489 |
|
---|
[16480] | 490 | /*@todo see comment regarding size/position updates and XSync, same applies to those functions but
|
---|
| 491 | * it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension.
|
---|
| 492 | */
|
---|
[30474] | 493 | XLOCK(dpy);
|
---|
| 494 | xreg = XCompositeCreateRegionFromBorderClip(dpy, pWindow->drawable);
|
---|
| 495 | pXRects = XFixesFetchRegion(dpy, xreg, &cRects);
|
---|
| 496 | XFixesDestroyRegion(dpy, xreg);
|
---|
| 497 | XUNLOCK(dpy);
|
---|
[16480] | 498 |
|
---|
[32420] | 499 | /* Check for compiz main window */
|
---|
| 500 | if (!pWindow->pVisibleRegions && !cRects)
|
---|
[16480] | 501 | {
|
---|
[32420] | 502 | #ifdef VBOX_TEST_MEGOO
|
---|
| 503 | XWindowAttributes attr;
|
---|
| 504 | XLOCK(dpy);
|
---|
| 505 | XSync(dpy, false);
|
---|
| 506 | XGetWindowAttributes(dpy, pWindow->drawable, &attr);
|
---|
| 507 | XUNLOCK(dpy);
|
---|
| 508 |
|
---|
| 509 | bNoUpdate = attr.override_redirect;
|
---|
| 510 | #else
|
---|
| 511 | bNoUpdate = true;
|
---|
| 512 | #endif
|
---|
| 513 | }
|
---|
| 514 |
|
---|
| 515 | if (!bNoUpdate
|
---|
| 516 | && (!pWindow->pVisibleRegions
|
---|
| 517 | || pWindow->cVisibleRegions!=cRects
|
---|
| 518 | || (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle)))))
|
---|
| 519 | {
|
---|
| 520 | if (pWindow->pVisibleRegions)
|
---|
| 521 | {
|
---|
| 522 | XFree(pWindow->pVisibleRegions);
|
---|
| 523 | }
|
---|
| 524 |
|
---|
[16480] | 525 | pWindow->pVisibleRegions = pXRects;
|
---|
| 526 | pWindow->cVisibleRegions = cRects;
|
---|
| 527 |
|
---|
[59505] | 528 | pGLRects = crAlloc(cRects ? 4*cRects*sizeof(GLint) : 4*sizeof(GLint));
|
---|
[16480] | 529 | if (!pGLRects)
|
---|
| 530 | {
|
---|
[28294] | 531 | crWarning("stubUpdateWindowVisibileRegions: failed to allocate %lu bytes",
|
---|
| 532 | (unsigned long)(4*cRects*sizeof(GLint)));
|
---|
[16480] | 533 | return GL_FALSE;
|
---|
| 534 | }
|
---|
| 535 |
|
---|
[16718] | 536 | //crDebug("Got %i rects.", cRects);
|
---|
[16480] | 537 | for (i=0; i<cRects; ++i)
|
---|
| 538 | {
|
---|
| 539 | pGLRects[4*i+0] = pXRects[i].x;
|
---|
| 540 | pGLRects[4*i+1] = pXRects[i].y;
|
---|
| 541 | pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width;
|
---|
| 542 | pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height;
|
---|
[16718] | 543 | //crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]);
|
---|
[16480] | 544 | }
|
---|
| 545 |
|
---|
| 546 | crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects);
|
---|
| 547 | stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects);
|
---|
| 548 | crFree(pGLRects);
|
---|
| 549 | return GL_TRUE;
|
---|
| 550 | }
|
---|
| 551 | else
|
---|
| 552 | {
|
---|
| 553 | XFree(pXRects);
|
---|
| 554 | }
|
---|
| 555 |
|
---|
| 556 | return GL_FALSE;
|
---|
| 557 | }
|
---|
| 558 | #endif //#ifdef WINDOWS
|
---|