| 536 | } |
| 537 | |
| 538 | void PiuScreen_launch(xsMachine* the) |
| 539 | { |
| 540 | PiuScreen* self = PIU(Screen, xsThis); |
| 541 | xsStringValue libraryPath = NULL; |
| 542 | xsStringValue archivePath = NULL; |
| 543 | xsStringValue ffiPath = NULL; |
| 544 | void* library = NULL; |
| 545 | txScreenLaunchProc launch; |
| 546 | int archiveFile = -1; |
| 547 | size_t archiveSize = 0; |
| 548 | void* archive = NULL; |
| 549 | void* ffiLibrary = NULL; |
| 550 | txScreenBuildFFIProc buildFFI; |
| 551 | xsTry { |
| 552 | libraryPath = xsToString(xsArg(0)); |
| 553 | if (xsToInteger(xsArgc) > 1) |
| 554 | archivePath = xsToString(xsArg(1)); |
| 555 | if (xsToInteger(xsArgc) > 2) |
| 556 | ffiPath = xsToString(xsArg(2)); |
| 557 | library = dlopen(libraryPath, RTLD_NOW); |
| 558 | if (library == NULL) { |
| 559 | xsUnknownError("%s", dlerror()); |
| 560 | } |
| 561 | launch = (txScreenLaunchProc)dlsym(library, "fxScreenLaunch"); |
| 562 | if (launch == NULL) { |
| 563 | xsUnknownError("%s", dlerror()); |
| 564 | } |
| 565 | if (xsToInteger(xsArgc) > 1) |
| 566 | archivePath = xsToString(xsArg(1)); |
| 567 | if (archivePath) { |
| 568 | archiveFile = open(archivePath, O_RDWR); |
| 569 | if (archiveFile < 0) { |
| 570 | xsUnknownError("%s", strerror(errno)); |
| 571 | } |
| 572 | struct stat statbuf; |
| 573 | fstat(archiveFile, &statbuf); |
| 574 | archiveSize = statbuf.st_size; |
| 575 | archive = mmap(NULL, archiveSize, PROT_READ|PROT_WRITE, MAP_SHARED, archiveFile, 0); |
| 576 | if (archive == MAP_FAILED) { |
| 577 | archive = NULL; |
| 578 | xsUnknownError("%s", strerror(errno)); |
| 579 | } |
| 580 | if (ffiPath) { |
| 581 | ffiLibrary = dlopen(ffiPath, RTLD_NOW); |
| 582 | if (ffiLibrary == NULL) { |
| 583 | xsUnknownError("%s", dlerror()); |
| 584 | } |
| 585 | buildFFI = (txScreenBuildFFIProc)dlsym(ffiLibrary, "fxBuildFFI"); |
| 586 | if (buildFFI == NULL) { |
| 587 | xsUnknownError("%s", dlerror()); |
| 588 | } |
| 589 | } |
| 590 | } |
| 591 | (*self)->library = library; |
| 592 | (*self)->archiveFile = archiveFile; |
| 593 | (*self)->archiveSize = archiveSize; |
| 594 | (*self)->ffiLibrary = ffiLibrary; |
| 595 | (*self)->screen->archive = archive; |