void KprDebugMachineEchoItem(KprDebugMachine self, int theView, char* path, int line, char* name, char* value) { KprDebug debug = self->debug; xsMachine* the = debug->the; if (xsTypeOf(debug->behavior) == xsUndefinedType) goto bail; { xsTry { xsVar(0) = xsAccess(debug->behavior); xsVar(1) = xsGet(xsVar(0), xsID(self->address)); xsVar(2) = xsNewInstanceOf(xsObjectPrototype); if (path) xsNewHostProperty(xsVar(2), xsID("path"), xsString(path), xsDefault, xsDontScript); if (line >= 0) xsNewHostProperty(xsVar(2), xsID("line"), xsInteger(line), xsDefault, xsDontScript); if (name) xsNewHostProperty(xsVar(2), xsID("name"), xsString(name), xsDefault, xsDontScript); if (value) xsNewHostProperty(xsVar(2), xsID("value"), xsString(value), xsDefault, xsDontScript); if (xsFindResult(xsVar(1), xsID_push)) { (void)xsCallFunction1(xsResult, xsVar(1), xsVar(2)); } } xsCatch { } } bail: return; }
void kpr2jsSplitPath(xsMachine* the) { char *aPath; char *aSeparator = NULL; char *aDot = NULL; int aLength; char aDirectory[1024]; char aName[1024]; char anExtension[1024]; aPath = xsToString(xsArg(0)); aSeparator = strrchr(aPath, mxSeparator); if (aSeparator == NULL) aSeparator = aPath; else aSeparator++; aDot = strrchr(aSeparator, '.'); if (aDot == NULL) aDot = aSeparator + strlen(aSeparator); aLength = aSeparator - aPath; strncpy(aDirectory, aPath, aLength); aDirectory[aLength - 1] = 0; aLength = aDot - aSeparator; strncpy(aName, aSeparator, aLength); aName[aLength] = 0; strcpy(anExtension, aDot); xsResult = xsNewInstanceOf(xsArrayPrototype); xsSet(xsResult, 0, xsString(aDirectory)); xsSet(xsResult, 1, xsString(aName)); xsSet(xsResult, 2, xsString(anExtension)); }
FskErr FskSSLNew(void **fsslp, const char *host, int port, Boolean blocking, long flags, int priority) { FskSSL *fssl; FskErr err; if ((err = FskMemPtrNewClear(sizeof(FskSSL), (FskMemPtr*)(void*)&fssl)) != kFskErrNone) return err; if ((err = newSSLVM(&fssl->vm)) != kFskErrNone) { FskMemPtrDispose(fssl); return err; } xsBeginHost(fssl->vm->the); xsTry { const char *prStr; xsVars(2); /* construct the options */ xsVar(0) = xsNewInstanceOf(xsObjectPrototype); if (blocking) xsSet(xsVar(0), xsID("blocking"), xsTrue); if (flags & kConnectFlagsSynchronous) xsSet(xsVar(0), xsID("synchronous"), xsTrue); switch (priority) { default: case kFskNetSocketLowestPriority: prStr = "lowest"; break; case kFskNetSocketLowPriority: prStr = "low"; break; case kFskNetSocketMediumPriority: prStr = "medium"; break; case kFskNetSocketHighPriority: prStr = "high"; break; case kFskNetSocketHighestPriority: prStr = "highest"; break; } (void)xsSet(xsVar(0), xsID("priority"), xsString((xsStringValue)prStr)); (void)xsSet(xsVar(0), xsID("raw"), xsTrue); xsVar(1) = xsNew3(xsGet(xsGlobal, xsID("Stream")), xsID("Socket"), xsString((xsStringValue)host), xsInteger(port), xsVar(0)); fssl->socket = xsVar(1); xsRemember(fssl->socket); xsVar(1) = xsNew0(xsGet(xsGlobal, xsID("FskSSL")), xsID("Session")); fssl->ssl = xsVar(1); xsRemember(fssl->ssl); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); if (err == kFskErrNone) { if (fsslp != NULL) *fsslp = fssl; } else { disposeSSLVM(fssl->vm); FskMemPtrDispose(fssl); } return err; }
void KPR_Message_patch(xsMachine* the) { xsResult = xsGet(xsGlobal, xsID("Message")); xsNewHostProperty(xsResult, xsID("CHUNK"), xsString("CHUNK"), xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsNewHostProperty(xsResult, xsID("DOM"), xsString("DOM"), xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsNewHostProperty(xsResult, xsID("JSON"), xsString("JSON"), xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsNewHostProperty(xsResult, xsID("TEXT"), xsString("TEXT"), xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsNewHostProperty(xsResult, xsID("URI"), xsNewHostFunction(KPR_Message_URI, 1), xsDefault, xsDontScript); xsNewHostProperty(xsResult, xsID("cancelReferrer"), xsNewHostFunction(KPR_Message_cancelReferrer, 1), xsDefault, xsDontScript); xsNewHostProperty(xsResult, xsID("notify"), xsNewHostFunction(KPR_Message_notify, 1), xsDefault, xsDontScript); }
FskErr KprApplicationNew(KprApplication* it, char* url, char* id, Boolean breakOnStart, Boolean breakOnExceptions) { KprCoordinatesRecord coordinates = { kprLeftRight, kprTopBottom, 0, 0, 0, 0, 0, 0 }; xsAllocation allocation = { 2 * 1024 * 1024, 1024 * 1024, 64 * 1024, 8 * 1024, 2048, 16000, 1993 }; FskErr err = kFskErrNone; KprApplication self; bailIfError(FskMemPtrNewClear(sizeof(KprApplicationRecord), it)); self = *it; FskInstrumentedItemNew(self, NULL, &KprApplicationInstrumentation); self->dispatch = &KprApplicationDispatchRecord; self->flags = kprContainer | kprClip | kprVisible; KprContentInitialize((KprContent)self, &coordinates, NULL, NULL); bailIfError(KprURLMerge(gShell->url, url, &self->url)); if (id) { self->id = FskStrDoCopy(id); bailIfNULL(self->id); } self->the = xsAliasMachine(&allocation, gShell->root, self->url, self); if (!self->the) BAIL(kFskErrMemFull); FskInstrumentedItemSendMessageNormal(self, kprInstrumentedContentCreateMachine, self); xsBeginHost(self->the); xsResult = xsNewHostFunction(KPR_include, 1); xsSet(xsResult, xsID("uri"), xsString(self->url)); xsNewHostProperty(xsGlobal, xsID("include"), xsResult, xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsResult = xsNewHostFunction(KPR_require, 1); xsSet(xsResult, xsID("uri"), xsString(self->url)); xsNewHostProperty(xsGlobal, xsID("require"), xsResult, xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsResult = xsNewInstanceOf(xsGet(xsGet(xsGlobal, xsID("KPR")), xsID("application"))); self->slot = xsResult; xsSetHostData(xsResult, self); (void)xsCall1(xsGet(xsGlobal, xsID("Object")), xsID("seal"), xsResult); xsNewHostProperty(xsGlobal, xsID("application"), xsResult, xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); xsNewHostProperty(xsGlobal, xsID("shell"), xsNull, xsDontDelete | xsDontSet, xsDontScript | xsDontDelete | xsDontSet); if (breakOnStart) xsDebugger(); if (breakOnExceptions) (void)xsCall1(xsGet(xsGet(xsGlobal, xsID("xs")), xsID("debug")), xsID("setBreakOnException"), xsBoolean(breakOnExceptions)); (void)xsCall1(xsGlobal, xsID("include"), xsString(self->url)); xsEndHost(self->the); KprContentChainPrepend(&gShell->applicationChain, self, 0, NULL); bail: return err; }
void Zeroconf_browser_callback(KprZeroconfBrowser self, char* function, KprZeroconfServiceInfo service) { xsBeginHostSandboxCode(self->the, self->code); if (xsTypeOf(self->behavior) == xsUndefinedType) goto bail; xsVars(3); { xsTry { xsVar(0) = xsAccess(self->behavior); xsVar(1) = xsNewInstanceOf(xsObjectPrototype); xsSet(xsVar(1), xsID("name"), xsString(service->name)); xsSet(xsVar(1), xsID("type"), xsString(service->type)); if (service->host) xsSet(xsVar(1), xsID("host"), xsString(service->host)); if (service->ip) { xsSet(xsVar(1), xsID("ip"), xsString(service->ip)); xsSet(xsVar(1), xsID("port"), xsInteger(service->port)); } if (service->txt) { char* txt = service->txt; UInt32 position = 0, size = FskStrLen(txt); UInt32 length = 0; xsVar(2) = xsNewInstanceOf(xsObjectPrototype); xsSet(xsVar(1), xsID("txt"), xsVar(2)); length = txt[position++] & 0xFF; while ((position + length) <= size) { char end; char* equal; if (!length) break; end = txt[position + length]; txt[position + length] = 0; equal = FskStrChr(txt + position, '='); if (equal) { *equal = 0; xsSet(xsVar(2), xsID(txt + position), xsString(equal + 1)); *equal = '='; } txt[position + length] = end; position += length; length = txt[position++] & 0xFF; } } if (xsFindResult(xsVar(0), xsID(function))) { (void)xsCallFunction1(xsResult, xsVar(0), xsVar(1)); } } xsCatch { } } bail: xsEndHostSandboxCode(); }
void xs_gpio_get_direction(xsMachine* the) { FskGPIO gpio = xsGetHostData(xsThis); if (gpio) { GPIOdirection direction; FskGPIOPlatformGetDirection(gpio, &direction); if (in == direction) xsResult = xsString("in"); //@@ input - to match constructor else if (out == direction) xsResult = xsString("out"); //@@ output - to match constructor else xsResult = xsString("undefined"); } }
void kpr2jsGetPlatform(xsMachine* the) { #if mxWindows xsResult = xsString("Windows"); #elif mxMacOSX xsResult = xsString("MacOSX"); #elif mxLinux xsResult = xsString("Linux"); #elif mxSolaris xsResult = xsString("Solaris"); #else #pragma error("need a platform") #endif }
void xsToolReadString(xsMachine* the) { char* aPath; FILE* aFile; size_t aSize; char *aBuffer; aPath = xsToString(xsArg(0)); #if mxWindows { char* aSlash; aSlash = aPath; while (*aSlash) { if (*aSlash == '/') *aSlash = '\\'; aSlash++; } } #endif aFile = fopen(aPath, "rb"); if (aFile) { fseek(aFile, 0, SEEK_END); aSize = ftell(aFile); fseek(aFile, 0, SEEK_SET); aBuffer = malloc(aSize + 1); if (aBuffer) { aSize = fread(aBuffer, 1, aSize, aFile); aBuffer[aSize] = 0; xsResult = xsString(aBuffer); free(aBuffer); } fclose(aFile); } }
void xsToolGetEnvironmentValue(xsMachine* the) { char* aName = xsToString(xsArg(0)); char* aValue = getenv(aName); if (aValue) xsResult = xsString(aValue); }
void KprDebugMachineLoadView(KprDebugMachine self, int theView, char* thePath, int theLine) { FskErr err = kFskErrNone; KprDebug debug = self->debug; xsMachine* the = debug->the; // FskFileInfo info; // FskFileMapping map = NULL; // FskDebugStr("%s: %d - %s:%d", __FUNCTION__, theView, thePath, theLine); if (xsTypeOf(debug->behavior) == xsUndefinedType) goto bail; xsVar(0) = xsAccess(debug->behavior); if (xsFindResult(xsVar(0), xsID("onMachineFileChanged"))) { (void)xsCallFunction5(xsResult, xsVar(0), xsString(self->address), xsInteger(theView), xsNull, thePath ? xsString(thePath) : xsNull, xsInteger(theLine)); } // if (kFskErrNone == FskFileGetFileInfo(thePath, &info) && (kFskDirectoryItemIsFile == info.filetype)) { // unsigned char *data; // FskInt64 size; // BAIL_IF_ERR(err = FskFileMap(thePath, &data, &size, 0, &map)); // xsVar(0) = xsAccess(debug->behavior); // // if (xsFindResult(xsVar(0), xsID("onMachineFileChanged"))) { // (void)xsCallFunction5(xsResult, xsVar(0), xsString(self->address), xsInteger(theView), xsNull, xsString(thePath), xsInteger(theLine)); // } // } bail: // FskFileDisposeMap(map); xsThrowIfFskErr(err); }
void KPR_host_get_id(xsMachine* the) { KprContainer self = xsGetHostData(xsThis); KprApplication application = (KprApplication)self->first; if (application->id) xsResult = xsString(application->id); }
void KPR_Message_URI(xsMachine* the) { char* url = NULL; xsThrowIfFskErr(KprMessageURL(xsGetContext(the), xsToString(xsArg(0)), &url)); xsResult = xsString(url); FskMemPtrDispose(url); }
void KPR_message_get_method(xsMachine *the) { KprMessage self = xsGetHostData(xsThis); xsStringValue method = KprMessageGetMethod(self); if (method) xsResult = xsString(method); }
void KprDebugMachineDataReader(FskThreadDataHandler handler UNUSED, FskThreadDataSource source UNUSED, void *refCon) { FskErr err = kFskErrNone; KprDebugMachine self = refCon; KprDebug debug = self->debug; int size; err = FskNetSocketRecvTCP(self->socket, self->buffer, XS_BUFFER_COUNT, &size); if (size > 0) { xsBeginHostSandboxCode(debug->the, debug->code); xsVars(4); KprDebugMachineParse(self, self->buffer, size); if (self->done) { self->state = XS_HEADER_STATE; self->dataIndex = 0; if (self->broken) { xsCall0(xsGet(xsGlobal, xsID_KPR), xsID_gotoFront); } else { xsCall1(debug->slot, xsID_go, xsString(self->address)); KprDebugMachineCallback(self, "gone"); } } xsEndHostSandboxCode(); } if (err) { KprDebugMachineDispose(self); } }
void KPR_message_getResponseHeader(xsMachine* the) { KprMessage self = kprGetHostData(xsThis, this, message); xsStringValue result = KprMessageGetResponseHeader(self, xsToString(xsArg(0))); if (result) xsResult = xsString(result); }
void KPR_system_saveFile(xsMachine* the) { FskErr err; xsIntegerValue argc = xsToInteger(xsArgc); xsStringValue name = NULL; xsStringValue prompt = NULL; xsStringValue initialPath = NULL; xsStringValue path = NULL; xsStringValue url = NULL; if ((argc > 0) && xsTest(xsArg(0))) { if (xsFindResult(xsArg(0), xsID_name)) name = xsToStringCopy(xsResult); if (xsFindResult(xsArg(0), xsID_prompt)) prompt = xsToStringCopy(xsResult); if (xsFindResult(xsArg(0), xsID_url)) KprURLToPath(xsToString(xsResult), &initialPath); } err = FskFileChooseSave(name, prompt, initialPath, &path); if ((kFskErrNone == err) && (NULL != path)) { KprPathToURL(path, &url); (void)xsCallFunction1(xsArg(1), xsNull, xsString(url)); } FskMemPtrDispose(url); FskMemPtrDispose(path); FskMemPtrDispose(initialPath); FskMemPtrDispose(prompt); FskMemPtrDispose(name); }
static void KPR_canvasRenderingContext2D_get_enum(xsMachine *the, UInt32 (*getter)(FskConstCanvas2dContext), xsStringValue* array, UInt32 start, UInt32 stop) { FskCanvas2dContext ctx = xsGetHostData(xsThis); UInt32 value = (*getter)(ctx); if ((start <= value) && (value <= stop)) xsResult = xsString(array[value - start]); }
void KPR_canvasRenderingContext2D_pickHitRegion(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsThis); xsNumberValue x = xsToNumber(xsArg(0)), y = xsToNumber(xsArg(1)); const char *id = NULL, *control = NULL; if (kFskErrNone == FskCanvas2dPickHitRegion(ctx, x, y, &id, &control)) { xsResult = xsNewInstanceOf(xsObjectPrototype); if (id) xsNewHostProperty(xsResult, xsID("id"), xsString((char*)id), xsDefault, xsDontScript); // TODO: Would we send a mouse event to the id? if (control) xsNewHostProperty(xsResult, xsID("control"), xsString((char*)control), xsDefault, xsDontScript); // TODO: We should call the control directly. } else { // How do we indicate failure? xsResult = NULL; } }
void process_execArgv(xsMachine* the) { int i; xsResult = xsNewInstanceOf(xsArrayPrototype); for (i = gargi; i < gargc; i++) { xsSetAt(xsResult, xsInteger(i - gargi), xsString(gargv[i])); } }
void KPR_mergeURI(xsMachine *the) { xsStringValue base = xsToString(xsArg(0)); xsStringValue url = xsToString(xsArg(1)); xsStringValue target; xsThrowIfFskErr(KprURLMerge(base, url, &target)); xsResult = xsString(target); FskMemPtrDispose(target); }
void KPR_debug_get_machines(xsMachine *the) { KprDebug self = xsGetHostData(xsThis); KprDebugMachine machine = NULL; xsEnterSandbox(); xsVars(1); { xsResult = xsNewInstanceOf(xsArrayPrototype); for (machine = self->machine; machine; machine = machine->next) { xsVar(0) = xsNewInstanceOf(xsObjectPrototype); xsNewHostProperty(xsVar(0), xsID("address"), xsString(machine->address), xsDefault, xsDontScript); if (machine->title) xsNewHostProperty(xsVar(0), xsID("title"), xsString(machine->title), xsDefault, xsDontScript); xsCall1(xsResult, xsID_push, xsVar(0)); } } xsLeaveSandbox(); }
void xsToolGetIPAddress(xsMachine* the) { char hostname[128]; struct hostent *he; gethostname(hostname, sizeof(hostname)); he = gethostbyname(hostname); if (he) xsResult = xsString(inet_ntoa(*(struct in_addr*)he->h_addr)); }
void xsToolReplacePath(xsMachine* the) { char* aName = xsToString(xsArg(1)); char* aValue = getenv(aName); if (aValue) xsResult = xsString(aValue); else xsResult = xsArg(1); }
void fxParse(xsMachine* the, void* theStream, xsGetter theGetter, xsStringValue thePath, xsIntegerValue theLine, xsFlag theFlag) { xsStreamGetter streamGetter; xsSlot* stack = the->stack; xsIntegerValue c = xsToInteger(stack[0]); stack[c] = xsGet(xsGet(xsGlobal, xsID("xs")), xsID("infoset")); stack[c - 1] = xsNewHostObject(NULL); streamGetter.stream = theStream; streamGetter.getter = theGetter; xsSetHostData(stack[c - 1], &streamGetter); if (thePath && theLine) stack[c - 2] = xsCall3(stack[c], xsID("scan"), stack[c - 1], xsString(thePath), xsInteger(theLine)); else if (thePath) stack[c - 2] = xsCall2(stack[c], xsID("scan"), stack[c - 1], xsString(thePath)); else stack[c - 2] = xsCall1(stack[c], xsID("scan"), stack[c - 1]); stack[c] = xsCall2(stack[c], xsID("parse"), stack[c - 2], xsInteger(theFlag)); the->stack = stack + c; }
void KPR_system_getenv(xsMachine *the) { xsIntegerValue c = xsToInteger(xsArgc); if ((c >= 1) && (xsTypeOf(xsArg(0)) == xsStringType)) { char* variable = xsToString(xsArg(0)); char* value = getenv(variable); if (value) xsResult = xsString(value); } }
void KPR_application_get_di(xsMachine* the) { KprApplication self = xsGetHostData(xsThis); if (self->id) { char* di; xsThrowIfFskErr(KprAuthorityReverse(self->id, &di)); xsResult = xsString(di); FskMemPtrDispose(di); } }
FskErr FskSSLLoadCerts(void *a, FskSocketCertificateRecord *cert) { FskSSL *fssl = a; FskErr err = kFskErrNone; xsBeginHost(fssl->vm->the); xsTry { xsVars(2); xsVar(0) = xsUndefined; xsVar(1) = xsUndefined; if (cert != NULL) { if (cert->certificates != NULL && cert->certificatesSize > 0) { xsVar(0) = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(cert->certificatesSize)); FskMemCopy(xsGetHostData(xsVar(0)), cert->certificates, cert->certificatesSize); } if (cert->policies != NULL) { if (cert->certificates == NULL) xsVar(0) = xsNew0(xsGlobal, xsID("Chunk")); // create a null chunk just for setting the polices xsSet(xsVar(0), xsID("policies"), xsString(cert->policies)); } if (cert->hostname != NULL) { xsSet(fssl->socket, xsID("hostname"), xsString(cert->hostname)); // too easy but should work... } if (cert->key != NULL && cert->keySize > 0) { xsVar(1) = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(cert->keySize)); FskMemCopy(xsGetHostData(xsVar(1)), cert->key, cert->keySize); } } xsCall2_noResult(fssl->ssl, xsID("loadCerts"), xsVar(0), xsVar(1)); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); return err; }
void xsToolResolvePath(xsMachine* the) { #if mxWindows char* srcPath; char* aSlash; char aPath[1024]; DWORD attributes; int aResult = 0; srcPath = xsToString(xsArg(0)); aSlash = srcPath; while (*aSlash) { if (*aSlash == '/') *aSlash = '\\'; aSlash++; } if (_fullpath(aPath, srcPath, 1024) != NULL) { attributes = GetFileAttributes(aPath); if (attributes != 0xFFFFFFFF) { if (xsToInteger(xsArgc) == 1) aResult = 1; else if (xsToBoolean(xsArg(1))) aResult = (attributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; else aResult = (attributes & FILE_ATTRIBUTE_DIRECTORY) ? 0 : 1; } } #else char* srcPath; char aPath[PATH_MAX]; struct stat a_stat; int aResult = 0; srcPath = xsToString(xsArg(0)); if (realpath(srcPath, aPath) != NULL) { if (stat(aPath, &a_stat) == 0) { if (xsToInteger(xsArgc) == 1) aResult = 1; else if (xsToBoolean(xsArg(1))) aResult = S_ISDIR(a_stat.st_mode) ? 1 : 0; else aResult = S_ISREG(a_stat.st_mode) ? 1 : 0; } } #endif if (aResult) { if (xsToBoolean(xsArg(1))) { aResult = strlen(aPath) - 1; if (aPath[aResult] == mxSeparator) aPath[aResult] = 0; } xsResult = xsString(aPath); } }
void KPR_system_alert(xsMachine* the) { int argc = xsToInteger(xsArgc); MSGBOXPARAMSW params; xsStringValue string; xsIntegerValue result; xsVars(1); params.cbSize = sizeof(params); params.hwndOwner = NULL; params.hInstance = FskMainGetHInstance(); params.lpszText = NULL; params.lpszCaption = xsStringToWideString("Kinoma Code"); params.dwStyle = MB_ICONSTOP; params.dwContextHelpId = 0; params.lpfnMsgBoxCallback = NULL; params.dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); if ((argc > 0) && xsTest(xsArg(0))) { if (xsFindString(xsArg(0), xsID_type, &string)) { if (!FskStrCompare(string, "about")) params.dwStyle = MB_ICONINFORMATION; else if (!FskStrCompare(string, "stop")) params.dwStyle = MB_ICONSTOP; else if (!FskStrCompare(string, "note")) params.dwStyle = MB_ICONEXCLAMATION; } if (xsFindResult(xsArg(0), xsID_prompt)) { xsVar(0) = xsResult; } if (xsFindResult(xsArg(0), xsID_info)) { xsVar(0) = xsCall1(xsVar(0), xsID("concat"), xsString("\n\n")); xsVar(0) = xsCall1(xsVar(0), xsID("concat"), xsResult); } params.lpszText = xsStringToWideString(xsToString(xsVar(0))); if (xsFindResult(xsArg(0), xsID_buttons)) { if (xsIsInstanceOf(xsResult, xsArrayPrototype)) { xsIntegerValue c = xsToInteger(xsGet(xsResult, xsID_length)); if (c == 3) params.dwStyle |= MB_YESNOCANCEL; else if (c == 2) params.dwStyle |= MB_OKCANCEL; else params.dwStyle |= MB_OK; } } } result = MessageBoxIndirectW(¶ms); if (params.lpszText) CoTaskMemFree((LPVOID *)params.lpszText); if (params.lpszCaption) CoTaskMemFree((LPVOID *)params.lpszCaption); if ((argc > 1) && xsTest(xsArg(1))) (void)xsCallFunction1(xsArg(1), xsNull, ((result == IDYES) || (result == IDOK)) ? xsTrue : (result == IDNO) ? xsFalse : xsUndefined); }