Example #1
0
DEFINE_CONSTRUCTOR() {

	JL_ASSERT_CONSTRUCTING();
	JL_DEFINE_CONSTRUCTOR_OBJ;

//	JSClass *test = JL_GetClass(obj);
	HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
	JL_ASSERT( hInst != NULL, "Unable to GetModuleHandle." );

	// hCursor doc: To use a predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the cursor values.
	WNDCLASS wc = { CS_HREDRAW | CS_VREDRAW | CS_OWNDC, (WNDPROC)WndProc, 0, 0, hInst, LoadIcon((HINSTANCE)NULL, IDI_APPLICATION), LoadCursor((HINSTANCE) NULL, IDC_ARROW), NULL, NULL, WINDOW_CLASS_NAME };
	ATOM rc = RegisterClass(&wc);
	JL_ASSERT( rc != 0, "Unable to RegisterClass." );

// http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=01
//	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);

	HWND hWnd = CreateWindow( (LPSTR)rc, NULL, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, hInst, (LPVOID)NULL);
	JL_ASSERT( hWnd != NULL, "Unable to CreateWindow." );

	CxObj *cxobj = (CxObj*)jl_malloc(sizeof(CxObj));
	JL_ASSERT_ALLOC( cxobj );
	cxobj->cx = cx;
	cxobj->obj = obj;

	DWORD err;
	JL_SAFE(SetLastError(0));
	LONG prevWindowLong = SetWindowLong(hWnd, GWL_USERDATA, (LONG)cxobj );
	JL_ASSERT( prevWindowLong != 0 || (err=GetLastError()) == 0, "Unable to SetWindowLong. (error %d)", err );

	JL_SetPrivate(obj, hWnd);
	return true;
}
Example #2
0
bool32 runNormalizationTest(int32 numVectors, float32 scalarMin, float32 scalarMax) {
	JL_ASSERT(numVectors > 0); JL_ASSERT(scalarMin <= scalarMax);
	jlVector4 *arr = generateRandomVectors(numVectors, scalarMin, scalarMax);
	if (!arr) return 0;
	normalizeVectors(arr, numVectors);
	delete [] arr;
	return 1;
}
Example #3
0
// The Effects of Double Buffering on Animation Frame Rates
//		http://www.futuretech.blinkenlights.nl/dbuffer.html
bool _SwapBuffers(JSContext *cx, JSObject *obj, unsigned argc, jsval *argv, jsval *rval) {

//	glFlush();
//	glFinish();
//	JL_ASSERT( JL_GetClass(obj) == _class, RT_ERROR_INVALID_CLASS );
	HDC hDC = wglGetCurrentDC(); // (TBD) un-specialize from OpenGL
	JL_ASSERT( hDC != NULL, "Could not get the Current Device Context." );
	BOOL res = SwapBuffers(hDC); // Doc: With multithread applications, flush the drawing commands in any other threads drawing to the same window before calling SwapBuffers.
	JL_ASSERT( res, "Unable to SwapBuffers.(%x)", GetLastError() );
	return true;
}
Example #4
0
jlMatrix4 * generateRandomMatrices(int32 numMatrices, float32 scalarMin, float32 scalarMax) {
	JL_ASSERT(numMatrices > 0);
	jlMatrix4 *matrices = new jlMatrix4[numMatrices];
	if (matrices) {
		jlRandom random;
		random.init(numMatrices);
		random.seed(jlRandom::DEFAULT_SEED);
		for (int32 i = 0; i < numMatrices; ++i) {
			float32 m00, m01, m02, m03;
			float32 m10, m11, m12, m13;
			float32 m20, m21, m22, m23;
			float32 m30, m31, m32, m33;
			m00 = random.randFloat32(scalarMin, scalarMax);
			m01 = random.randFloat32(scalarMin, scalarMax);
			m02 = random.randFloat32(scalarMin, scalarMax);
			m03 = random.randFloat32(scalarMin, scalarMax);
			m10 = random.randFloat32(scalarMin, scalarMax);
			m11 = random.randFloat32(scalarMin, scalarMax);
			m12 = random.randFloat32(scalarMin, scalarMax);
			m13 = random.randFloat32(scalarMin, scalarMax);
			m20 = random.randFloat32(scalarMin, scalarMax);
			m21 = random.randFloat32(scalarMin, scalarMax);
			m22 = random.randFloat32(scalarMin, scalarMax);
			m23 = random.randFloat32(scalarMin, scalarMax);
			m30 = random.randFloat32(scalarMin, scalarMax);
			m31 = random.randFloat32(scalarMin, scalarMax);
			m32 = random.randFloat32(scalarMin, scalarMax);
			m33 = random.randFloat32(scalarMin, scalarMax);
			matrices[i] = jlMatrix4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
		}
	}
	return matrices;
}
Example #5
0
/**doc
$TOC_MEMBER $INAME
 $INAME( world, [ jointGroup ] )
  TBD
**/
DEFINE_CONSTRUCTOR() {

	ode::dJointID jointId = NULL;

	JL_ASSERT_ARGC_RANGE(1,2);
	JL_ASSERT_CONSTRUCTING();
	JL_DEFINE_CONSTRUCTOR_OBJ;

	ode::dJointGroupID groupId;
	if ( JL_ARG_ISDEF(2) ) {

		JL_ASSERT_ARG_IS_OBJECT(2);
		JL_ASSERT_INSTANCE( &JL_ARG(2).toObject(), JL_CLASS(JointGroup) );
		groupId = (ode::dJointGroupID)JL_GetPrivate(&JL_ARG(2).toObject());
	} else {

		groupId = 0;
	}

	ode::dWorldID worldId;
	JL_CHK( JL_JsvalToWorldID( cx, JL_ARG(1), &worldId) );
	jointId = ode::dJointCreatePiston(worldId, groupId); // The joint group ID is 0 to allocate the joint normally.
	JL_ASSERT( jointId, E_STR(JL_THIS_CLASS_NAME), E_CREATE );

	ode::dJointSetData(jointId, obj);
	ode::dJointSetFeedback(jointId, NULL);
	
	JL_SetPrivate(obj, jointId);
	return true;

bad:
	if ( jointId )
		ode::dJointDestroy(jointId);
	return false;
}
Example #6
0
/**doc
$TOC_MEMBER $INAME
 $INAME( [ space ] )
  TBD
**/
DEFINE_CONSTRUCTOR() {

	ode::dGeomID geomId = NULL;

	JL_ASSERT_ARGC_RANGE(0, 1);
	JL_ASSERT_CONSTRUCTING();
	JL_DEFINE_CONSTRUCTOR_OBJ;

	ode::dSpaceID space;
	if ( JL_ARG_ISDEF(1) ) { // place it in a space ?

		JL_CHK( JL_JsvalToSpaceID(cx, JL_ARG(1), &space) );
		JL_CHK( JL_SetReservedSlot( obj, SLOT_GEOM_SPACEOBJECT, JL_ARG(1)) );
	} else {

		space = 0;
	}
	geomId = ode::dCreatePlane(space, 0,0,1,0); // default lengths are 1
	JL_ASSERT( geomId, E_STR(JL_THIS_CLASS_NAME), E_CREATE );

	JL_CHK( SetupReadMatrix(cx, obj) );
	ode::dGeomSetData(geomId, obj); // 'obj' do not need to be rooted because Goem's data is reset to NULL when 'obj' is finalized.

	JL_SetPrivate(obj, geomId);
	return true;

bad:
	if ( geomId )
		ode::dGeomDestroy(geomId);
	return false;
}
Example #7
0
bool ReconstructBody(JSContext *cx, ode::dBodyID bodyId, JSObject **obj) { // (TBD) JSObject** = Conservative Stack Scanning issue ?

	if (unlikely( bodyId == (ode::dBodyID)0 )) { // bodyId may be null if body is world.env

		*obj = jl::newObjectWithGivenProto(cx, JL_CLASS(Body), JL_CLASS_PROTOTYPE(cx, Body));
		JL_CHK( *obj );
	} else {

		//JL_ASSERT( ode::dBodyGetData(bodyId) == NULL, "Invalid case (object not finalized)." );
		JL_ASSERT( ode::dBodyGetData(bodyId) == NULL, E_MODULE, E_INTERNAL, E_SEP, E_STR(JL_CLASS_NAME(Body)), E_STATE, E_INVALID );

		*obj = jl::newObjectWithGivenProto(cx, JL_CLASS(Body), JL_CLASS_PROTOTYPE(cx, Body), NULL);
		JL_CHK( *obj );
//		BodyPrivate *bodypv = (BodyPrivate*)jl_malloc(sizeof(BodyPrivate));
//		JL_ASSERT_ALLOC( bodypv );
//		bodypv->obj = *obj;
//		ode::dBodySetData(bodyId, bodypv);
		ode::dBodySetData(bodyId, *obj);
	}

	JL_CHK( SetMatrix44GetInterface(cx, *obj, BodyReadMatrix) );
	JL_SetPrivate( *obj, bodyId);
	return true;
	JL_BAD;
}
Example #8
0
DEFINE_CONSTRUCTOR() {

	ode::dBodyID bodyId = NULL;

	JL_ASSERT_ARGC_MIN(1);
	JL_ASSERT_CONSTRUCTING();
	JL_DEFINE_CONSTRUCTOR_OBJ;

	ode::dWorldID worldId;
	JL_CHK( JL_JsvalToWorldID(cx, JL_ARG(1), &worldId) );

//	BodyPrivate *bodypv = (BodyPrivate*)jl_malloc(sizeof(BodyPrivate));
//	JL_ASSERT_ALLOC( bodypv );
//	bodypv->obj

	bodyId = ode::dBodyCreate(worldId);
	JL_ASSERT( bodyId != NULL, E_LIB, E_NAME("ODE"), E_SEP, E_STR(JL_THIS_CLASS_NAME), E_CREATE );
	
	JL_CHK( SetMatrix44GetInterface(cx, obj, BodyReadMatrix) );
	ode::dBodySetData(bodyId, obj);

	S_ASSERT( sizeof(bodyId) == sizeof(void*) );
	JL_SetPrivate(obj, bodyId);
	return true;
bad:
	if ( bodyId )
		ode::dBodyDestroy(bodyId);
	return false;
}
Example #9
0
void jl::PreallocatedObjectPool::Init( void* pBuffer, unsigned nCapacity, unsigned nStride, unsigned nFlags /*= eFlag_Default */ )
{
    JL_ASSERT( m_pObjectBuffer == NULL );

    m_pObjectBuffer = (unsigned char*)pBuffer;
    m_pFreeListHead = ObjectPool::InitFreeList( m_pObjectBuffer, nCapacity, nStride );

    m_nCapacity = nCapacity;
    m_nStride = nStride;
    m_nFlags = nFlags;
}
Example #10
0
/**doc
$TOC_MEMBER $INAME
 $INAME( filename )
  Constructs a new inflater or deflater object.
  $H example
  {{{
  var f = new ZipFile('test.zip');
  f.open(ZipFile.CREATE);
  f.select('file1.txt');
  f.write('data1');
  f.close();
  }}}
**/
DEFINE_CONSTRUCTOR() {

	Private *pv = NULL;

	JL_DEFINE_ARGS;

	JL_ASSERT_CONSTRUCTING();
	JL_ASSERT_ARGC(1);
	JL_DEFINE_CONSTRUCTOR_OBJ;
	
	//JL_CHK( JL_SetReservedSlot(JL_OBJ, SLOT_FILENAME, JL_ARG(1)) );
	JL_CHK( jl::setSlot(cx, JL_OBJ, SLOT_FILENAME, JL_ARG(1)) );

	pv = (Private*)jl_calloc(sizeof(Private), 1);
	JL_ASSERT_ALLOC(pv);
	pv->uf = NULL;
	pv->zf = NULL;

	JL_updateMallocCounter(cx, sizeof(Private));
	JL_ASSERT( !pv->uf && !pv->zf );
	JL_ASSERT( !pv->inZipOpened );

	//JL_CHK( ReserveStreamReadInterface(cx, obj) );
	JL_CHK( jl::setStreamReadInterface(cx, JL_OBJ, NativeInterfaceStreamRead) );

	JL_SetPrivate(JL_OBJ, pv);
	return true;

bad:
	if ( pv ) {

		if ( pv->zf )
			zipClose(pv->zf, NULL);
		if ( pv->uf )
			unzClose(pv->uf);
		jl_free(pv);
	}
	return false;
}
Example #11
0
/* BEGIN RANDOM GENERATION FUNCTIONS */
jlVector4 * generateRandomVectors(int32 numVectors, float32 scalarMin, float32 scalarMax) {
	JL_ASSERT(numVectors > 0);
	jlVector4 *vectors = new jlVector4[numVectors];
	if (vectors) {
		jlRandom random;
		random.init(numVectors);
		random.seed(jlRandom::DEFAULT_SEED);
		for (int32 i = 0; i < numVectors; i++) {
			float32 x = random.randFloat32(scalarMin, scalarMax);
			float32 y = random.randFloat32(scalarMin, scalarMax);
			float32 z = random.randFloat32(scalarMin, scalarMax);
			//float32 w = random.randFloat32(scalarMin, scalarMax);
			vectors[i].set(x, y, z, 0.0f);
		}
	}
	return vectors;
}
Example #12
0
bool
ModuleInit( JSContext *cx, JS::HandleObject obj ) {

	JLDisableThreadNotifications();

	JL_ASSERT( jl::Host::getJLHost(cx)->checkCompatId( JL_HOST_VERSIONID ), E_MODULE, E_NOTCOMPATIBLE, E_HOST );

//	JL_ASSERT( vi == NULL, E_LIB, E_STR("videoinput"), E_INIT ); // "Invalid case: videoInput already initialized'"


	videoInput::setVerbose(false);
	videoInput *vi = new videoInput();
	JL_ASSERT_ALLOC( vi );
	jl::Host::getJLHost(cx)->moduleManager().modulePrivateT<videoInput*>( moduleId() ) = vi;

		
	struct ReleaseModule : jl::Callback {
		jl::HostRuntime &_hostRuntime;
		videoInput *_vi;
	
		ReleaseModule(jl::HostRuntime &hostRuntime, videoInput *vi)
		: _hostRuntime(hostRuntime), _vi(vi) {
		}

		bool operator()( EventType &ev ) {
		
			ASSERT( _hostRuntime );
			if ( _hostRuntime.skipCleanup() )
				return true;

			if ( _vi != NULL )
				delete _vi;

			return true;
		}
	};

	jl::HostRuntime &hostRuntime = jl::HostRuntime::getJLRuntime(cx);
	hostRuntime.addListener(jl::EventId::AFTER_DESTROY_RUNTIME, new ReleaseModule(hostRuntime, vi)); // frees mpv after rt and cx has been destroyed


	INIT_CLASS( VideoInput );

	return true;
	JL_BAD;
}
Example #13
0
bool SlotGetPrng(JSContext *cx, JS::HandleObject obj, int *prngIndex, prng_state **prngState) {

	JS::RootedValue prngVal(cx);
	JL_CHK( JL_GetReservedSlot( obj, ASYMMETRIC_CIPHER_PRNG_SLOT, &prngVal) );
	JL_ASSERT_OBJECT_STATE( prngVal.isObject(), JL_CLASS_NAME(Prng) );
	{
	JS::RootedObject prngObj(cx, &prngVal.toObject());
	JL_ASSERT_INSTANCE( prngObj, JL_CLASS(Prng) );
	PrngPrivate *prngPrivate;
	prngPrivate = (PrngPrivate *)JL_GetPrivate(prngObj);
	JL_ASSERT_OBJECT_STATE( prngPrivate, JL_CLASS_NAME(Prng) );
	*prngState = &prngPrivate->state;
	*prngIndex = find_prng(prngPrivate->prng.name);
	JL_ASSERT( *prngIndex != -1, E_STR("PRNG"), E_NAME(prngPrivate->prng.name), E_NOTFOUND );
	
	}

	return true;
	JL_BAD;
}
Example #14
0
bool DoStep(JSContext *cx, JS::HandleObject obj, JS::MutableHandleValue rval) {

	sqlite3_stmt *pStmt = (sqlite3_stmt*)JL_GetPrivate(obj);
	JL_ASSERT_THIS_OBJECT_STATE( pStmt );

	DatabasePrivate *dbpv;
	{

	JS::RootedValue dbVal(cx);
	JL_CHK( JL_GetReservedSlot(obj, SLOT_RESULT_DATABASE, &dbVal) );
	JL_ASSERT( dbVal.isObject() );


	JS::RootedObject dbValObj(cx, &dbVal.toObject());

	dbpv = (DatabasePrivate*)JL_GetPrivate(dbValObj);
	JL_ASSERT_OBJECT_STATE(dbpv, JL_GetClassName(dbValObj));

	}

	sqlite3 *db;
	db = dbpv->db;
	ASSERT( db == sqlite3_db_handle(pStmt) );

	{

	// check if bindings are up to date
	JS::RootedValue bindingUpToDate(cx);
	JL_CHK( JL_GetReservedSlot(obj, SLOT_RESULT_BINDING_UP_TO_DATE, &bindingUpToDate) );

	if ( bindingUpToDate != JSVAL_TRUE ) {

		JS::RootedValue queryArgument(cx);
		JS::RootedObject queryArgumentObj(cx);
		JL_CHK(jl::getSlot(cx, obj, SLOT_RESULT_QUERY_ARGUMENT_OBJECT, &queryArgumentObj));



		JL_CHK(SqliteSetupBindings(cx, pStmt, queryArgumentObj, obj)); // ":" use result object. "@" is the object passed to Query()
		JL_CHK( JL_SetReservedSlot(obj, SLOT_RESULT_BINDING_UP_TO_DATE, JL_TRUE) );
		// doc: The sqlite3_bind_*() routines must be called AFTER sqlite3_prepare() or sqlite3_reset() and BEFORE sqlite3_step().
		//      Bindings are not cleared by the sqlite3_reset() routine. Unbound parameters are interpreted as NULL.
	}

	}

	dbpv->tmpcx = cx;
	int status;
	status = sqlite3_step( pStmt ); // The return value will be either SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
	dbpv->tmpcx = NULL;
	
	JL_CHK( !JL_IsExceptionPending(cx) );

	switch ( status ) {

		case SQLITE_ROW: // SQLITE_ROW is returned each time a new row of data is ready for processing by the caller
			rval.setBoolean(true);
			return true;
		case SQLITE_DONE: // means that the statement has finished executing successfully. sqlite3_step() should not be called again on this virtual machine without first calling sqlite3_reset() to reset the virtual machine back to its initial state.
			rval.setBoolean(false);
			return true;
		case SQLITE_MISUSE:
			// doc. means that the this routine was called inappropriately. Perhaps it was called on a virtual machine that had already been finalized or on one that had previously returned SQLITE_ERROR or SQLITE_DONE.
			//      Or it could be the case that a database connection is being used by a different thread than the one it was created it.
			// doc. If an interface fails with SQLITE_MISUSE, that means the interface was invoked incorrectly by the application. In that case, the error code and message may or may not be set.
			JL_CHK( SqliteThrowError(cx, db) );
//		case SQLITE_ERROR:
//		case SQLITE_SCHEMA: // (TBD) check for another error (doc. The database schema changed)
//			JL_CHK( SqliteThrowError(cx, db) );
	}
//	JL_REPORT_ERROR("invalid case (status:%d)", status );

	JL_CHK( SqliteThrowError(cx, db) );
	JL_BAD;
}
Example #15
0
/* NORMALIZATION/MATRIX MULTIPLY TEST */
void normalizeVectors(jlVector4 *ptr, int32 n) {
	JL_ASSERT(ptr != NULL && n > 0);
	for (int i = 0; i < n; i++) {
		ptr[i].normalize3();
	}
}
Example #16
0
LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

	CxObj *cxobj = (CxObj*)GetWindowLong(hWnd, GWL_USERDATA);
	if ( cxobj == NULL )
		return DefWindowProc(hWnd, message, wParam, lParam);

	JSContext *cx = cxobj->cx;
	JS::RootedObject obj(cx, cxobj->obj);

	jsval rval;
	jsval functionVal;

	LRESULT returnValue = 0;

	switch (message) {

		//case WM_COMMAND:
		//case WM_PAINT

		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		case WM_CHAR:
			JS_GetProperty(cx, obj, "onchar", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				char c = wParam;
				jsval argv[] = { STRING_TO_JSVAL(JS_NewStringCopyN(cx, &c, 1)), INT_TO_JSVAL(lParam) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // needed to protect the new string
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_KEYUP:
			JS_GetProperty(cx, obj, "onkeyup", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL(wParam), INT_TO_JSVAL(lParam) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_KEYDOWN:
			JS_GetProperty(cx, obj, "onkeydown", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL(wParam), INT_TO_JSVAL(lParam) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_ACTIVATE:
			JS_GetProperty(cx, obj, "onactivate", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { BOOLEAN_TO_JSVAL(wParam != WA_INACTIVE) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
//		case WM_SIZING:
		case WM_SIZE:
			JS_GetProperty(cx, obj, "onsize", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL((short)LOWORD(lParam)), INT_TO_JSVAL((short)HIWORD(lParam)) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_MOUSEMOVE:
			JS_GetProperty(cx, obj, "onmousemove", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL(MAKEPOINTS(lParam).x), INT_TO_JSVAL(MAKEPOINTS(lParam).y), BOOLEAN_TO_JSVAL(wParam & MK_LBUTTON), BOOLEAN_TO_JSVAL(wParam & MK_RBUTTON), BOOLEAN_TO_JSVAL(wParam & MK_MBUTTON) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_MOUSEWHEEL:
			JS_GetProperty(cx, obj, "onmousewheel", &functionVal);
			if ( !functionVal.isUndefined() ) {

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL( GET_WHEEL_DELTA_WPARAM(wParam)/WHEEL_DELTA ), BOOLEAN_TO_JSVAL(wParam & MK_LBUTTON), BOOLEAN_TO_JSVAL(wParam & MK_RBUTTON), BOOLEAN_TO_JSVAL(wParam & MK_MBUTTON) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_LBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_RBUTTONDOWN:
			JS_GetProperty(cx, obj, "onmousedown", &functionVal);
			if ( !functionVal.isUndefined() ) {

				// xPos = GET_X_LPARAM(lParam);
				// yPos = GET_Y_LPARAM(lParam);

				JL_ASSERT_FUNCTION(functionVal); // (TBD) return value of assert is not compatible with this function (WndProc)
				jsval argv[] = { INT_TO_JSVAL( message==WM_LBUTTONDOWN ? 1 : message==WM_RBUTTONDOWN ? 2 : message==WM_MBUTTONDOWN ? 3 : 0 ), JSVAL_TRUE };
//					BOOLEAN_TO_JSVAL(wParam & MK_LBUTTON),
//					BOOLEAN_TO_JSVAL(wParam & MK_RBUTTON),
//					BOOLEAN_TO_JSVAL(wParam & MK_MBUTTON) };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;
		case WM_LBUTTONUP:
		case WM_MBUTTONUP:
		case WM_RBUTTONUP:
			JS_GetProperty(cx, obj, "onmouseup", &functionVal);
			if ( !functionVal.isUndefined() ) {

				// xPos = GET_X_LPARAM(lParam);
				// yPos = GET_Y_LPARAM(lParam);

				JL_ASSERT( JS_TypeOfValue( cx, functionVal ) == JSTYPE_FUNCTION, "Need a function." );
				jsval argv[] = { INT_TO_JSVAL( message==WM_LBUTTONUP ? 1 : message==WM_RBUTTONUP ? 2 : message==WM_MBUTTONUP ? 3 : 0 ), JSVAL_FALSE };
				JSTempValueRooter tvr;
				JS_PUSH_TEMP_ROOT(cx, COUNTOF(argv), argv, &tvr); // not really needed
				bool status = JS_CallFunctionValue(cx, obj, functionVal, COUNTOF(argv), argv, &rval);
				JS_POP_TEMP_ROOT(cx, &tvr);
				JL_CHK( status );
				return 0;
			}
			break;

		//case WM_MOUSELEAVE: // need TrackMouseEvent() ...
		//	JS_GetProperty(cx, obj, "onmouseleave", &functionVal);
		//	if ( !JSVAL_IS_VOID( functionVal ) ) {

		//		JS_CallFunctionValue(cx, obj, functionVal, 0, NULL, &rval);
		//	}
		//	break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam); // We do not want to handle this message so pass back to Windows to handle it in a default way
}