示例#1
0
文件: win32s.cpp 项目: z4y4/njord
JSBool win32_getlasterror(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
	JS_BeginRequest(cx);
	JSBool retVal = JS_NewNumberValue(cx, GetLastError(), rval);
	JS_EndRequest(cx);
	return retVal;
}
JSBool S_CCApplication::jsgetCurrentLanguage(JSContext *cx, uint32_t argc, jsval *vp) {
    JSObject* obj = (JSObject *)JS_THIS_OBJECT(cx, vp);
    CCApplication* self = NULL; JSGET_PTRSHELL(CCApplication, self, obj);
    if (self == NULL) return JS_FALSE;
    jsval result; JS_NewNumberValue(cx, self->getCurrentLanguage(), &result);
    JS_SET_RVAL(cx, vp, result);
    return JS_TRUE;
}
template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx, const u32& val)
{
	if (val <= JSVAL_INT_MAX)
		return INT_TO_JSVAL(val);
	jsval rval = JSVAL_VOID;
	JS_NewNumberValue(cx, val, &rval); // ignore return value
	return rval;
}
示例#4
0
文件: js_wimg.cpp 项目: z4y4/njord
JSBool wimg_get_image_count(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
    HANDLE wimFile = JS_GetPrivate(cx, obj);
    JS_BeginRequest(cx);
    JSBool retBool = JS_NewNumberValue(cx, WIMGetImageCount(wimFile), rval);
    JS_EndRequest(cx);
    return retBool;
}
JSBool S_SimpleAudioEngine::jsPropertyGet(JSContext *cx, JSObject *obj, jsid _id, jsval *val)
{
	int32_t propId = JSID_TO_INT(_id);
	S_SimpleAudioEngine *cobj; JSGET_PTRSHELL(S_SimpleAudioEngine, cobj, obj);
	if (!cobj) return JS_FALSE;
	switch(propId) {
	case kBackgroundMusicVolume:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->getBackgroundMusicVolume(), &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	case kEffectsVolume:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->getEffectsVolume(), &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	default:
		break;
	}
	return JS_TRUE;
}
JSBool S_AnotherClass::jsPropertyGet(JSContext *cx, JSObject *obj, jsid _id, jsval *val)
{
	int32_t propId = JSID_TO_INT(_id);
	S_AnotherClass *cobj; JSGET_PTRSHELL(S_AnotherClass, cobj, obj);
	if (!cobj) return JS_FALSE;
	switch(propId) {
	case kAPublicField:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->aPublicField, &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	case kJustOneField:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->getJustOneField(), &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	default:
		break;
	}
	return JS_TRUE;
}
示例#7
0
文件: Events.cpp 项目: ds-hwang/d2bs
bool __fastcall ItemEventCallback(Script* script, void* argv, uint argc)
{
	ItemEventHelper* helper = (ItemEventHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("itemaction"))
	{
		AutoRoot** argv = new AutoRoot*[4];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		argv[1] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->id, argv[0]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[1]->value());
		argv[2] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->code)));
		argv[3] = new AutoRoot(BOOLEAN_TO_JSVAL(helper->global));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("itemaction", 4, argv);
	}
	return true;
}
示例#8
0
void ScriptingHost::SetObjectProperty_Double(JSObject* object, const char* propertyName, double value)
{
	jsval v;
	if (! JS_NewNumberValue(m_Context, value, &v))
		throw PSERROR_Scripting_ConversionFailed();

	if (! JS_SetProperty(m_Context, object, propertyName, &v))
		throw PSERROR_Scripting_ConversionFailed();
}
示例#9
0
文件: js_wimg.cpp 项目: z4y4/njord
JSBool wimg_image_count_getter(JSContext * cx, JSObject * obj, jsval idval, jsval * vp)
{
    JS_BeginRequest(cx);
    HANDLE hImage = JS_GetPrivate(cx, obj);
    DWORD imageCount = WIMGetImageCount(hImage);
    JS_NewNumberValue(cx, (jsdouble)imageCount, vp);
    JS_EndRequest(cx);
    return JS_TRUE;
}
示例#10
0
文件: win32s.cpp 项目: z4y4/njord
JSBool win32_setenv(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
	LPWSTR name, value;
	JSBool local = JS_TRUE, addition = JS_TRUE;

	JS_BeginRequest(cx);
	if(!JS_ConvertArguments(cx, argc, argv, "W W /b b", &name, &value, &addition, &local))
	{
		JS_ReportError(cx, "Error parsing arguments in win32_setenv");
		JS_EndRequest(cx);
		return JS_FALSE;
	}

	if(local)
	{
		*rval = SetEnvironmentVariable(name, value) ? JSVAL_TRUE : JSVAL_FALSE;
		JS_EndRequest(cx);
		return JS_TRUE;
	}

	HKEY envKey;
	DWORD type, size, statusCode;
	statusCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"), 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &envKey);
	if(envKey == NULL)
	{
		SetLastError(statusCode);
		*rval = JSVAL_FALSE;
		JS_EndRequest(cx);
		return JS_TRUE;
	}
	if(addition == TRUE && RegQueryValueEx(envKey, name, NULL, &type, NULL, &size) == ERROR_SUCCESS)
	{
		LPWSTR regValue = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + sizeof(WCHAR));
		RegQueryValueEx(envKey, name, NULL, NULL, (LPBYTE)regValue, &size);
		LPWSTR outputValue = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + wcslen(value) + sizeof(WCHAR));
		size = wsprintf(outputValue, TEXT("%s;%s"), regValue, value) + 1;
		statusCode = RegSetValueExW(envKey, name, 0, type, (LPBYTE)outputValue, size);
		HeapFree(GetProcessHeap(), 0, regValue);
		HeapFree(GetProcessHeap(), 0, outputValue);
	}
	else
	{
		if(wcschr(value, TEXT('%')) == NULL)
			type = REG_SZ;
		else
			type = REG_EXPAND_SZ;

		statusCode = RegSetValueExW(envKey, name, 0, type, (BYTE*)value, wcslen(value) + 1);
	}
	RegCloseKey(envKey);
	DWORD messageResult = 0;
	SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)(TEXT("Environment")), SMTO_NORMAL, 0, &messageResult);
	JSBool retVal = JS_NewNumberValue(cx, statusCode, rval);
	JS_EndRequest(cx);
	return retVal;
}
示例#11
0
文件: Events.cpp 项目: ds-hwang/d2bs
bool __fastcall GameActionEventCallback(Script* script, void* argv, uint argc)
{
	GameActionEventHelper* helper = (GameActionEventHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("gameevent"))
	{
		AutoRoot** argv = new AutoRoot*[5];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		argv[1] = new AutoRoot();
		argv[2] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[0]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->param1, argv[1]->value());
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->param2, argv[2]->value());
		argv[3] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->name1)));
		argv[4] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->name2)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("gameevent", 5, argv);
	}
	return true;
}
JSBool S_SimpleNativeClass::jsPropertyGet(JSContext *cx, JSObject *obj, jsid _id, jsval *val)
{
	int32_t propId = JSID_TO_INT(_id);
	S_SimpleNativeClass *cobj; JSGET_PTRSHELL(S_SimpleNativeClass, cobj, obj);
	if (!cobj) return JS_FALSE;
	switch(propId) {
	case kSomeField:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->getSomeField(), &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	case kSomeOtherField:
		do { jsval tmp; JS_NewNumberValue(cx, cobj->getSomeOtherField(), &tmp); JS_SET_RVAL(cx, val, tmp); } while (0);
		break;
	case kAnotherMoreComplexField:
		do { JSString *tmp = JS_NewStringCopyZ(cx, cobj->getAnotherMoreComplexField()); JS_SET_RVAL(cx, val, STRING_TO_JSVAL(tmp)); } while (0);
		break;
	default:
		break;
	}
	return JS_TRUE;
}
示例#13
0
jsval
to_js_number(JSContext* cx, double value)
{
    jsval ret;

    if(!JS_NewNumberValue(cx, value, &ret))
    {
        return JSVAL_VOID;
    }

    return ret;
}
示例#14
0
static JSBool
gjs_value_from_gsize(JSContext         *context,
                     gsize              v,
                     JS::MutableHandleValue value_p)
{
    if (v > (gsize) JSVAL_INT_MAX) {
        value_p.set(INT_TO_JSVAL(v));
        return JS_TRUE;
    } else {
        return JS_NewNumberValue(context, v, value_p.address());
    }
}
示例#15
0
文件: Events.cpp 项目: ds-hwang/d2bs
bool __fastcall ManaEventCallback(Script* script, void* argv, uint argc)
{
	SingleArgHelper* helper = (SingleArgHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("memana"))
	{
		AutoRoot** argv = new AutoRoot*[1];
		argv[0] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->arg1, argv[0]->value());
		script->ExecEventAsync("memana", 1, argv);
	}
	return true;
}
// ****************************************************************************
// ***  static helper functions
// ****************************************************************************
JSBool GetValue(JSContext *cx, JSObject *obj, int index, jsval *ret) {
  gstRecordJSWrapperImpl* wrapper =
    static_cast<gstRecordJSWrapperImpl*>(JS_GetPrivate(cx, obj));
  if (!wrapper) {
    JS_ReportError(cx, "object doesn't have gstRecordWrapper\n");
    return JS_FALSE;
  }

  const gstHeaderHandle &header = wrapper->header();
  const gstRecordHandle &rec    = wrapper->record();
  if (!rec) {
    JS_ReportError(cx, "gstRecordWrapper doesn't have an active record");
    return JS_FALSE;
  }


  if ((index >= 0) && (index < (int)header->numColumns())) {
    switch (header->ftype(index)) {
      case gstTagBoolean:
        *ret = BOOLEAN_TO_JSVAL(rec->Field(index)->ValueAsBoolean());
        return JS_TRUE;
      case gstTagInt:
      case gstTagUInt:
      case gstTagInt64:
      case gstTagUInt64:
      case gstTagFloat:
      case gstTagDouble:
        return JS_NewNumberValue(cx, rec->Field(index)->ValueAsDouble(), ret);
      case gstTagString:
      case gstTagUnicode:
        {
          QString str = rec->Field(index)->ValueAsUnicode();
          if (str.isEmpty()) {
            *ret = JS_GetEmptyStringValue(cx);
          } else {
            JSString *newstr = JS_NewUCStringCopyN(cx, str.ucs2(), str.length());
            if (!newstr) {
              // out of memory error already reported
              return JS_FALSE;
            }
            *ret = STRING_TO_JSVAL(newstr);
          }
          return JS_TRUE;
        }
      default:
        JS_ReportError(cx, "Unhandled field type: %d",
                       header->ftype(index));
    }
  } else {
    JS_ReportError(cx, "field index out of range: %d", index);
  }
  return JS_FALSE;
}
static JSBool vector3_constructor(JSContext *cx, unsigned argc, jsval *vp)
{
	JSObject *returnObject;
	jsval returnValue;
	double x, y, z;
	jsval r, g, b;
	if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "ddd", &x, &y, &z))
		return JS_FALSE;
	returnObject = JS_NewObject(cx, &vector3_class, NULL, NULL);
	returnValue = OBJECT_TO_JSVAL(returnObject);

	JS_NewNumberValue(cx, x, &r);
	JS_NewNumberValue(cx, y, &g);
	JS_NewNumberValue(cx, z, &b);

	JS_SetProperty(cx, returnObject, "X", &r);
	JS_SetProperty(cx, returnObject, "Y", &g);
	JS_SetProperty(cx, returnObject, "Z", &b);

	JS_SET_RVAL(cx, vp, returnValue);
	return JS_TRUE;
}
示例#18
0
文件: Events.cpp 项目: ds-hwang/d2bs
bool __fastcall KeyEventCallback(Script* script, void* argv, uint argc)
{
	KeyEventHelper* helper = (KeyEventHelper*)argv;
	char* event = (helper->up ? "keyup" : "keydown");
	if(script->IsRunning() && script->IsListenerRegistered(event))
	{
		AutoRoot** argv = new AutoRoot*[1];
		argv[0] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->key, argv[0]->value());
		script->ExecEventAsync(event, 1, argv);
	}
	return true;
}
示例#19
0
文件: rpmseq-js.c 项目: avokhmin/RPM5
static JSBool
rpmseq_Get(JSContext *cx, uintN argc, jsval *vp)
{
    jsval *argv = JS_ARGV(cx , vp);
    JSObject *obj = JS_NewObjectForConstructor(cx , vp);
    if(!obj) {
	JS_ReportError(cx , "Failed to create 'this' object");
	return JS_FALSE;
    }
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmseqClass, NULL);
    DB_SEQUENCE * seq = ptr;
    JSObject * o = NULL;
    DB_TXN * _txn = NULL;
    int32_t _delta = 1;
    uint32_t _flags = 0;
    JSBool ok = JS_FALSE;

_METHOD_DEBUG_ENTRY(_debug);

    if (seq == NULL) goto exit;
    JS_SET_RVAL(cx, vp, JSVAL_FALSE);

    if (!(ok = JS_ConvertArguments(cx, argc, argv, "o/iu", &o, &_delta, &_flags)))
	goto exit;

    if (o && OBJ_IS_RPMTXN(cx, o))
	_txn = JS_GetInstancePrivate(cx, o, &rpmtxnClass, NULL);
    if (_delta <= 0)
	goto exit;

    {	jsdouble d = 0;
	db_seq_t _seqno = 0;
	int ret = seq->get(seq, _txn, _delta, &_seqno, _flags);
	switch (ret) {
	default:
	    fprintf(stderr, "DB_SEQUENCE->get: %s\n", db_strerror(ret));
	    goto exit;
	    break;
	case 0:
	    d = _seqno;
	    if (!JS_NewNumberValue(cx, d, &JS_RVAL(cx, vp)))
		JS_SET_RVAL(cx, vp, JSVAL_FALSE);
	    break;
	}
    }

    ok = JS_TRUE;

exit:
    return ok;
}
JSBool S_SimpleNativeClass::jsthisReturnsALongLong(JSContext *cx, uint32_t argc, jsval *vp) {
	JSObject* obj = (JSObject *)JS_THIS_OBJECT(cx, vp);
	S_SimpleNativeClass* self = NULL; JSGET_PTRSHELL(S_SimpleNativeClass, self, obj);
	if (self == NULL) return JS_FALSE;
	if (argc == 0) {
		jsval *argv = JS_ARGV(cx, vp);
		long long ret = self->thisReturnsALongLong();
		do { jsval tmp; JS_NewNumberValue(cx, ret, &tmp); JS_SET_RVAL(cx, vp, tmp); } while (0);
		
		return JS_TRUE;
	}
	JS_SET_RVAL(cx, vp, JSVAL_TRUE);
	return JS_TRUE;
}
示例#21
0
static JSBool
elixir_dbl_evas_object_params(double (*func)(const Evas_Object *obj),
                              const elixir_parameter_t *params[],
                              JSContext *cx, uintN argc, jsval *vp)
{
   Evas_Object *know = NULL;
   elixir_value_t val[1];

   if (!elixir_params_check(cx, params, val, argc, JS_ARGV(cx, vp)))
     return JS_FALSE;

   GET_PRIVATE(cx, val[0].v.obj, know);

   return JS_NewNumberValue(cx, func(know), &(JS_RVAL(cx, vp)));
}
static JSBool sys_registermodel(JSContext *cx, unsigned argc, jsval *vp)
{
    JSString *s;
    char *message;
    jsval rval;
    qhandle_t handle;
    if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &s))
        return JS_FALSE;
    message = JS_EncodeString(cx, s);
    handle = trap_R_RegisterModel(message);
    JS_free(cx, message);
    JS_NewNumberValue(cx, handle, &rval);
    JS_SET_RVAL(cx, vp, rval);
    return JS_TRUE;
}
static JSBool cvar_getint(JSContext *cx, unsigned argc, jsval *vp)
{
	JSString *s;
	char *message;
	jsval rval;
	int result;
	if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "S", &s))
		return JS_FALSE;
	message = JS_EncodeString(cx, s);
	result = trap_Cvar_VariableIntegerValue(message);
	JS_free(cx, message);
	JS_NewNumberValue(cx, result, &rval);
	JS_SET_RVAL(cx, vp, rval);
	return JS_TRUE;	
}
示例#24
0
文件: Events.cpp 项目: ds-hwang/d2bs
bool __fastcall CopyDataCallback(Script* script, void* argv, uint argc)
{
	CopyDataHelper* helper = (CopyDataHelper*)argv;
	if(script->IsRunning() && script->IsListenerRegistered("copydata"))
	{
		AutoRoot** argv = new AutoRoot*[2];
		JS_SetContextThread(ScriptEngine::GetGlobalContext());
		argv[0] = new AutoRoot();
		JS_NewNumberValue(ScriptEngine::GetGlobalContext(), helper->mode, argv[0]->value());
		argv[1] = new AutoRoot(STRING_TO_JSVAL(JS_NewStringCopyZ(ScriptEngine::GetGlobalContext(), helper->msg)));
		JS_ClearContextThread(ScriptEngine::GetGlobalContext());
		script->ExecEventAsync("copydata", 2, argv);
	}
	return true;
}
示例#25
0
NS_IMETHODIMP
IDBVersionChangeEvent::GetNewVersion(JSContext* aCx,
                                     JS::Value* aNewVersion)
{
  NS_ENSURE_ARG_POINTER(aNewVersion);

  if (!mNewVersion) {
    *aNewVersion = JSVAL_NULL;
  }
  else if (!JS_NewNumberValue(aCx, double(mNewVersion), aNewVersion)) {
    return NS_ERROR_FAILURE;
  }

  return NS_OK;
}
示例#26
0
  static JSBool
  ejs_system(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
  {
    EJS_CHECK_TRUSTED(cx,obj);
    EJS_CHECK_NUM_ARGS(cx,obj,1,argc);

    JSString *strtype=JS_ValueToString(cx, argv[0]);
    // todo: we loose unicode information here
    const char* ctype=JS_GetStringBytes(strtype);
    if (!ctype) return JS_FALSE;

    int r=system(ctype);
    if (r==-1) EJS_THROW_ERROR(cx,obj,"system failed");

    return JS_NewNumberValue(cx,r,rval);
  }
示例#27
0
  static
  JSBool
  loadSample(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
  {
    // sound disabled?
    if (!Audio::audio) return JS_TRUE;

    EJS_CHECK_NUM_ARGS(cx,obj,1,argc);

    char* ctype;
    size_t len;
    STRING_TO_CHARVEC(argv[0],ctype,len);

    Audio::SID sid=Audio::audio->loadSample(ctype,len);
    return JS_NewNumberValue(cx,sid,rval);
  }
示例#28
0
  static
  JSBool
  playSample(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
  {
    // sound disabled?
    if (!Audio::audio) return JS_TRUE;

    if((argc<1)||(argc>2)) EJS_THROW_ERROR(cx,obj,"Between 1 and 2 arguments required");
    jsdouble sid;
    if (!JS_ValueToNumber(cx,argv[0],&sid)) return JS_FALSE;
    jsdouble repeat;
    if (argc>=2)
      if (!JS_ValueToNumber(cx,argv[1],&repeat)) return JS_FALSE;
    Audio::CID cid=Audio::audio->playSample(sid,repeat);
    return JS_NewNumberValue(cx,cid,rval);
  }
JSBool S_SimpleAudioEngine::jsplayEffect(JSContext *cx, uint32_t argc, jsval *vp) {
	JSObject* obj = (JSObject *)JS_THIS_OBJECT(cx, vp);
	S_SimpleAudioEngine* self = NULL; JSGET_PTRSHELL(S_SimpleAudioEngine, self, obj);
	if (self == NULL) return JS_FALSE;
	if (argc == 2) {
		JSString *arg0;
		JSBool arg1;
		JS_ConvertArguments(cx, 2, JS_ARGV(cx, vp), "Sb", &arg0, &arg1);
		char *narg0 = JS_EncodeString(cx, arg0);
		unsigned int ret = self->playEffect(narg0, arg1);
		do { jsval tmp; JS_NewNumberValue(cx, ret, &tmp); JS_SET_RVAL(cx, vp, tmp); } while (0);
		
		return JS_TRUE;
	}
	JS_SET_RVAL(cx, vp, JSVAL_TRUE);
	return JS_TRUE;
}
示例#30
0
文件: mainloop.c 项目: sjokkis/gjs
static JSBool
gjs_timeout_add(JSContext *context,
                   JSObject  *obj,
                   uintN      argc,
                   jsval     *argv,
                   jsval     *retval)
{
    GClosure *closure;
    JSObject *callback;
    guint32 interval;
    guint id;

    /* Best I can tell, there is no way to know if argv[1] is really
     * callable other than to just try it. Checking whether it's a
     * function will not detect native objects that provide
     * JSClass::call, for example.
     */
    if (!gjs_parse_args(context, "timeout_add", "uo", argc, argv,
                        "interval", &interval, "callback", &callback))
      return JS_FALSE;

    closure = gjs_closure_new(context, callback, "timeout");
    if (closure == NULL)
        return JS_FALSE;

    g_closure_ref(closure);
    g_closure_sink(closure);

    id = g_timeout_add_full(G_PRIORITY_DEFAULT,
                            interval,
                            closure_source_func,
                            closure,
                            closure_destroy_notify);

    /* this is needed to remove the timeout if the JSContext is
     * destroyed.
     */
    g_closure_add_invalidate_notifier(closure, GUINT_TO_POINTER(id),
                                      closure_invalidated);

    if (!JS_NewNumberValue(context, id, retval))
        return JS_FALSE;

    return JS_TRUE;
}