Beispiel #1
0
MCStreamCache::~MCStreamCache()
{
	if (m_cache_file)
		MCS_close(m_cache_file);
	if (m_cache_buffer)
		MCMemoryDeallocate(m_cache_buffer);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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));
}
Beispiel #5
0
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;
}
Beispiel #6
0
void MCEncodedImageRep::ClearImageLoader()
{
	if (m_loader != nil)
	{
		delete m_loader;
		m_loader = nil;
	}
	if (m_stream != nil)
	{
		MCS_close(m_stream);
		m_stream = nil;
	}
}
Beispiel #7
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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();
}
Beispiel #11
0
// 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;
}
Beispiel #12
0
// 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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #20
0
	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);
	}
Beispiel #22
0
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);
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}