stub.c revision 648dd7edbbd133f10d5213c7a0d66414c8c3873c
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington/* Copyright (c) 2001, Stanford University
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * All rights reserved
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington *
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * See the file LICENSE.txt for information on redistributing this software.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#include "cr_spu.h"
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#include "cr_error.h"
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#include "cr_mem.h"
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#include "stub.h"
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#ifdef GLX
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#include <X11/extensions/Xcomposite.h>
d4f49965121892f04f785a9a695fd709b929e9cfJames Phillpotts#include <X11/extensions/Xfixes.h>
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#endif
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonstatic void crForcedFlush()
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey GLint buffer;
af38905e8a5231702db169603d942d5d2e0c4332David Luna stub.spu->dispatch_table.GetIntegerv(GL_DRAW_BUFFER, &buffer);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.DrawBuffer(GL_FRONT);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.Flush();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.DrawBuffer(buffer);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
2dd75eff92ef66e22cca286b6f4fe5a9c929af9dPhill Cunnington
af38905e8a5231702db169603d942d5d2e0c4332David Luna/**
af38905e8a5231702db169603d942d5d2e0c4332David Luna * Returns -1 on error
af38905e8a5231702db169603d942d5d2e0c4332David Luna */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill CunningtonGLint APIENTRY crCreateContext( const char *dpyName, GLint visBits )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ContextInfo *context;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stubInit();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington /* XXX in Chromium 1.5 and earlier, the last parameter was UNDECIDED.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * That didn't seem right so it was changed to CHROMIUM. (Brian)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington context = stubNewContext(dpyName, visBits, CHROMIUM, 0);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington return context ? (int) context->id : -1;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY crDestroyContext( GLint context )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stubDestroyContext(context);
77a123fe3fd0188a9552995da5a36a9f70b0d36fPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
77a123fe3fd0188a9552995da5a36a9f70b0d36fPhill Cunningtonvoid APIENTRY crMakeCurrent( GLint window, GLint context )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington WindowInfo *winInfo = (WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington ContextInfo *contextInfo = (ContextInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.contextTable, context);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (contextInfo && contextInfo->type == NATIVE) {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crWarning("Can't call crMakeCurrent with native GL context");
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington return;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stubMakeCurrent(winInfo, contextInfo);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill CunningtonGLint APIENTRY crGetCurrentContext( void )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington stubInit();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (stub.currentContext)
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey return (GLint) stub.currentContext->id;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington else
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington return 0;
af38905e8a5231702db169603d942d5d2e0c4332David Luna}
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey
33908fb93167e643fbb21b47d87c5b632df0dc59Phill CunningtonGLint APIENTRY crGetCurrentWindow( void )
00d5a64516e3c0f8fddd75cc75da6587b3f02bfcJames Phillpotts{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stubInit();
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey if (stub.currentContext && stub.currentContext->currentDrawable)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington return stub.currentContext->currentDrawable->spuWindow;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington else
af38905e8a5231702db169603d942d5d2e0c4332David Luna return -1;
af38905e8a5231702db169603d942d5d2e0c4332David Luna}
af38905e8a5231702db169603d942d5d2e0c4332David Luna
af38905e8a5231702db169603d942d5d2e0c4332David Lunavoid APIENTRY crSwapBuffers( GLint window, GLint flags )
af38905e8a5231702db169603d942d5d2e0c4332David Luna{
af38905e8a5231702db169603d942d5d2e0c4332David Luna const WindowInfo *winInfo = (const WindowInfo *)
af38905e8a5231702db169603d942d5d2e0c4332David Luna crHashtableSearch(stub.windowTable, (unsigned int) window);
af38905e8a5231702db169603d942d5d2e0c4332David Luna if (winInfo)
af38905e8a5231702db169603d942d5d2e0c4332David Luna stubSwapBuffers(winInfo, flags);
af38905e8a5231702db169603d942d5d2e0c4332David Luna}
af38905e8a5231702db169603d942d5d2e0c4332David Luna
af38905e8a5231702db169603d942d5d2e0c4332David Luna/**
af38905e8a5231702db169603d942d5d2e0c4332David Luna * Returns -1 on error
af38905e8a5231702db169603d942d5d2e0c4332David Luna */
af38905e8a5231702db169603d942d5d2e0c4332David LunaGLint APIENTRY crWindowCreate( const char *dpyName, GLint visBits )
af38905e8a5231702db169603d942d5d2e0c4332David Luna{
af38905e8a5231702db169603d942d5d2e0c4332David Luna stubInit();
af38905e8a5231702db169603d942d5d2e0c4332David Luna return stubNewWindow( dpyName, visBits );
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY crWindowDestroy( GLint window )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington WindowInfo *winInfo = (WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo && winInfo->type == CHROMIUM && stub.spu) {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.WindowDestroy( winInfo->spuWindow );
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#ifdef WINDOWS
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo->hVisibleRegion != INVALID_HANDLE_VALUE)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington DeleteObject(winInfo->hVisibleRegion);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#elif defined(GLX)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo->pVisibleRegions)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington XFree(winInfo->pVisibleRegions);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington#endif
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crForcedFlush();
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableDelete(stub.windowTable, window, crFree);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
d4f49965121892f04f785a9a695fd709b929e9cfJames Phillpotts}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
d4f49965121892f04f785a9a695fd709b929e9cfJames Phillpottsvoid APIENTRY crWindowSize( GLint window, GLint w, GLint h )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington const WindowInfo *winInfo = (const WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts if (winInfo && winInfo->type == CHROMIUM)
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts {
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts crDebug("Dispatched crWindowSize (%i)", window);
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts stub.spu->dispatch_table.WindowSize( window, w, h );
d4f49965121892f04f785a9a695fd709b929e9cfJames Phillpotts }
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts}
c0202e5a338212ae386c672821f6dc4931c50f45James Phillpotts
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY crWindowPosition( GLint window, GLint x, GLint y )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington const WindowInfo *winInfo = (const WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo && winInfo->type == CHROMIUM)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crDebug("Dispatched crWindowPosition (%i)", window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.WindowPosition( window, x, y );
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY crWindowVisibleRegion( GLint window, GLint cRects, void *pRects )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington const WindowInfo *winInfo = (const WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo && winInfo->type == CHROMIUM)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington {
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crDebug("Dispatched crWindowVisibleRegion (%i, cRects=%i)", window, cRects);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.WindowVisibleRegion( window, cRects, pRects );
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY crWindowShow( GLint window, GLint flag )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington WindowInfo *winInfo = (WindowInfo *)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington crHashtableSearch(stub.windowTable, (unsigned int) window);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winInfo && winInfo->type == CHROMIUM)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stub.spu->dispatch_table.WindowShow( window, flag );
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington winInfo->mapped = flag ? GL_TRUE : GL_FALSE;
e9f58f98089a4e4670e5ee2d3df315561084786eRich Riley}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunningtonvoid APIENTRY stub_GetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington char **ret;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington switch( target )
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington {
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington case GL_HEAD_SPU_NAME_CR:
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington ret = (char **) values;
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington *ret = stub.spu->name;
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington return;
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington default:
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington stub.spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, values );
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington break;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington}
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington/*
33908fb93167e643fbb21b47d87c5b632df0dc59Phill Cunnington * Updates geometry info for given spu window.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * Returns GL_TRUE if it changed since last call, GL_FALSE overwise.
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington * bForceUpdate - forces dispatching of geometry info even if it's unchanged
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington */
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill CunningtonGLboolean stubUpdateWindowGeometry(WindowInfo *pWindow, GLboolean bForceUpdate)
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington{
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington int winX, winY;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington unsigned int winW, winH;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington GLboolean res = GL_FALSE;
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington CRASSERT(pWindow);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington /* @todo remove "if (winW && winH)"?*/
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington if (winW && winH) {
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey if (stub.trackWindowSize) {
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey if (bForceUpdate || winW != pWindow->width || winH != pWindow->height) {
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey crDebug("Dispatched WindowSize (%i)", pWindow->spuWindow);
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey stub.spuDispatch.WindowSize(pWindow->spuWindow, winW, winH);
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey pWindow->width = winW;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey pWindow->height = winH;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey res = GL_TRUE;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey }
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey }
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey if (stub.trackWindowPos) {
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey if (bForceUpdate || winX != pWindow->x || winY != pWindow->y) {
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey crDebug("Dispatched WindowPosition (%i)", pWindow->spuWindow);
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey stub.spuDispatch.WindowPosition(pWindow->spuWindow, winX, winY);
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey pWindow->x = winX;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey pWindow->y = winY;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey res = GL_TRUE;
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey }
abba466207a7a0932f2e83e44989ac71b58e1269Brian Bailey }
756d4b8bce5a58e5bd8fe686688b6c42d2e7052bPhill Cunnington }
return res;
}
#ifdef WINDOWS
/*
* Updates visible regions for given spu window.
* Returns GL_TRUE if regions changed since last call, GL_FALSE overwise.
*/
GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
{
HRGN hVisRgn;
HWND hwnd;
DWORD dwCount;
LPRGNDATA lpRgnData;
POINT pt;
int iret;
if (!pWindow) return GL_FALSE;
hwnd = WindowFromDC(pWindow->drawable);
if (!hwnd) return GL_FALSE;
hVisRgn = CreateRectRgn(0,0,0,0);
iret = GetRandomRgn(pWindow->drawable, hVisRgn, SYSRGN);
if (iret==1)
{
/*@todo check win95/win98 here, as rects should be already in client space there*/
/* Convert screen related rectangles to client related rectangles */
pt.x = 0;
pt.y = 0;
ScreenToClient(hwnd, &pt);
OffsetRgn(hVisRgn, pt.x, pt.y);
/*
dwCount = GetRegionData(hVisRgn, 0, NULL);
lpRgnData = crAlloc(dwCount);
crDebug("GetRandomRgn returned 1, dwCount=%d", dwCount);
GetRegionData(hVisRgn, dwCount, lpRgnData);
crDebug("Region consists of %d rects", lpRgnData->rdh.nCount);
pRects = (RECT*) lpRgnData->Buffer;
for (i=0; i<lpRgnData->rdh.nCount; ++i)
{
crDebug("Rgn[%d] = (%d, %d, %d, %d)", i, pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
}
crFree(lpRgnData);
*/
if (pWindow->hVisibleRegion==INVALID_HANDLE_VALUE
|| !EqualRgn(pWindow->hVisibleRegion, hVisRgn))
{
DeleteObject(pWindow->hVisibleRegion);
pWindow->hVisibleRegion = hVisRgn;
dwCount = GetRegionData(hVisRgn, 0, NULL);
lpRgnData = crAlloc(dwCount);
if (lpRgnData)
{
GetRegionData(hVisRgn, dwCount, lpRgnData);
crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, lpRgnData->rdh.nCount);
stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, lpRgnData->rdh.nCount, (GLint*) lpRgnData->Buffer);
crFree(lpRgnData);
return GL_TRUE;
}
else crWarning("GetRegionData failed, VisibleRegions update failed");
}
else
{
DeleteObject(hVisRgn);
}
}
else
{
crWarning("GetRandomRgn returned (%d) instead of (1), VisibleRegions update failed", iret);
DeleteObject(hVisRgn);
}
return GL_FALSE;
}
static void stubCBCheckWindowsInfo(unsigned long key, void *data1, void *data2)
{
WindowInfo *winInfo = (WindowInfo *) data1;
CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) data2;
(void) key;
if (winInfo && pMsgInfo && winInfo->type == CHROMIUM)
{
switch (pMsgInfo->message)
{
case WM_MOVING:
case WM_SIZING:
case WM_MOVE:
case WM_CREATE:
case WM_SIZE:
{
GLboolean changed = stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo);
if (stubUpdateWindowGeometry(winInfo, GL_FALSE) || changed)
{
crForcedFlush();
}
break;
}
case WM_SHOWWINDOW:
case WM_ACTIVATEAPP:
case WM_PAINT:
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_ERASEBKGND:
{
if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
{
crForcedFlush();
}
break;
}
default:
{
if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
{
crDebug("Visibility info updated due to unknown hooked message (%d)", pMsgInfo->message);
crForcedFlush();
}
break;
}
}
}
}
LRESULT CALLBACK stubCBWindowMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) lParam;
if (nCode>=0 && pMsgInfo)
{
#ifdef CHROMIUM_THREADSAFE
crLockMutex(&stub.mutex);
#endif
switch (pMsgInfo->message)
{
case WM_MOVING:
case WM_SIZING:
case WM_MOVE:
case WM_ACTIVATEAPP:
case WM_NCPAINT:
case WM_NCACTIVATE:
case WM_ERASEBKGND:
case WM_CREATE:
case WM_SIZE:
case WM_SHOWWINDOW:
{
crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
break;
}
/* @todo remove it*/
default:
{
/*crDebug("hook: unknown message (%d)", pMsgInfo->message);*/
crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
break;
}
}
#ifdef CHROMIUM_THREADSAFE
crUnlockMutex(&stub.mutex);
#endif
}
return CallNextHookEx(stub.hMessageHook, nCode, wParam, lParam);
}
void stubInstallWindowMessageHook()
{
stub.hMessageHook = SetWindowsHookEx(WH_CALLWNDPROCRET, stubCBWindowMessageHookProc, 0, crThreadID());
if (!stub.hMessageHook)
crWarning("Window message hook install failed! (not fatal)");
}
void stubUninstallWindowMessageHook()
{
if (stub.hMessageHook)
UnhookWindowsHookEx(stub.hMessageHook);
}
#elif defined(GLX) //#ifdef WINDOWS
static GLboolean stubCheckXExtensions(WindowInfo *pWindow)
{
int evb, erb, vmi=0, vma=0;
if (XCompositeQueryExtension(pWindow->dpy, &evb, &erb)
&& XCompositeQueryVersion(pWindow->dpy, &vma, &vmi)
&& (vma>0 || vmi>=4))
{
crDebug("XComposite %i.%i", vma, vmi);
vma=0;
vmi=0;
if (XFixesQueryExtension(pWindow->dpy, &evb, &erb)
&& XFixesQueryVersion(pWindow->dpy, &vma, &vmi)
&& vma>=2)
{
crDebug("XFixes %i.%i", vma, vmi);
return GL_TRUE;
}
else
{
crWarning("XFixes not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
}
}
else
{
crWarning("XComposite not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
}
return GL_FALSE;
}
/*
* Updates visible regions for given spu window.
* Returns GL_TRUE if regions changed since last call, GL_FALSE overwise.
*/
GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
{
static GLboolean bExtensionsChecked = GL_FALSE;
XserverRegion xreg;
int cRects, i;
XRectangle *pXRects;
GLint* pGLRects;
if (bExtensionsChecked || stubCheckXExtensions(pWindow))
{
bExtensionsChecked = GL_TRUE;
}
else
{
stub.trackWindowVisibleRgn = 0;
return GL_FALSE;
}
/*@todo see comment regarding size/position updates and XSync, same applies to those functions but
* it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension.
*/
xreg = XCompositeCreateRegionFromBorderClip(pWindow->dpy, pWindow->drawable);
pXRects = XFixesFetchRegion(pWindow->dpy, xreg, &cRects);
XFixesDestroyRegion(pWindow->dpy, xreg);
/* @todo For some odd reason *first* run of compiz on freshly booted VM gives us 0 cRects all the time.
* In (!pWindow->pVisibleRegions && cRects) "&& cRects" is a workaround for that case, especially as this
* information is useless for full screen composing managers anyway.
*/
if ((!pWindow->pVisibleRegions && cRects)
|| pWindow->cVisibleRegions!=cRects
|| (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle))))
{
pWindow->pVisibleRegions = pXRects;
pWindow->cVisibleRegions = cRects;
pGLRects = crAlloc(4*cRects*sizeof(GLint));
if (!pGLRects)
{
crWarning("stubUpdateWindowVisibileRegions: failed to allocate %i bytes", 4*cRects*sizeof(GLint));
return GL_FALSE;
}
//crDebug("Got %i rects.", cRects);
for (i=0; i<cRects; ++i)
{
pGLRects[4*i+0] = pXRects[i].x;
pGLRects[4*i+1] = pXRects[i].y;
pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width;
pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height;
//crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]);
}
crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects);
stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects);
crFree(pGLRects);
return GL_TRUE;
}
else
{
XFree(pXRects);
}
return GL_FALSE;
}
#endif //#ifdef WINDOWS