MCStreamCache::~MCStreamCache() { if (m_cache_file) MCS_close(m_cache_file); if (m_cache_buffer) MCMemoryDeallocate(m_cache_buffer); }
IO_stat MCS_fakeclosewrite(IO_handle& p_stream, char*& r_buffer, uint4& r_length) { if ((p_stream -> flags & IO_FAKEWRITE) != IO_FAKEWRITE) { r_buffer = NULL; r_length = 0; MCS_close(p_stream); return IO_ERROR; } MCMemoryFileHandle *t_handle; t_handle = static_cast<MCMemoryFileHandle *>(p_stream -> handle); t_handle -> TakeBuffer(r_buffer, r_length); MCS_close(p_stream); return IO_NORMAL; }
void MCDispatch::cleanup(IO_handle stream, char *linkname, char *bname) { if (stream != NULL) MCS_close(stream); MCS_unlink(linkname); if (bname != NULL) MCS_unbackup(bname, linkname); delete linkname; delete bname; }
static void cgi_dispose_multipart_context(cgi_multipart_context_t *p_context) { MCCStringFree(p_context->name); MCCStringFree(p_context->file_name); MCCStringFree(p_context->type); MCCStringFree(p_context->boundary); if (p_context->file_handle != NULL) MCS_close(p_context->file_handle); MCMemoryClear(p_context, sizeof(cgi_multipart_context_t)); }
Boolean IO_closefile(const char *name) { uint2 index; if (IO_findfile(name, index)) { if (MCfiles[index].ihandle != NULL) MCS_close(MCfiles[index].ihandle); else { if (MCfiles[index].ohandle->flags & IO_WRITTEN && !(MCfiles[index].ohandle->flags & IO_SEEKED)) MCS_trunc(MCfiles[index].ohandle); MCS_close(MCfiles[index].ohandle); } delete MCfiles[index].name; while (++index < MCnfiles) MCfiles[index - 1] = MCfiles[index]; MCnfiles--; return True; } return False; }
void MCEncodedImageRep::ClearImageLoader() { if (m_loader != nil) { delete m_loader; m_loader = nil; } if (m_stream != nil) { MCS_close(m_stream); m_stream = nil; } }
void IO_cleanprocesses() { MCS_checkprocesses(); uint2 i = 0; while (i < MCnprocesses) if (MCprocesses[i].pid == 0 && (MCprocesses[i].ihandle == NULL || MCS_eof(MCprocesses[i].ihandle))) { #ifdef X11 if (MCprocesses[i].mode == OM_VCLIP) { MCPlayer *tptr = MCplayers; while (tptr != NULL) { if (strequal(MCprocesses[i].name, tptr->getcommand())) { tptr->playstop(); // removes from linked list break; } tptr = tptr->getnextplayer(); } } #endif if (MCprocesses[i].ihandle != NULL) MCS_close(MCprocesses[i].ihandle); if (MCprocesses[i].ohandle != NULL) MCS_close(MCprocesses[i].ohandle); delete MCprocesses[i].name; uint2 j = i; while (++j < MCnprocesses) MCprocesses[j - 1] = MCprocesses[j]; MCnprocesses--; } else i++; }
bool MCVectorImageRep::CalculateGeometry(uindex_t &r_width, uindex_t &r_height) { bool t_success = true; IO_handle t_stream = nil; t_success = nil != (t_stream = MCS_fakeopen(MCString((char*)m_data, m_size))); if (t_success) t_success = MCImageGetMetafileGeometry(t_stream, r_width, r_height); if (t_stream != nil) MCS_close(t_stream); return t_success; }
bool MCImageDecode(const uint8_t *p_data, uindex_t p_size, MCImageFrame *&r_frames, uindex_t &r_frame_count) { bool t_success = true; IO_handle t_stream = nil; t_success = nil != (t_stream = MCS_fakeopen(MCString((const char*)p_data, p_size))); if (t_success) t_success = MCImageDecode(t_stream, r_frames, r_frame_count); if (t_stream != nil) MCS_close(t_stream); return t_success; }
void MCS_downloadurl(MCObject *p_target, const char *p_url, const char *p_file) { bool t_success = true; char *t_processed = nil; MCObjectHandle *t_obj = nil; IO_handle t_output = nil; MCSDownloadUrlState t_state; t_output = MCS_open(p_file, IO_WRITE_MODE, False, False, 0); if (t_output == nil) { MCresult -> sets("can't open that file"); return; } t_success = MCSystemProcessUrl(p_url, kMCSystemUrlOperationStrip, t_processed); if (t_success) t_success = nil != (t_obj = p_target->gethandle()); if (t_success) { t_state . url = t_processed; t_state . status = kMCSystemUrlStatusNone; t_state . object = t_obj; t_state . output = t_output; t_state . length = 0; t_state . total = 0; t_success = MCSystemLoadUrl(t_processed, MCS_downloadurl_callback, &t_state); } if (t_success) { while(t_state . status != kMCSystemUrlStatusFinished && t_state . status != kMCSystemUrlStatusError) MCscreen -> wait(60.0, True, True); if (t_state . status == kMCSystemUrlStatusFinished) MCresult -> clear(); } MCCStringFree(t_processed); if (t_output != nil) MCS_close(t_output); if (t_obj != nil) t_obj->Release(); }
// IM-2014-07-31: [[ ImageLoader ]] Use image loader method to identify stream format uint32_t MCEncodedImageRep::GetDataCompression() { if (m_have_compression) return m_compression; IO_handle t_stream; t_stream = nil; MCImageLoaderFormat t_format; if (GetDataStream(t_stream) && MCImageLoader::IdentifyFormat(t_stream, t_format)) /* UNCHECKED */ MCImageLoaderFormatToCompression(t_format, m_compression); if (t_stream != nil) MCS_close(t_stream); return m_compression; }
// IM-2011-08-05: Reorganization of post variables, now generating all at the same time static Exec_stat cgi_compute_post_variables() { Exec_stat t_stat = ES_NORMAL; if (s_cgi_processed_post) return ES_NORMAL; s_cgi_processed_post = true; char *t_content_type; t_content_type = MCS_getenv("CONTENT_TYPE"); if (t_content_type != NULL && strcasecmp(t_content_type, "application/x-www-form-urlencoded") == 0) { // TODO: currently we assume that urlencoded form data is small enough to fit into memory, // so we fetch the contents from $_POST_RAW (which automatically reads the data from stdin). // in the future we should read from stdin to avoid duplicating large amounts of data MCExecPoint raw_ep, ep; MCVarref *t_raw_ref; t_raw_ref = s_cgi_post_raw->newvarref(); t_stat = t_raw_ref->eval(raw_ep); if (t_stat == ES_NORMAL) { MCString t_raw_string; t_raw_string = raw_ep.getsvalue(); cgi_store_form_urlencoded(ep, s_cgi_post_binary, t_raw_string.getstring(), t_raw_string.getstring() + t_raw_string.getlength(), false); cgi_store_form_urlencoded(ep, s_cgi_post, t_raw_string.getstring(), t_raw_string.getstring() + t_raw_string.getlength(), true); } delete t_raw_ref; } else if (t_content_type != NULL && MCCStringBeginsWithCaseless(t_content_type, "multipart/form-data;")) { // read post-data from stdin, via the stream cache MCExecPoint ep; MCCacheHandle *t_stdin = new MCCacheHandle(s_cgi_stdin_cache); IO_handle t_stdin_handle = new IO_header(t_stdin, 0); cgi_store_form_multipart(ep, t_stdin_handle); MCS_close(t_stdin_handle); } return t_stat; }
bool MCVectorImageRep::LoadHeader(uindex_t &r_width, uindex_t &r_height, uint32_t &r_frame_count) { bool t_success = true; MCAutoDataRef t_data; IO_handle t_stream = nil; if (t_success) t_success = nil != (t_stream = MCS_fakeopen((const char *)m_data, m_size)); if (t_success) t_success = MCImageGetMetafileGeometry(t_stream, r_width, r_height); if (t_success) r_frame_count = 1; if (t_stream != nil) MCS_close(t_stream); return t_success; }
bool MCEncodedImageRep::SetupImageLoader() { if (m_loader != nil) return true; bool t_success; t_success = true; IO_handle t_stream; t_stream = nil; MCImageLoader *t_loader; t_loader = nil; if (t_success) t_success = GetDataStream(t_stream); if (t_success) t_success = MCImageLoader::LoaderForStream(t_stream, t_loader); if (t_success) { m_stream = t_stream; m_loader = t_loader; m_have_compression = MCImageLoaderFormatToCompression(m_loader->GetFormat(), m_compression); } else { if (t_loader != nil) delete t_loader; // PM-2015-10-20: [[ Bug 15256 ]] Prevent crash when loading a remote image and there is no internet connection if (t_stream != nil) MCS_close(t_stream); } return t_success; }
char *MCVideoClip::getfile() { if (frames != NULL) { char *tmpfile = strclone(MCS_tmpnam()); IO_handle tstream; if ((tstream = MCS_open(tmpfile, IO_WRITE_MODE, False, False, 0)) == NULL) { delete tmpfile; return NULL; } IO_stat stat = IO_write(frames, sizeof(int1), size, tstream); MCS_close(tstream); if (stat != IO_NORMAL) { MCS_unlink(tmpfile); delete tmpfile; return NULL; } return tmpfile; } return NULL; }
void MCArraysEvalArrayDecode(MCExecContext& ctxt, MCDataRef p_encoding, MCArrayRef& r_array) { bool t_success; t_success = true; IO_handle t_stream_handle; t_stream_handle = nil; if (t_success) { t_stream_handle = MCS_fakeopen(MCDataGetBytePtr(p_encoding), MCDataGetLength(p_encoding)); if (t_stream_handle == nil) t_success = false; } uint8_t t_type; if (t_success) if (IO_read_uint1(&t_type, t_stream_handle) != IO_NORMAL) t_success = false; // AL-2014-05-01: [[ Bug 11989 ]] If the type is 'empty' then just return the empty array. if (t_success && t_type == kMCEncodedValueTypeEmpty) { r_array = MCValueRetain(kMCEmptyArray); return; } // AL-2014-05-15: [[ Bug 12203 ]] Check initial byte for version 7.0 encoded array. bool t_legacy; t_legacy = t_type < kMCEncodedValueTypeArray; MCArrayRef t_array; t_array = nil; if (t_success) t_success = MCArrayCreateMutable(t_array); if (t_legacy) { if (t_success) if (MCS_putback(t_type, t_stream_handle) != IO_NORMAL) t_success = false; MCObjectInputStream *t_stream; t_stream = nil; if (t_success) { t_stream = new MCObjectInputStream(t_stream_handle, MCDataGetLength(p_encoding), false); if (t_stream == nil) t_success = false; } if (t_success) if (t_stream -> ReadU8(t_type) != IO_NORMAL) t_success = false; if (t_success) if (MCArrayLoadFromStreamLegacy(t_array, *t_stream) != IO_NORMAL) t_success = false; delete t_stream; } else { if (t_success) if (IO_read_valueref_new((MCValueRef &)t_array, t_stream_handle) != IO_NORMAL) t_success = false; } MCS_close(t_stream_handle); if (t_success) { r_array = t_array; return; } MCValueRelease(t_array); ctxt . Throw(); }
bool MCDispatch::isolatedsend(const char *p_stack_data, uint32_t p_stack_data_length, const char *p_message, MCParameter *p_parameters) { Boolean t_old_allow_interrupts; MCStack *t_old_stacks; MCObjectList *t_old_frontscripts, *t_old_backscripts; MCStack **t_old_using; uint2 t_old_nusing; MCStack *t_old_defaultstack; MCStack *t_old_staticdefaultstack; MCStack *t_old_topstackptr; t_old_allow_interrupts = MCallowinterrupts; t_old_stacks = stacks; t_old_frontscripts = MCfrontscripts; t_old_backscripts = MCbackscripts; t_old_using = MCusing; t_old_nusing = MCnusing; t_old_defaultstack = MCdefaultstackptr; t_old_staticdefaultstack = MCstaticdefaultstackptr; t_old_topstackptr = MCtopstackptr; MCallowinterrupts = False; stacks = nil; MCnusing = 0; MCusing = nil; MCbackscripts = nil; MCfrontscripts = nil; // Load the stack MCExecPoint ep; ep . setstaticbytes(p_stack_data, p_stack_data_length); MCDecompress::do_decompress(ep, 0, 0); bool t_success; MCStack *t_stack; IO_handle t_stream; t_success = false; t_stack = nil; t_stream = MCS_fakeopen(ep . getsvalue()); if (MCdispatcher -> readfile(NULL, NULL, t_stream, t_stack) == IO_NORMAL) { MCdefaultstackptr = MCstaticdefaultstackptr = MCtopstackptr = stacks; MCAutoNameRef t_message_name; /* UNCHECKED */ t_message_name . CreateWithCString(p_message); if (t_stack -> message(t_message_name, p_parameters, True, True, False) == ES_NORMAL) t_success = true; destroystack(t_stack, True); } MCS_close(t_stream); memset((void *)ep . getsvalue() . getstring(), 0, ep . getsvalue() . getlength()); ep . clear(); MCtopstackptr = t_old_topstackptr; MCstaticdefaultstackptr = t_old_staticdefaultstack; MCdefaultstackptr = t_old_defaultstack; MCnusing = t_old_nusing; MCusing = t_old_using; MCbackscripts = t_old_backscripts; MCfrontscripts = t_old_frontscripts; stacks = t_old_stacks; MCallowinterrupts = t_old_allow_interrupts; return t_success; }
IO_stat MCDispatch::startup(void) { IO_stat stat; MCStack *sptr; // set up image cache before the first stack is opened MCCachedImageRep::init(); startdir = MCS_getcurdir(); enginedir = strclone(MCcmd); char *eptr; eptr = strrchr(enginedir, PATH_SEPARATOR); if (eptr != NULL) *eptr = '\0'; else *enginedir = '\0'; MCExecPoint ep; ep . setstaticbytes(MCstartupstack, MCstartupstack_length); MCDecompress::do_decompress(ep, 0, 0); IO_handle stream = MCS_fakeopen(ep . getsvalue()); if ((stat = MCdispatcher -> readfile(NULL, NULL, stream, sptr)) != IO_NORMAL) { MCS_close(stream); return stat; } MCS_close(stream); memset((void *)ep . getsvalue() . getstring(), 0, ep . getsvalue() . getlength()); ep . clear(); // Temporary fix to make sure environment stack doesn't get lost behind everything. #if defined(_MACOSX) ProcessSerialNumber t_psn = { 0, kCurrentProcess }; SetFrontProcess(&t_psn); #elif defined(_WINDOWS) SetForegroundWindow(((MCScreenDC *)MCscreen) -> getinvisiblewindow()); #endif MCenvironmentactive = True; sptr -> setfilename(strclone(MCcmd)); MCdefaultstackptr = MCstaticdefaultstackptr = stacks; { MCdefaultstackptr -> setextendedstate(true, ECS_DURING_STARTUP); MCdefaultstackptr -> message(MCM_start_up, nil, False, True); MCdefaultstackptr -> setextendedstate(false, ECS_DURING_STARTUP); } if (!MCquit) { MCresult -> fetch(ep); ep . appendchar('\0'); if (ep . getsvalue() . getlength() == 1) { sptr -> open(); MCImage::init(); X_main_loop(); MCresult -> fetch(ep); ep . appendchar('\0'); if (ep . getsvalue() . getlength() == 1) return IO_NORMAL; } if (sptr -> getscript() != NULL) memset(sptr -> getscript(), 0, strlen(sptr -> getscript())); destroystack(sptr, True); MCtopstackptr = NULL; MCquit = False; MCenvironmentactive = False; send_relaunch(); sptr = findstackname(ep . getsvalue() . getstring()); if (sptr == NULL && (stat = loadfile(ep . getsvalue() . getstring(), sptr)) != IO_NORMAL) return stat; } if (!MCquit) { // OK-2007-11-13 : Bug 5525, after opening the IDE engine, the allowInterrupts should always default to false, // regardless of what the environment stack may have set it to. MCallowinterrupts = true; sptr -> setparent(this); MCdefaultstackptr = MCstaticdefaultstackptr = stacks; send_startup_message(false); if (!MCquit) sptr -> open(); } return IO_NORMAL; }
bool MCEncodedImageRep::LoadImageFrames(MCImageFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied) { bool t_success = true; // IM-2013-02-18 - switching this back to using MCImageImport as we need to // determine the compression type for m_compression IO_handle t_stream = nil; IO_handle t_mask_stream = nil; MCImageCompressedBitmap *t_compressed = nil; MCImageBitmap *t_bitmap = nil; MCPoint t_hotspot = {1, 1}; char *t_name = nil; t_success = GetDataStream(t_stream) && MCImageImport(t_stream, t_mask_stream, t_hotspot, t_name, t_compressed, t_bitmap); if (t_stream != nil) MCS_close(t_stream); MCImageFrame *t_frames; t_frames = nil; uindex_t t_frame_count; t_frame_count = 0; if (t_success) { if (t_compressed != nil) t_success = MCImageDecompress(t_compressed, t_frames, t_frame_count); else { t_success = MCMemoryNewArray(1, t_frames); if (t_success) { t_frames[0].image = t_bitmap; t_frames[0].density = 1.0; t_bitmap = nil; t_frame_count = 1; } } } if (t_success) { m_width = t_frames[0].image->width; m_height = t_frames[0].image->height; if (t_compressed != nil) m_compression = t_compressed->compression; m_have_geometry = true; r_frames = t_frames; r_frame_count = t_frame_count; r_frames_premultiplied = false; } MCCStringFree(t_name); MCImageFreeBitmap(t_bitmap); MCImageFreeCompressedBitmap(t_compressed); return t_success; }
Exec_stat exec(MCExecPoint& ep) { bool t_success; t_success = true; char *t_old_filename; t_old_filename = nil; if (t_success && m_old_file -> eval(ep) == ES_NORMAL) t_old_filename = ep . getsvalue() . clone(); else t_success = false; char *t_new_filename; t_new_filename = nil; if (t_success && m_new_file -> eval(ep) == ES_NORMAL) t_new_filename = ep . getsvalue() . clone(); else t_success = false; char *t_patch_filename; t_patch_filename = nil; if (t_success && m_patch_file -> eval(ep) == ES_NORMAL) t_patch_filename = ep . getsvalue() . clone(); else t_success = false; IO_handle t_old_handle; t_old_handle = nil; if (t_success) { t_old_handle = MCS_open(t_old_filename, IO_READ_MODE, False, False, 0); if (t_old_handle == nil) t_success = false; } IO_handle t_new_handle; t_new_handle = nil; if (t_success) { t_new_handle = MCS_open(t_new_filename, IO_READ_MODE, False, False, 0); if (t_new_handle == nil) t_success = false; } IO_handle t_patch_handle; t_patch_handle = nil; if (t_success) { t_patch_handle = MCS_open(t_patch_filename, IO_WRITE_MODE, False, False, 0); if (t_patch_handle == nil) t_success = false; } if (t_success) { InputStream t_new_stream, t_old_stream; OutputStream t_patch_stream; t_new_stream . handle = t_new_handle; t_old_stream . handle = t_old_handle; t_patch_stream . handle = t_patch_handle; t_success = MCBsDiffBuild(&t_old_stream, &t_new_stream, &t_patch_stream); } if (t_success) MCresult -> clear(); else MCresult -> sets("patch building failed"); if (t_patch_handle != nil) MCS_close(t_patch_handle); if (t_new_handle != nil) MCS_close(t_new_handle); if (t_old_handle != nil) MCS_close(t_old_handle); delete t_patch_filename; delete t_new_filename; delete t_old_filename; return ES_NORMAL; }
void exec_ctxt(MCExecContext &ctxt) { bool t_success; t_success = true; MCAutoStringRef t_old_filename; if (!ctxt . EvalExprAsStringRef(m_old_file, EE_INTERNAL_BSDIFF_BADOLD, &t_old_filename)) return; MCAutoStringRef t_new_filename; if (!ctxt . EvalExprAsStringRef(m_new_file, EE_INTERNAL_BSDIFF_BADNEW, &t_new_filename)) return; MCAutoStringRef t_patch_filename; if (!ctxt . EvalExprAsStringRef(m_patch_file, EE_INTERNAL_BSDIFF_BADPATCH, &t_patch_filename)) return; IO_handle t_old_handle; t_old_handle = nil; if (t_success) { t_old_handle = MCS_open(*t_old_filename, kMCOpenFileModeRead, False, False, 0); if (t_old_handle == nil) t_success = false; } IO_handle t_new_handle; t_new_handle = nil; if (t_success) { t_new_handle = MCS_open(*t_new_filename, kMCOpenFileModeRead, False, False, 0); if (t_new_handle == nil) t_success = false; } IO_handle t_patch_handle; t_patch_handle = nil; if (t_success) { t_patch_handle = MCS_open(*t_patch_filename, kMCOpenFileModeWrite, False, False, 0); if (t_patch_handle == nil) t_success = false; } if (t_success) { InputStream t_new_stream, t_old_stream; OutputStream t_patch_stream; t_new_stream . handle = t_new_handle; t_old_stream . handle = t_old_handle; t_patch_stream . handle = t_patch_handle; t_success = MCBsDiffBuild(&t_old_stream, &t_new_stream, &t_patch_stream); } if (t_success) ctxt . SetTheResultToEmpty(); else ctxt . SetTheResultToCString("patch building failed"); if (t_patch_handle != nil) MCS_close(t_patch_handle); if (t_new_handle != nil) MCS_close(t_new_handle); if (t_old_handle != nil) MCS_close(t_old_handle); }
void MCStack::effectrect(const MCRectangle& p_area, Boolean& r_abort) { // Get the list of effects. MCEffectList *t_effects = MCcur_effects; MCcur_effects = NULL; // If the window isn't opened or hasn't been attached (plugin) or if we have no // snapshot to use, this is a no-op. if (!opened || !haswindow() || m_snapshot == nil) { while(t_effects != NULL) { MCEffectList *t_effect; t_effect = t_effects; t_effects = t_effects -> next; delete t_effect; } return; } // Mark the stack as being in an effect. state |= CS_EFFECT; // Lock messages while the effect is happening. Boolean t_old_lockmessages; t_old_lockmessages = MClockmessages; MClockmessages = True; // Calculate the area of interest. MCRectangle t_effect_area; t_effect_area = curcard -> getrect(); t_effect_area . y = getscroll(); t_effect_area . height -= t_effect_area . y; t_effect_area = MCU_intersect_rect(t_effect_area, p_area); // IM-2013-08-21: [[ ResIndependence ]] Scale effect area to device coords // Align snapshot rect to device pixels // IM-2013-09-30: [[ FullscreenMode ]] Use stack transform to get device coords MCGAffineTransform t_transform; t_transform = getdevicetransform(); // MW-2013-10-29: [[ Bug 11330 ]] Make sure the effect area is cropped to the visible // area. t_effect_area = MCRectangleGetTransformedBounds(t_effect_area, getviewtransform()); t_effect_area = MCU_intersect_rect(t_effect_area, MCU_make_rect(0, 0, view_getrect() . width, view_getrect() . height)); // IM-2014-01-24: [[ HiDPI ]] scale effect region to backing surface coords MCGFloat t_scale; t_scale = view_getbackingscale(); MCRectangle t_device_rect, t_user_rect; t_device_rect = MCRectangleGetScaledBounds(t_effect_area, t_scale); t_user_rect = MCRectangleGetTransformedBounds(t_device_rect, MCGAffineTransformInvert(t_transform)); // IM-2013-08-29: [[ RefactorGraphics ]] get device height for CoreImage effects // IM-2013-09-30: [[ FullscreenMode ]] Use view rect to get device height uint32_t t_device_height; t_device_height = floor(view_getrect().height * t_scale); // Make a region of the effect area // IM-2013-08-29: [[ ResIndependence ]] scale effect region to device coords MCRegionRef t_effect_region; t_effect_region = nil; /* UNCHECKED */ MCRegionCreate(t_effect_region); /* UNCHECKED */ MCRegionSetRect(t_effect_region, t_effect_area); #ifndef FEATURE_PLATFORM_PLAYER #if defined(FEATURE_QUICKTIME) // MW-2010-07-07: Make sure QT is only loaded if we actually are doing an effect if (t_effects != nil) if (!MCdontuseQTeffects) if (!MCtemplateplayer -> isQTinitted()) MCtemplateplayer -> initqt(); #endif #endif // Lock the screen to prevent any updates occuring until we want them. MCRedrawLockScreen(); // By default, we have not aborted. r_abort = False; MCGImageRef t_initial_image; t_initial_image = MCGImageRetain(m_snapshot); while(t_effects != nil) { uint32_t t_duration; t_duration = MCU_max(1, MCeffectrate / (t_effects -> speed - VE_VERY)); if (t_effects -> type == VE_DISSOLVE) t_duration *= 2; uint32_t t_delta; t_delta = 0; // Create surface at effect_area size. // Render into surface based on t_effects -> image MCGImageRef t_final_image = nil; // If this isn't a plain effect, then we must fetch first and last images. if (t_effects -> type != VE_PLAIN) { // Render the final image. MCGContextRef t_context = nil; // IM-2014-05-20: [[ GraphicsPerformance ]] Create opaque context for snapshot /* UNCHECKED */ MCGContextCreate(t_device_rect.width, t_device_rect.height, false, t_context); MCGContextTranslateCTM(t_context, -t_device_rect.x, -t_device_rect.y); // IM-2013-10-03: [[ FullscreenMode ]] Apply device transform to context MCGContextConcatCTM(t_context, t_transform); // Configure the context. MCGContextClipToRect(t_context, MCRectangleToMCGRectangle(t_user_rect)); // Render an appropriate image switch(t_effects -> image) { case VE_INVERSE: { MCContext *t_old_context = nil; /* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context); curcard->draw(t_old_context, t_user_rect, false); delete t_old_context; MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0); MCGContextSetBlendMode(t_context, kMCGBlendModeDifference); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); } break; case VE_BLACK: MCGContextSetFillRGBAColor(t_context, 0.0, 0.0, 0.0, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; case VE_WHITE: MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; case VE_GRAY: MCGContextSetFillRGBAColor(t_context, 0.5, 0.5, 0.5, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; default: { MCContext *t_old_context = nil; /* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context); curcard->draw(t_old_context, t_user_rect, false); delete t_old_context; } } /* UNCHECKED */ MCGContextCopyImage(t_context, t_final_image); MCGContextRelease(t_context); } MCStackEffectContext t_context; t_context.delta = t_delta; t_context.duration = t_duration; t_context.effect = t_effects; t_context.effect_area = t_device_rect; t_context.initial_image = t_initial_image; t_context.final_image = t_final_image; // MW-2011-10-20: [[ Bug 9824 ]] Make sure dst point is correct. // Initialize the destination with the start image. view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderInitial, &t_context); // If there is a sound, then start playing it. if (t_effects -> sound != NULL) { MCAudioClip *acptr; MCNewAutoNameRef t_sound; /* UNCHECKED */ MCNameCreate(t_effects->sound, &t_sound); if ((acptr = (MCAudioClip *)getobjname(CT_AUDIO_CLIP, *t_sound)) == NULL) { IO_handle stream; if ((stream = MCS_open(t_effects->sound, kMCOpenFileModeRead, True, False, 0)) != NULL) { acptr = new MCAudioClip; acptr->setdisposable(); if (!acptr->import(t_effects->sound, stream)) { delete acptr; acptr = NULL; } MCS_close(stream); } } if (acptr != NULL) { MCU_play_stop(); MCacptr = acptr; MCU_play(); #ifndef FEATURE_PLATFORM_AUDIO if (MCacptr != NULL) MCscreen->addtimer(MCacptr, MCM_internal, PLAY_RATE); #endif } if (MCscreen->wait((real8)MCsyncrate / 1000.0, False, True)) { r_abort = True; break; } } // Initialize CoreImage of QTEffects if needed. if (t_effects -> type != VE_PLAIN) { MCAutoPointer<char> t_name; /* UNCHECKED */ MCStringConvertToCString(t_effects -> name, &t_name); #ifdef _MAC_DESKTOP // IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for CI effects if (t_effects -> type == VE_UNDEFINED && MCCoreImageEffectBegin(*t_name, t_initial_image, t_final_image, t_device_rect, t_device_height, t_effects -> arguments)) t_effects -> type = VE_CIEFFECT; else #endif #ifdef FEATURE_QUICKTIME_EFFECTS // IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for QT effects if (t_effects -> type == VE_UNDEFINED && MCQTEffectBegin(t_effects -> type, *t_name, t_effects -> direction, t_initial_image, t_final_image, t_device_rect)) t_effects -> type = VE_QTEFFECT; #else ; #endif } // Run effect // Now perform the effect loop, but only if there is something to do. if (t_effects -> type != VE_PLAIN || old_blendlevel != blendlevel) { // Calculate timing parameters. double t_start_time; t_start_time = 0.0; for(;;) { t_context.delta = t_delta; Boolean t_drawn = False; view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderEffect, &t_context); // Now redraw the window with the new image. // if (t_drawn) { MCscreen -> sync(getw()); } // Update the window's blendlevel (if needed) if (old_blendlevel != blendlevel) { float t_fraction = float(t_delta) / t_duration; setopacity(uint1((old_blendlevel * 255 + (float(blendlevel) - old_blendlevel) * 255 * t_fraction) / 100)); } // If the start time is zero, then start counting from here. if (t_start_time == 0.0) t_start_time = MCS_time(); // If we've reached the end of the transition, we are done. if (t_delta == t_duration) { #ifdef _ANDROID_MOBILE // MW-2011-12-12: [[ Bug 9907 ]] Make sure we let the screen sync at this point MCscreen -> wait(0.01, False, False); #endif break; } // Get the time now. double t_now; t_now = MCS_time(); // Compute the new delta value. uint32_t t_new_delta; t_new_delta = (uint32_t)ceil((t_now - t_start_time) * 1000.0); // If the new value is same as the old, then advance one step. if (t_new_delta == t_delta) t_delta = t_new_delta + 1; else t_delta = t_new_delta; // If the new delta is beyond the end point, set it to the end. if (t_delta > t_duration) t_delta = t_duration; // Wait until the next boundary, making sure we break for no reason // other than abort. if (MCscreen -> wait((t_start_time + (t_delta / 1000.0)) - t_now, False, False)) r_abort = True; // If we aborted, we render the final step and are thus done. if (r_abort) t_delta = t_duration; } } #ifdef _MAC_DESKTOP if (t_effects -> type == VE_CIEFFECT) MCCoreImageEffectEnd(); else #endif #ifdef FEATURE_QUICKTIME_EFFECTS if (t_effects -> type == VE_QTEFFECT) MCQTEffectEnd(); #endif // Free initial surface. MCGImageRelease(t_initial_image); // initial surface becomes final surface. t_initial_image = t_final_image; t_final_image = nil; // Move to the next effect. MCEffectList *t_current_effect; t_current_effect = t_effects; t_effects = t_effects -> next; delete t_current_effect; } // Make sure the pixmaps are freed and any dangling effects // are cleaned up. if (t_effects != NULL) { /* OVERHAUL - REVISIT: error cleanup needs revised */ MCGImageRelease(t_initial_image); // MCGSurfaceRelease(t_final_image); while(t_effects != NULL) { MCEffectList *t_current_effect; t_current_effect = t_effects; t_effects = t_effects -> next; delete t_current_effect; } } MCRegionDestroy(t_effect_region); MCGImageRelease(m_snapshot); m_snapshot = nil; m_snapshot = t_initial_image; // Unlock the screen. MCRedrawUnlockScreen(); // Unlock messages. MClockmessages = t_old_lockmessages; // Turn off effect mode. state &= ~CS_EFFECT; // The stack's blendlevel is now the new one. old_blendlevel = blendlevel; // Finally, mark the affected area of the stack for a redraw. dirtyrect(p_area); }
IO_stat MCDispatch::loadfile(const char *inname, MCStack *&sptr) { IO_handle stream; char *openpath = NULL; char *fname = strclone(inname); if ((stream = MCS_open(fname, IO_READ_MODE, True, False, 0)) != NULL) if (fname[0] != PATH_SEPARATOR && fname[1] != ':') { char *curpath = MCS_getcurdir(); if (curpath[strlen(curpath) - 1] == '/') curpath[strlen(curpath) - 1] = '\0'; openpath = new char[strlen(curpath) + strlen(fname) + 2]; sprintf(openpath, "%s/%s", curpath, fname); delete curpath; } else openpath = strclone(fname); else { char *tmparray = new char[strlen(fname) + 1]; strcpy(tmparray, fname); char *tname = strrchr(tmparray, PATH_SEPARATOR); if (tname == NULL) tname = tmparray; else tname++; if ((stream = MCS_open(tname, IO_READ_MODE, True, False, 0)) != NULL) { char *curpath = MCS_getcurdir(); openpath = new char[strlen(curpath) + strlen(tname) + 2]; sprintf(openpath, "%s/%s", curpath, tname); delete curpath; } else { if (!openstartup(tname, &openpath, stream) && !openenv(tname, "MCPATH", &openpath, stream, 0) && !openenv(tname, "PATH", &openpath, stream, 0)) { char *homename; if ((homename = MCS_getenv("HOME")) != NULL) { openpath = new char[strlen(homename) + strlen(tname) + 13]; if (homename[strlen(homename) - 1] == '/') homename[strlen(homename) - 1] = '\0'; sprintf(openpath, "%s/%s", homename, tname); if ((stream = MCS_open(openpath, IO_READ_MODE, True, False, 0)) == NULL) { sprintf(openpath, "%s/stacks/%s", homename, tname); if ((stream = MCS_open(openpath, IO_READ_MODE, True, False, 0)) == NULL) { sprintf(openpath, "%s/components/%s", homename, tname); if ((stream = MCS_open(openpath, IO_READ_MODE, True, False, 0)) == NULL) { delete openpath; openpath = NULL; } } } } } } delete tmparray; } if (stream == NULL) { if (openpath != NULL) delete openpath; delete fname; return IO_ERROR; } delete fname; IO_stat stat = readfile(openpath, inname, stream, sptr); delete openpath; MCS_close(stream); return stat; }
bool MCVariableValue::decode(const MCString& p_value) { IO_handle t_stream_handle; t_stream_handle = MCS_fakeopen(p_value); if (t_stream_handle == NULL) return false; MCObjectInputStream *t_stream = nil; t_stream = new MCObjectInputStream(t_stream_handle, p_value . getlength()); if (t_stream == NULL) { MCS_close(t_stream_handle); return false; } IO_stat t_stat; t_stat = IO_NORMAL; uint8_t t_type; t_stat = t_stream -> ReadU8(t_type); if (t_stat == IO_NORMAL) { switch(t_type) { case kMCEncodedValueTypeUndefined: clear(); break; case kMCEncodedValueTypeEmpty: assign_empty(); break; case kMCEncodedValueTypeString: { uint32_t t_length; t_stat = t_stream -> ReadU32(t_length); if (t_stat == IO_NORMAL) { char *t_value; t_value = new char[t_length]; if (t_value != NULL) assign_buffer(t_value, t_length); else t_stat = IO_ERROR; } } break; case kMCEncodedValueTypeNumber: { double t_value; t_stat = t_stream -> ReadFloat64(t_value); if (t_stat == IO_NORMAL) assign_real(t_value); } break; case kMCEncodedValueTypeArray: t_stat = loadarray(*t_stream, false); break; default: t_stat = IO_ERROR; break; } } delete t_stream; MCS_close(t_stream_handle); set_dbg_changed(true); return t_stat == IO_NORMAL; }
IO_stat MCDispatch::dosavestack(MCStack *sptr, const MCString &fname) { if (MCModeCheckSaveStack(sptr, fname) != IO_NORMAL) return IO_ERROR; char *linkname; if (fname.getlength() != 0) linkname = fname.clone(); else if ((linkname = strclone(sptr->getfilename())) == NULL) { MCresult->sets("stack does not have a filename"); return IO_ERROR; } if (linkname == NULL) { MCresult->sets("can't open stack file, bad path"); return IO_ERROR; } if (MCS_noperm(linkname)) { MCresult->sets("can't open stack file, no permission"); delete linkname; return IO_ERROR; } char *oldfiletype = MCfiletype; MCfiletype = MCstackfiletype; char *backup = new char[strlen(linkname) + 2]; strcpy(backup, linkname); strcat(backup, "~"); MCS_unlink(backup); if (MCS_exists(linkname, True) && !MCS_backup(linkname, backup)) { MCresult->sets("can't open stack backup file"); MCfiletype = oldfiletype; delete linkname; delete backup; return IO_ERROR; } IO_handle stream; if ((stream = MCS_open(linkname, IO_WRITE_MODE, True, False, 0)) == NULL) { MCresult->sets("can't open stack file"); cleanup(stream, linkname, backup); MCfiletype = oldfiletype; return IO_ERROR; } MCfiletype = oldfiletype; MCString errstring = "Error writing stack (disk full?)"; // MW-2012-03-04: [[ StackFile5500 ]] Work out what header to emit, and the size. const char *t_header; uint32_t t_header_size; if (MCstackfileversion >= 5500) t_header = newheader5500, t_header_size = 8; else if (MCstackfileversion >= 2700) t_header = newheader, t_header_size = 8; else t_header = header, t_header_size = HEADERSIZE; if (IO_write(t_header, sizeof(char), t_header_size, stream) != IO_NORMAL || IO_write_uint1(CHARSET, stream) != IO_NORMAL) { MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } if (IO_write_uint1(OT_NOTHOME, stream) != IO_NORMAL || IO_write_string(NULL, stream) != IO_NORMAL) { // was stackfiles MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } // MW-2012-02-22; [[ NoScrollSave ]] Adjust the rect by the current group offset. MCgroupedobjectoffset . x = 0; MCgroupedobjectoffset . y = 0; MCresult -> clear(); if (sptr->save(stream, 0, false) != IO_NORMAL || IO_write_uint1(OT_END, stream) != IO_NORMAL) { if (MCresult -> isclear()) MCresult->sets(errstring); cleanup(stream, linkname, backup); return IO_ERROR; } MCS_close(stream); uint2 oldmask = MCS_umask(0); uint2 newmask = ~oldmask & 00777; if (oldmask & 00400) newmask &= ~00100; if (oldmask & 00040) newmask &= ~00010; if (oldmask & 00004) newmask &= ~00001; MCS_umask(oldmask); MCS_chmod(linkname, newmask); if (sptr->getfilename() != NULL && !strequal(linkname, sptr->getfilename())) MCS_copyresourcefork(sptr->getfilename(), linkname); else if (sptr -> getfilename() != NULL) MCS_copyresourcefork(backup, linkname); sptr->setfilename(linkname); if (backup != NULL) { MCS_unlink(backup); delete backup; } return IO_NORMAL; }