Fixed by updating indra/cmake/WebKitLibPlugin.cmake with version from imprudence. This commit also contains removal of execute permissions of source files and configure files, sorry...
512 lines
14 KiB
C++
512 lines
14 KiB
C++
/**
|
|
* @file demo_plugin.cpp
|
|
* @brief Test plugin to be loaded by the llplugin testbed.
|
|
*
|
|
* $LicenseInfo:firstyear=2008&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2008-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "linden_common.h"
|
|
#include "indra_constants.h"
|
|
|
|
#include "lltimer.h" // for ms_sleep()
|
|
#include "llpumpio.h"
|
|
#include "llapr.h"
|
|
#include "llerrorcontrol.h"
|
|
#include "llpluginclassmedia.h"
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#include "llmediaplugintest.h" // for GLUT headers
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
class mediaPluginTest : public LLPluginClassMediaOwner
|
|
{
|
|
private:
|
|
int mAppWindowWidth;
|
|
int mAppWindowHeight;
|
|
LLPluginClassMedia* mMediaSource;
|
|
int mAppTextureWidth;
|
|
int mAppTextureHeight;
|
|
bool mAppTextureCoordsOpenGL;
|
|
GLuint mAppTexture;
|
|
std::string mAppWindowName;
|
|
std::string mHomeUrl;
|
|
std::string mLauncherFilename;
|
|
std::string mPluginFilename;
|
|
|
|
LLPluginClassMedia *mPlugin;
|
|
|
|
public:
|
|
mediaPluginTest(const std::string &launcher_filename, const std::string &plugin_filename) :
|
|
mAppWindowWidth( 800 ),
|
|
mAppWindowHeight( 600 ),
|
|
mAppTextureWidth( 0 ),
|
|
mAppTextureHeight( 0 ),
|
|
mAppTextureCoordsOpenGL(false),
|
|
mAppTexture( 0 ),
|
|
mAppWindowName( "Media Simple Test" ),
|
|
mHomeUrl( "" )
|
|
{
|
|
mLauncherFilename = launcher_filename;
|
|
mMediaSource = new LLPluginClassMedia(this);
|
|
mMediaSource->init(launcher_filename, plugin_filename);
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
virtual ~mediaPluginTest()
|
|
{
|
|
delete mMediaSource;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void createTexture()
|
|
{
|
|
// create the texture used to display the browser data
|
|
if(mMediaSource->textureValid())
|
|
{
|
|
mAppTextureWidth = mMediaSource->getTextureWidth();
|
|
mAppTextureHeight = mMediaSource->getTextureHeight();
|
|
mAppTextureCoordsOpenGL = mMediaSource->getTextureCoordsOpenGL();
|
|
|
|
if(mAppTexture != 0)
|
|
{
|
|
glDeleteTextures( 1, &mAppTexture );
|
|
mAppTexture = 0;
|
|
}
|
|
|
|
glGenTextures( 1, &mAppTexture );
|
|
glBindTexture( GL_TEXTURE_2D, mAppTexture );
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
|
glTexImage2D( GL_TEXTURE_2D, 0,
|
|
mMediaSource->getTextureFormatInternal(),
|
|
mAppTextureWidth,
|
|
mAppTextureHeight,
|
|
0,
|
|
mMediaSource->getTextureFormatPrimary(),
|
|
mMediaSource->getTextureFormatType(),
|
|
NULL );
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void initGL()
|
|
{
|
|
// OpenGL initialization
|
|
glClearColor( 0.0f, 0.0f, 0.0f, 0.5f);
|
|
glEnable( GL_COLOR_MATERIAL );
|
|
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
|
|
glEnable( GL_TEXTURE_2D );
|
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
|
glEnable( GL_CULL_FACE );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void reshape( int width, int height )
|
|
{
|
|
if ( height == 0 )
|
|
height = 1;
|
|
|
|
glMatrixMode( GL_PROJECTION );
|
|
glLoadIdentity();
|
|
|
|
glViewport( 0, 0, width, height );
|
|
glOrtho( 0.0f, width, height, 0.0f, -1.0f, 1.0f );
|
|
|
|
// we use these values elsewhere so save
|
|
mAppWindowWidth = width;
|
|
mAppWindowHeight = height;
|
|
|
|
// Request a media size change
|
|
mMediaSource->setSize(width, height);
|
|
|
|
glMatrixMode( GL_MODELVIEW );
|
|
glLoadIdentity();
|
|
|
|
glutPostRedisplay();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void idle()
|
|
{
|
|
// lots of updates for smooth motion
|
|
glutPostRedisplay();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void display()
|
|
{
|
|
mMediaSource->idle();
|
|
|
|
// Check whether the texture needs to be recreated.
|
|
if(mMediaSource->textureValid())
|
|
{
|
|
if(
|
|
(mAppTextureWidth != mMediaSource->getTextureWidth() || mAppTextureHeight != mMediaSource->getTextureHeight()) &&
|
|
(mAppWindowWidth == mMediaSource->getWidth() && mAppWindowHeight == mMediaSource->getHeight())
|
|
)
|
|
{
|
|
// Attempt to (re)create the texture
|
|
createTexture();
|
|
}
|
|
}
|
|
|
|
// clear screen
|
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
|
|
|
glLoadIdentity();
|
|
|
|
if(mAppTexture != 0)
|
|
{
|
|
// use the browser texture
|
|
glBindTexture( GL_TEXTURE_2D, mAppTexture );
|
|
|
|
// If dirty, update the texture.
|
|
LLRect dirtyRect;
|
|
if(!mMediaSource->textureValid())
|
|
{
|
|
// LL_DEBUGS("media_plugin_test") << "Resize in progress, skipping update..." << LL_ENDL;
|
|
}
|
|
else if(mAppWindowWidth != mMediaSource->getWidth() || mAppWindowHeight != mMediaSource->getHeight())
|
|
{
|
|
// A resize is in progress. Just wait for it...
|
|
}
|
|
else if(mMediaSource->getDirty(&dirtyRect))
|
|
{
|
|
// grab the page
|
|
const unsigned char* pixels = mMediaSource->getBitsData();
|
|
if ( pixels )
|
|
{
|
|
// write them into the texture
|
|
|
|
// Paranoia: intersect dirtyRect with (0, 0, mAppTextureWidth, mAppTextureHeight)?
|
|
|
|
int x_offset = dirtyRect.mLeft;
|
|
int y_offset = dirtyRect.mBottom;
|
|
int width = dirtyRect.mRight - dirtyRect.mLeft;
|
|
int height = dirtyRect.mTop - dirtyRect.mBottom;
|
|
|
|
LL_DEBUGS("media_plugin_test") << "Updating, dirty rect is ("
|
|
<< dirtyRect.mLeft << ", "
|
|
<< dirtyRect.mTop << ", "
|
|
<< dirtyRect.mRight << ", "
|
|
<< dirtyRect.mBottom << "), update params are: ("
|
|
<< x_offset << ", "
|
|
<< y_offset << ", "
|
|
<< width << ", "
|
|
<< height << ")"
|
|
<< LL_ENDL;
|
|
|
|
// Offset the pixels pointer properly
|
|
pixels += (y_offset * mMediaSource->getTextureDepth() * mMediaSource->getTextureWidth());
|
|
pixels += (x_offset * mMediaSource->getTextureDepth());
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, mMediaSource->getTextureWidth());
|
|
|
|
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
|
x_offset,
|
|
y_offset,
|
|
width,
|
|
height,
|
|
mMediaSource->getTextureFormatPrimary(),
|
|
mMediaSource->getTextureFormatType(),
|
|
pixels );
|
|
|
|
mMediaSource->resetDirty();
|
|
}
|
|
}
|
|
|
|
// scale the texture so that it fits the screen
|
|
GLdouble media_texture_x = mAppWindowWidth / (double)mAppTextureWidth;
|
|
GLdouble media_texture_y = mAppWindowHeight / (double)mAppTextureHeight;
|
|
|
|
// draw the single quad full screen (orthographic)
|
|
|
|
glEnable( GL_TEXTURE_2D );
|
|
glColor3f( 1.0f, 1.0f, 1.0f );
|
|
glBegin( GL_QUADS );
|
|
if(mAppTextureCoordsOpenGL)
|
|
{
|
|
// Render the texture as per opengl coords (where 0,0 is at the lower left)
|
|
glTexCoord2d( 0, 0 );
|
|
glVertex2d( 0, 0 );
|
|
|
|
glTexCoord2d( 0 , media_texture_y );
|
|
glVertex2d( 0, mAppWindowHeight);
|
|
|
|
glTexCoord2d( media_texture_x, media_texture_y );
|
|
glVertex2d( mAppWindowWidth , mAppWindowHeight);
|
|
|
|
glTexCoord2d( media_texture_x, 0 );
|
|
glVertex2d( mAppWindowWidth, 0 );
|
|
}
|
|
else
|
|
{
|
|
// Render the texture the "other way round" (where 0,0 is at the upper left)
|
|
glTexCoord2d( 0, media_texture_y );
|
|
glVertex2d( 0, 0 );
|
|
|
|
glTexCoord2d( 0 , 0 );
|
|
glVertex2d( 0, mAppWindowHeight);
|
|
|
|
glTexCoord2d( media_texture_x, 0 );
|
|
glVertex2d( mAppWindowWidth , mAppWindowHeight);
|
|
|
|
glTexCoord2d( media_texture_x, media_texture_y );
|
|
glVertex2d( mAppWindowWidth, 0 );
|
|
}
|
|
glEnd();
|
|
|
|
}
|
|
|
|
glutSwapBuffers();
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
MASK getModifiers(void)
|
|
{
|
|
MASK result = 0;
|
|
|
|
int modifiers = glutGetModifiers();
|
|
|
|
if(modifiers & GLUT_ACTIVE_SHIFT)
|
|
result |= MASK_SHIFT;
|
|
if(modifiers & GLUT_ACTIVE_CTRL)
|
|
result |= MASK_CONTROL;
|
|
if(modifiers & GLUT_ACTIVE_ALT)
|
|
result |= MASK_ALT;
|
|
|
|
return result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void mouseButton( int button, int state, int x, int y )
|
|
{
|
|
// Texture has been scaled so it's 1:1 with screen pixels, so no need to scale mouse coords here.
|
|
// x = ( x * mAppTextureWidth ) / mAppWindowWidth;
|
|
// y = ( y * mAppTextureHeight ) / mAppWindowHeight;
|
|
|
|
if ( button == GLUT_LEFT_BUTTON )
|
|
{
|
|
if ( state == GLUT_DOWN )
|
|
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, x, y, getModifiers());
|
|
else if ( state == GLUT_UP )
|
|
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, x, y, getModifiers());
|
|
}
|
|
|
|
// force a GLUT update
|
|
glutPostRedisplay();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void mouseMove( int x , int y )
|
|
{
|
|
// Texture has been scaled so it's 1:1 with screen pixels, so no need to scale mouse coords here.
|
|
// x = ( x * mAppTextureWidth ) / mAppWindowWidth;
|
|
// y = ( y * mAppTextureHeight ) / mAppWindowHeight;
|
|
|
|
// GLUT complains if I get the keyboard modifiers here, so just pretend there aren't any.
|
|
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, x, y, 0);
|
|
|
|
// force a GLUT update
|
|
glutPostRedisplay();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void keyboard( unsigned char key )
|
|
{
|
|
mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, getModifiers());
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
int getAppWindowWidth()
|
|
{
|
|
return mAppWindowWidth;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
int getAppWindowHeight()
|
|
{
|
|
return mAppWindowHeight;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
std::string getAppWindowName()
|
|
{
|
|
return mAppWindowName;
|
|
};
|
|
|
|
};
|
|
|
|
mediaPluginTest* gApplication;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutReshape( int width, int height )
|
|
{
|
|
if ( gApplication )
|
|
gApplication->reshape( width, height );
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutDisplay()
|
|
{
|
|
if ( gApplication )
|
|
gApplication->display();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutIdle()
|
|
{
|
|
if ( gApplication )
|
|
gApplication->idle();
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutKeyboard( unsigned char key, int x, int y )
|
|
{
|
|
if ( key == 27 )
|
|
{
|
|
delete gApplication;
|
|
exit( 0 );
|
|
};
|
|
|
|
if ( gApplication )
|
|
gApplication->keyboard( key );
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutMouseMove( int x, int y )
|
|
{
|
|
if ( gApplication )
|
|
gApplication->mouseMove( x, y );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
void glutMouseButton( int button, int state, int x, int y )
|
|
{
|
|
if ( gApplication )
|
|
gApplication->mouseButton( button, state, x, y );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
|
|
ll_init_apr();
|
|
|
|
// Set up llerror logging
|
|
{
|
|
LLError::initForApplication(".");
|
|
LLError::setDefaultLevel(LLError::LEVEL_INFO);
|
|
}
|
|
|
|
std::string launcher_name;
|
|
std::string plugin_name;
|
|
|
|
if(argc >= 3)
|
|
{
|
|
launcher_name = argv[1];
|
|
plugin_name = argv[2];
|
|
}
|
|
else
|
|
{
|
|
#if LL_DARWIN
|
|
// hardcoding the testbed arguments by default
|
|
launcher_name = "plugin_process_host";
|
|
plugin_name = "libdemo_media_plugin_quicktime.dylib";
|
|
#elif LL_WINDOWS
|
|
// hardcoding the testbed arguments by default
|
|
launcher_name = "plugin_process_host.exe";
|
|
plugin_name = "demo_media_plugin_quicktime.dll";
|
|
#else
|
|
LL_ERRS("plugin_process_launcher") << "usage: " << argv[0] << " launcher_filename plugin_filename" << LL_ENDL;
|
|
#endif
|
|
}
|
|
|
|
gApplication = new mediaPluginTest(launcher_name, plugin_name);
|
|
|
|
if ( gApplication )
|
|
{
|
|
glutInit( &argc, argv );
|
|
glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
|
|
|
|
glutInitWindowPosition( 80, 0 );
|
|
glutInitWindowSize( gApplication->getAppWindowWidth(), gApplication->getAppWindowHeight() );
|
|
|
|
glutCreateWindow( gApplication->getAppWindowName().c_str() );
|
|
|
|
glutKeyboardFunc( glutKeyboard );
|
|
|
|
glutMouseFunc( glutMouseButton );
|
|
glutPassiveMotionFunc( glutMouseMove );
|
|
glutMotionFunc( glutMouseMove );
|
|
|
|
glutDisplayFunc( glutDisplay );
|
|
glutReshapeFunc( glutReshape );
|
|
|
|
glutIdleFunc( glutIdle );
|
|
|
|
gApplication->initGL();
|
|
|
|
glutMainLoop();
|
|
|
|
delete gApplication;
|
|
};
|
|
|
|
ll_cleanup_apr();
|
|
|
|
return 0;
|
|
}
|
|
|