예제 #1
0
		int32_t DeflateStreamDecompressor::Init()
		{
			EAW_ASSERT_MSG(!mInitialized, "Already Initialized"); //TODO: Change this for redirection
			EAW_ASSERT_MSG(mStreamType != EA::EAWEBKIT_PACKAGE_NAMESPACE::eStreamTypeNone, "Need correct stream type before it can initialize"); //TODO: Change this for redirection

			int status = 0;
			if(!mInitialized)
			{
				mZStream = (z_stream*)(ACCESS_EAWEBKIT_API(GetAllocator())->Malloc(sizeof(z_stream),0,0));

				mZStream->zalloc = (alloc_func)EAWEBKIT_ZLIB_ALLOC;
				mZStream->zfree = (free_func)EAWEBKIT_ZLIB_FREE;
				mZStream->opaque = Z_NULL;
				mZStream->next_in = Z_NULL;
				mZStream->avail_in = 0;

				switch(mStreamType)
				{
				case eStreamTypeZLib:
					status = inflateInit(mZStream);
					break;
				case eStreamTypeRaw:
					status = inflateInit2(mZStream,-MAX_WBITS);
					break;
				case eStreamTypeGZip:
					//Since we are using an old version of ZLib, the library lacks support of transparent initialization of such stream.
					//In newer versions, one can call inflateInit2(mZStream,-MAX_WBITS+32); to do this.
					//We expect the stream header to be removed at this point.
					status = inflateInit2(mZStream,-MAX_WBITS);
					break;
				default:
					EAW_ASSERT_MSG(false, "Unknown stream format"); 
				}
				

				if(status == Z_OK)
				{
					mInitialized = true;
				}
				else
				{
					char debugBuffer[64];
					sprintf(debugBuffer, "Error initializing decompressor - %d", status);
					EAW_ASSERT_MSG(false, debugBuffer);
				}
				
			}

			return status;

		}
예제 #2
0
void SetCookieUsage(const EA::WebKit::CookieInfo& cookieInfo)
{
	if (!cookieInfo.mCookieFilePath || !cookieInfo.mCookieFilePath[0] ) 
	{
		EAW_ASSERT_MSG(false,"Cookies persistence disabled. Invalid cookie file path.");
		return;
	}
	
	const char8_t* pCookieFilePath = cookieInfo.mCookieFilePath;

	EA::IO::Path::PathString8 fullPath;
	if(pCookieFilePath)
	{
        fullPath.assign(GetFullPath(pCookieFilePath, true));
		if(!fullPath.empty())
		{
			pCookieFilePath = fullPath.c_str();
		}
	}

	WebCore::ResourceHandleManager* pRHM = WebCore::ResourceHandleManager::sharedInstance();
	EA::WebKit::CookieManager* pCM = pRHM->GetCookieManager();   
	CookieManagerParameters    params(pCookieFilePath, cookieInfo.mMaxIndividualCookieSize, 
									cookieInfo.mDiskCookieStorageSize, cookieInfo.mMaxCookieCount);
	pCM->SetParametersAndInitialize(params);
}
예제 #3
0
void ClearMemoryCache()
{
	// This code is ported from Qt port. This would free up as much memory as possible.
	if (!WebCore::memoryCache()->disabled()) 
	{
		WebCore::memoryCache()->setDisabled(true);
		WebCore::memoryCache()->setDisabled(false);
	}

	int pageCapacity = WebCore::pageCache()->capacity();
	EAW_ASSERT_MSG(pageCapacity == 0, "We should not use page cache");
	// Setting size to 0, makes all pages be released.
	WebCore::pageCache()->setCapacity(0);
	WebCore::pageCache()->releaseAutoreleasedPagesNow();
	WebCore::pageCache()->setCapacity(pageCapacity);

	// Invalidating the font cache and freeing all inactive font data.
	WebCore::fontCache()->invalidate();

	// Empty the Cross-Origin Preflight cache
	WebCore::CrossOriginPreflightResultCache::shared().empty();

	// abaldeva: After freeing up the cache, we set the RAM Cache back to what user intends it to be.
	// If the user wants to disable the RAM Cache, they can call that API directly with 0 values.
	SetRAMCacheUsage(sRamCacheInfo);

}
예제 #4
0
void setFireTimerRate(EA::WebKit::FireTimerRate rate)
{
    double adjustedRate;

    switch (rate)
    {
        case EA::WebKit::kFireTimerRate120Hz:
            adjustedRate = 1.0/120.0;     
            break;
        
        case EA::WebKit::kFireTimerRate60Hz:
            adjustedRate = 1.0/60.0; 
            break;
        
        case EA::WebKit::kFireTimerRate30Hz:
            adjustedRate = 1.0/30.0;         
            break;

        case EA::WebKit::kFireTimerRate20Hz:
            adjustedRate = 1.0/20.0; 
            break;

        case EA::WebKit::kFireTimerRate15Hz:
            adjustedRate = 1.0/15.0; 
            break;

        default:        
            EAW_ASSERT_MSG(false, "Invalid rate. Using default 60 Hz");  // Invalid rate
            adjustedRate = 1.0/60.0;         
            break;
    }

    sFireTimerRate = adjustedRate;
}
예제 #5
0
void SetPlatformSocketAPI(const EA::WebKit::PlatformSocketAPI& platformSocketAPI)
{
#if ENABLE(DIRTYSDK_IN_DLL)  
	PlatformSocketAPICallbacks* socketCallbacks = GetPlatformSocketAPICallbacksInstance();
	if(socketCallbacks)
	{
		socketCallbacks->accept			=  platformSocketAPI.accept;
		socketCallbacks->bind			=  platformSocketAPI.bind;
		socketCallbacks->connect		=  platformSocketAPI.connect;
		socketCallbacks->gethostbyaddr	=  platformSocketAPI.gethostbyaddr;
		socketCallbacks->gethostbyname	=  platformSocketAPI.gethostbyname;
		socketCallbacks->dnslookup		=  platformSocketAPI.dnslookup;	
		socketCallbacks->getpeername	=  platformSocketAPI.getpeername;
		socketCallbacks->getsockopt		=  platformSocketAPI.getsockopt;
		socketCallbacks->listen			=  platformSocketAPI.listen;
		socketCallbacks->recv			=  platformSocketAPI.recv;
		socketCallbacks->recvfrom		=  platformSocketAPI.recvfrom;
		socketCallbacks->send			=  platformSocketAPI.send;
		socketCallbacks->sendto			=  platformSocketAPI.sendto;
		socketCallbacks->setsockopt		=  platformSocketAPI.setsockopt;
		socketCallbacks->shutdown		=  platformSocketAPI.shutdown;
		socketCallbacks->socket			=  platformSocketAPI.socket;
		socketCallbacks->close			=  platformSocketAPI.close;
		socketCallbacks->poll			=  platformSocketAPI.poll;
		socketCallbacks->getlasterror	=  platformSocketAPI.getlasterror;
	}
#else
	EAW_ASSERT_MSG(false, "Invalid call. Calling SetPlatformSocketAPI without enabling the DirtySDK code in DLL\n");
#endif
}
예제 #6
0
bool FileSystemDefault::DeleteDirectory(const char* path)
{
    // The following is copied from the EAIO package.
    // This code is not smart enough to do a recursive delete, but the one in EAIO is.
	// We need to implement a recursive delete.

    // Windows doesn't like it when the directory path ends with a 
    // separator (e.g. '\') character, so we correct for this if needed.
    if(path && *path)
	{

		const size_t nStrlen = strlen(path);

		if((path[nStrlen - 1] != '/') && (path[nStrlen - 1] != '\\'))
		{
			#if defined(EA_PLATFORM_MICROSOFT)
				return (RemoveDirectoryA(path) != 0);
			#elif defined(EA_PLATFORM_UNIX) || defined(CS_UNDEFINED_STRING)
				return (rmdir(path) == 0);
			#endif
		}

		// Else we need to remove the separator.
		char pathMod[EA::WebKit::FileSystem::kMaxPathLength];
		EAW_ASSERT_MSG(nStrlen < EA::WebKit::FileSystem::kMaxPathLength, "Directory path exceeds max path length");
		memcpy(pathMod, path, nStrlen - 1);   // Force 0 terminator in place of directory separator
		pathMod[nStrlen - 1] = 0;

		return DeleteDirectory(pathMod);  // Call ourselves recursively.
	}
	
	return false;
}
예제 #7
0
bool FileSystemDefault::MakeDirectoryInternal(const char* path)
{
	if(path && *path)
	{
		const size_t nStrlen = strlen(path);

		if((path[nStrlen - 1] != '/') && (path[nStrlen - 1] != '\\'))
		{
#if defined(EA_PLATFORM_MICROSOFT)

			const BOOL bResult = CreateDirectoryA(path, NULL);
			return bResult || (GetLastError() == ERROR_ALREADY_EXISTS);

#elif defined(EA_PLATFORM_UNIX) || defined(CS_UNDEFINED_STRING)

			const int result = mkdir(path, 0777);
			return ((result == 0) || (errno == EEXIST));
#endif
		}

		// Else we need to remove the separator.
		char pathMod[EA::WebKit::FileSystem::kMaxPathLength];
		EAW_ASSERT_MSG(nStrlen < EA::WebKit::FileSystem::kMaxPathLength, "Directory path exceeds max path length");
		memcpy(pathMod, path, nStrlen - 1);   // Force 0 terminator in place of directory separator
		pathMod[nStrlen - 1] = 0;

		return MakeDirectoryInternal(pathMod);  // Call ourselves recursively.
	}

	return false;
}
예제 #8
0
void GIFImageDecoder::prepEmptyFrameBuffer(RGBA32Buffer* buffer) 
{
    //+ 7/13/09 CSidhall - Added for alloc fail handling and cache space arranging.
    if(!buffer)
        return;
    buffer->setHasAlpha(true);   
    int size = m_size.width() * m_size.height();        
    setImagePruneLockStatus(true);  // Lock against pruning this resource   
#ifdef _DEBUG   
    static bool overflowFlag = false;    // Avoid too many asserts
    bool cachePrune = cache()->pruneImages(size << 2);
    if(cachePrune == false){
        if(!overflowFlag){
            char buffer[256];
            sprintf(buffer, "RAM Cache Overflow: cache is too small to decode GIF image: %d bytes\n", (size << 2));
            EAW_ASSERT_MSG(cachePrune, buffer);        
            overflowFlag = true;
        }
        // Could exit here but we get into image skipping issues that still need to be worked out.
        // return false;
    }
#else
    cache()->pruneImages(size << 2);
#endif
    setImagePruneLockStatus(false);  // Unlock

    buffer->bytes().resize(size);
    if(buffer->bytes().data())      
        buffer->bytes().fill(0);
   
}
예제 #9
0
bool SetDiskCacheUsage(const EA::WebKit::DiskCacheInfo& diskCacheInfo)
{
	if (!diskCacheInfo.mDiskCacheDirectory || !diskCacheInfo.mDiskCacheDirectory[0] ) 
	{
		EAW_ASSERT_MSG(false,"Disk cache disabled. Invalid disk cache directory.");
		return false;
	}

	const char8_t* pDiskCacheDir = diskCacheInfo.mDiskCacheDirectory;
    EA::IO::Path::PathString8 fullPath = GetFullPath(pDiskCacheDir, true);
	if(!fullPath.empty())
	{
		pDiskCacheDir = fullPath.c_str();
	}

	if(!EA::WebKit::GetFileSystem()->MakeDirectory(pDiskCacheDir))
	{
		EAW_ASSERT_FORMATTED(false , "Could not create directory for %s disk cache directory path \n",pDiskCacheDir);
		return false;
	}

	//11/17/2011 - Bug fix otherwise diskcache does not work with relative path for cache directory.
	EA::WebKit::DiskCacheInfo diskCacheInfoNew = diskCacheInfo;
	diskCacheInfoNew.mDiskCacheDirectory = pDiskCacheDir;
	return WebCore::ResourceHandleManager::sharedInstance()->SetDiskCacheParams(diskCacheInfoNew); 
}
예제 #10
0
        // Return the current system time in seconds, using the classic POSIX epoch of January 1, 1970.
        double currentTime()
        {
			//If the application has installed a timer, use it. Otherwise, use the standard C time function.
			if(EA::WebKit::gTimerCallback)
				return EA::WebKit::gTimerCallback();

			EAW_ASSERT_MSG(false, "The current time resolution is in seconds. This means that some JavaScript that may require better resolution (like for animation effects) would not work correctly. An application may provide a higher resolution timer using the EAWebKit API.");

			return time(0);
        }
예제 #11
0
		void EAWebKitDomainFilter::AddAllowedDomainInfo(const char8_t* allowedDomain, const char8_t* excludedPaths)
		{
			if(!allowedDomain || !allowedDomain[0])
			{
				EAW_ASSERT_MSG(false, "Can't add a null/empty Domain");
				return;
			}
			
			mDomainInfoCollection.push_back(DomainInfo(allowedDomain, excludedPaths));
		}
예제 #12
0
void EAWebKitLib::ClearSSLCertificates()
{
	SET_AUTOFPUPRECISION(EA::WebKit::kFPUPrecisionExtended);

#if ENABLE(DIRTYSDK_IN_DLL)
    EAWEBKIT_THREAD_CHECK();
    EAWWBKIT_INIT_CHECK(); 
	ProtoSSLClrCACerts();
#else
	EAW_ASSERT_MSG(false, "Invalid call. Loading certificates without enabling the DirtySDK code inside DLL\n");
#endif
}
예제 #13
0
void SetTextSystem(ITextSystem* pTextSystem) 
{
	EAW_ASSERT_MSG(!spTextSystem, "TextSystem already exists. Do not call TextSystem more than once!");
	
	if(pTextSystem)
		pTextSystem->Init();

	spTextSystem = pTextSystem;

    // Set up the JS Core interface
    static EA::Internal::JSTextWrapper sJSTextWrapper;    
    JSSetTextInterface(&sJSTextWrapper);    // Just set it regardless, even if pTextSytem is null.
}
예제 #14
0
void EAWebKitLib::AddUserStyleSheet(const char8_t* userStyleSheet)
{
	SET_AUTOFPUPRECISION(EA::WebKit::kFPUPrecisionExtended);
    EAWEBKIT_THREAD_CHECK();
    EAWWBKIT_INIT_CHECK(); 
	if(!userStyleSheet || userStyleSheet[0] == '\0')
		return;

	if(WebCore::PageGroup* pageGroup = WebCore::PageGroup::pageGroup(kDefaultPageGroupName))
		pageGroup->addUserStyleSheetToWorld(WebCore::mainThreadNormalWorld(), userStyleSheet, WebCore::KURL(), nullptr, nullptr, WebCore::InjectInAllFrames);
	else
		EAW_ASSERT_MSG(false,"Unable to create page group. User style sheets won't work");
}
예제 #15
0
FileSystem* GetFileSystem()
{
#if EAWEBKIT_DEFAULT_FILE_SYSTEM_ENABLED
	if(!spFileSystem)
	{
		static FileSystemDefault defaultFileSystem;
		spFileSystem = &defaultFileSystem;
	}
#endif

	EAW_ASSERT_MSG(spFileSystem, "File system does not exist");
	return spFileSystem;
}
예제 #16
0
SocketTransportHandler* GetSocketTransportHandler()
{
	if(!spSocketTransportHandler)
	{
#if ENABLE(DIRTYSDK_IN_DLL)
		EAW_ASSERT_MSG(false, "No application supplied socket transport handler is found. Using the socket transport handler in the EAWebKit package.");
		spSocketTransportHandler = new EA::WebKit::SocketTransportHandlerDirtySDK();
		spSocketTransportHandler->Init();
		ownsSocketTransportHandler = true;
#endif
	}
	return spSocketTransportHandler;
}
예제 #17
0
void EAWebKitThreadErrorCheck(void)
{
    const bool mainThread = WTF::isMainThread();
    if (!mainThread)
    {
        const eastl::string8 message("Error: This API should be called on the same thread as EAWebKit thread.");
        EAW_ASSERT_MSG(mainThread, message.c_str());

        // Output to the client log.
        DebugLogCallback(message, false);

        // Crash EAWebKit so that this thread error is detected promptly.
        EAW_CRASH();
    }
}
예제 #18
0
int32_t EAWebKitLib::LoadSSLCertificate(const uint8_t *pCACert, int32_t iCertSize)
{
	SET_AUTOFPUPRECISION(EA::WebKit::kFPUPrecisionExtended);

#if ENABLE(DIRTYSDK_IN_DLL)
    EAWEBKIT_THREAD_CHECK();
    EAWWBKIT_INIT_CHECK(); 
	int32_t result = ProtoSSLSetCACert(pCACert, iCertSize); 
	EAW_ASSERT(result > 0);
	return result;
#else
	EAW_ASSERT_MSG(false, "Invalid call. Loading certificates without enabling the DirtySDK code inside DLL\n");
	return -1;
#endif
}
예제 #19
0
EASTLHeaderMapWrapper::EASTLHeaderMapWrapperIterator* EASTLHeaderMapWrapper::GetNext()
{
	EAW_ASSERT_MSG(mHeaderMapWrapperIterator, "Please make sure to call EASTLHeaderMapWrapper::First() before this. See header file for documentation.\n");
	if(mHeaderMapWrapperIterator)
	{
		HeaderMap* headerMapPtr = reinterpret_cast<HeaderMap*>(mHeaderMap);
		HeaderMap::iterator& headerMapIterator = *(reinterpret_cast<HeaderMap::iterator*>(mHeaderMapWrapperIterator->mIterator));
		
		++headerMapIterator;

		if(headerMapIterator != headerMapPtr->end())
			return mHeaderMapWrapperIterator;
	}

	return 0;
}
예제 #20
0
void Shutdown()
{
    EAW_ASSERT_MSG( (GetWebKitStatus() == kWebKitStatusActive), "Init() needs to have been called or Shutdown() was called twice");
    
	SET_AUTO_COLLECTOR_STACK_BASE();   // 9/4/09 - CSidhall - Added to get approximate stack base
	
	SetWebKitStatus(kWebKitStatusShuttingDown);
	WebCore::pageCache()->setCapacity(0);
	WebCore::pageCache()->releaseAutoreleasedPagesNow();    
#if ENABLE(INSPECTOR)
	WebCore::InspectorSettingsEA::finalize(); // This saves inspector settings
#endif
	WebCore::PageGroup::closeLocalStorage();
	if(WebCore::PageGroup* pageGroup = WebCore::PageGroup::pageGroup(kDefaultPageGroupName))
		pageGroup->removeUserStyleSheetsFromWorld(WebCore::mainThreadNormalWorld());


 	WTF::waitForAllThreadsCompletion();			// Needed because if dll is freed before this, it would crash 

	// These are statics but we want to have them destruct so that any open file handles they hold are released.  
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
	WebCore::cacheStorage().~ApplicationCacheStorage();
#endif

#if ENABLE(DATABASE)
	WebCore::DatabaseTracker::tracker().~DatabaseTracker();
	// This is so that the local sqlite3_os_end is called on exit.
	// Shutdown before the thread system shutdown.
	sqlite3_shutdown();
#endif

	if(ownsSocketTransportHandler)
	{
		spSocketTransportHandler->Shutdown();
		spSocketTransportHandler = NULL;
	}

	WebCore::ResourceHandleManager::finalize();	// Needed to free DirtySDK related resources
	EA::WebKit::GetTextSystem()->Shutdown();	// Needed to free EAText related resources 

#if ENABLE(EATEXT_IN_DLL) 
    EA::WebKit::ShutdownFontSystem();
#endif

	EA::WebKit::GetThreadSystem()->Shutdown(); // Needed to free any thread related resources. Call at last since some timer stuff uses it to query main thread.
	SetWebKitStatus(kWebKitStatusInactive);
}
예제 #21
0
void SoftwareSurface::Lock(SurfaceDescriptor *pSDOut, const IntRect *rect)
{
	EAW_ASSERT_MSG(mStride == mContentWidth * kBytesPerPixel, "Stride calculation mismatch");
	
	pSDOut->mStride = mStride; 
	if (rect)
    {
        pSDOut->mData = mData + (rect->mLocation.mX * kBytesPerPixel) + (rect->mLocation.mY * mStride) ;
        EAW_ASSERT(pSDOut->mData < mData + (mContentHeight * mStride));
        EAW_ASSERT(pSDOut->mData >= mData);
    }
    else
    {
        pSDOut->mData = mData;
    }

}
예제 #22
0
        double currentTime()
        {
			//If the application has installed a timer, use it. Otherwise, use the standard C time function.
			if(EA::WebKit::gTimerCallback)
				return EA::WebKit::gTimerCallback();
			
			EAW_ASSERT_MSG(false, "The current time resolution is in seconds. This means that some JavaScript that may require better resolution (like for animation effects) would not work correctly. An application may provide a higher resolution timer using the EAWebKit API.");
			
			timeval  aTimeval;
            timezone aTimezone;
            double   dTime;

            gettimeofday(&aTimeval, &aTimezone);
            dTime = (double)aTimeval.tv_sec + (double)(aTimeval.tv_usec / 1000000.0);

            return dTime;
        }
void CanvasRenderingContext2D::bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
{
    if (!isfinite(cp1x) | !isfinite(cp1y) | !isfinite(cp2x) | !isfinite(cp2y) | !isfinite(x) | !isfinite(y))
        return;
    m_path.addBezierCurveTo(FloatPoint(cp1x, cp1y), FloatPoint(cp2x, cp2y), FloatPoint(x, y));

//+ 8/11/09 CSidhall - Added assert for unsuported bezier draw 
// (Seems possible to support it as the ctrl points are passed down...).
#ifdef _DEBUG   
    static bool overflowFlag = false;    // Avoid too many asserts
    if(!overflowFlag) {
        EAW_ASSERT_MSG(0, "Bezier draw is unsupported");                       
        overflowFlag = true;    
     }
#endif
//- CS

}
예제 #24
0
void  EAWebKitLib::AddSocketTransportHandler(SocketTransportHandler* pSTH)
{
	SET_AUTOFPUPRECISION(EA::WebKit::kFPUPrecisionExtended);
    EAWEBKIT_THREAD_CHECK();
    EAWWBKIT_INIT_CHECK(); 
	if(pSTH)
	{
		if(!spSocketTransportHandler)
		{
			spSocketTransportHandler = pSTH;
			pSTH->Init();
		}
		else
		{
			EAW_ASSERT_MSG(false, "Adding SocketTransportHandler more than once. Not supported. Skipping the add");
		}
	}

}
예제 #25
0
AutoFPUPrecision::AutoFPUPrecision(EA::WebKit::FPUPrecision precisionDesired)
{
	unsigned int controlWord = 0;

	switch (precisionDesired)
	{
	case kFPUPrecisionExtended:
		controlWord = _PC_64;
		break;
	case kFPUPrecisionDouble:
		controlWord = _PC_53;
		break;
	case kFPUPrecisionSingle:
		controlWord = _PC_24;
		break;
	default:
		EAW_ASSERT_MSG(false,"Invalid FPUPrecision specified");
		break;
	}
	_controlfp_s(&mSavedControlWord, 0, 0); //Save original Control word
	_controlfp_s(NULL, controlWord, MCW_PC);//Set the higher precision
}
예제 #26
0
// The fire time is relative to the classic POSIX epoch of January 1, 1970,
// as the result of currentTime() is.
void setSharedTimerFireTime(double fireTime)
{
     size_t fireCount = gFireTimeCount;
    
    //+ 1/20/10 CSidhall - This +3 seems mostly a safety to prevent the timer list from overflow.
    // A bad javascript might fill the timer array with too many far distant timers.
    // It is however somewhat pointless and wrong to set a distant trigger to +3 seconds if the real trigger is at +900
    // seconds and won't actually fire even if called at +3 seconds.
    // But this might be ok for now to keep as safety for eventually a future timer will trigger at some point
    // the original timer request. So will keep it for now for only if our array is starting to fill up.
    // Old code:    
    //      if(fireTime > (currentTime + 3))  // Note by Paul Pedriana: I don't know if we really want to do this.
    //        fireTime = (currentTime + 3);  // We need to find out more about how timers internally expect to work.
    // New code: 
    static const size_t kFireTimeOverflow = kFireTimeCapacity/4;    // Any small size will do really. We just want to keep some empty slots around
    if(fireCount > kFireTimeOverflow)
    {
        const double currentTime = OWBAL::currentTime();
        if(fireTime > (currentTime + 3))  // Note by Paul Pedriana: I don't know if we really want to do this.
            fireTime = (currentTime + 3);  // We need to find out more about how timers internally expect to work.
    }

    // Added removal of duplicate time triggers as not having it can overflow the array.
     for(size_t i = 0; i < fireCount; ++i)
     {
            double time = gFireTimeArray[i];
            // Ignore if we have one already 
            if(time == fireTime)
                return;
     }
    //-CS

    EAW_ASSERT_MSG(gFireTimeCount < kFireTimeCapacity, "Fire timers exceed the capacity");
    if(gFireTimeCount < kFireTimeCapacity)
    {
        // To consider: Maintain this list in sorted order. We aren't dependent on it being so, but it might allow us to be a little more efficient.
        gFireTimeArray[gFireTimeCount++] = fireTime;
    }
}
예제 #27
0
void SetFileSystem(FileSystem* pFileSystem)
{
    EAW_ASSERT_MSG(!spFileSystem, "FileSystem already exists. Do not call SetFileSystem more than once!");
	spFileSystem = pFileSystem;
}
예제 #28
0
bool FileSystemDefault::MakeDirectory(const char* path)
{
	// 05/02/2011 - This function is now smart enough to create multiple levels
	// of directories.

	if(path && *path)
	{
		//Fast case - where we may be creating only a top level directory
		if(!DirectoryExists(path))
			MakeDirectoryInternal(path);

		if(DirectoryExists(path))
			return true;

		
		
		//Slow case - where we may be creating multiple levels of directory

		char path8[EA::WebKit::FileSystem::kMaxPathLength];
		const size_t nStrlen = strlen(path);
		EAW_ASSERT_MSG(nStrlen < EA::WebKit::FileSystem::kMaxPathLength, "Directory path exceeds max path length");
		strncpy(path8, path, EA::WebKit::FileSystem::kMaxPathLength);
		path8[EA::WebKit::FileSystem::kMaxPathLength-1] = 0;

		char8_t* p    = path8;
		char8_t* pEnd = path8 + nStrlen; 

#if defined(EA_PLATFORM_WINDOWS) // Windows has the concept of UNC paths which begin with two back slashes \\server\dir\dir
		if(IsDirectorySeparator(*p))
		{
			if(IsDirectorySeparator(*++p)) // Move past an initial path separator.
				++p;
		}
#endif

#if defined(EA_PLATFORM_MICROSOFT)
		// 05/03/2011 - abaldeva: Fix a bug which could otherwise result in incorrect behavior on Xenon.
		char* rootDrive = strchr(p, ':');
		if(rootDrive)
		{
			p = ++rootDrive;
			while(IsDirectorySeparator(*p))
				++p;
		}
		/* //Old code
		if(p[0] && (p[1] == ':') && IsDirectorySeparator(p[2])) // Move past an initial C:/
			p += 3;
		*/
#else
		if(IsDirectorySeparator(*p)) // Move past an initial path separator.
			++p;
#endif

		if(IsDirectorySeparator(pEnd[-1])) // Remove a trailing path separator if present.
			pEnd[-1] = 0;

		for(; *p; ++p) // Walk through the path, creating each component of it if necessary.
		{
			if(IsDirectorySeparator(*p))
			{
				*p = 0;

				if(!DirectoryExists(path8))
				{
					if(!MakeDirectoryInternal(path8))//05/02/11 - abaldeva: Fix a bug otherwise multiple directories are not created.
						return false;
				}

				*p = kDirectorySeparator;
			}
		}

		if(!DirectoryExists(path8))
		{
			if(!MakeDirectoryInternal(path8))//05/02/11 - abaldeva: Fix a bug otherwise multiple directories are not created.
				return false;
		}

		return true; //12/20/11 - abaldeva: Fix a bug otherwise though multiple directories are created, the API returns false.

	}
	
	
	return false;
}
bool ViewNavigationDelegate::JumpToNearestElement(EA::WebKit::JumpDirection direction, bool scrollIfElementNotFound)
{

	// Note by Arpit Baldeva:
	// We have a problem here. mpModalInputClient object is supposed to be used for Modal input only however the only class using this object 
	// is html SELECT element(implemented as a popup). But in reality, html SELECT element is NOT modal. So it is little ill-conceived. 
	// For example, in all the browsers, if you scroll the mouse wheel on the frame, the SELECT element disappears and the actual frame scrolls.

	// For any modal input needs on a web page, the users are advised to use the Z-layer technique with Javascript/CSS - http://jqueryui.com/demos/dialog/#modal-confirmation.

	// The problem we want to solve here is have the SELECT element respond to the controller input correctly(select element one by one).
	// But the button event information is lost by the time we are in the EA::WebKit::View. For the foreseeable future, there is no candidate
	// other than html SELECT element which is implemented as a modal popup inside EAWebKit. So inside EA::WebKit::View, we create a dummy
	// button event from the Jump direction and make SELECT respond to it. If any other object starts using the modal input, this would need to be
	// revisited. But then, we'll need to solve a plethora of issues. So we do minimum work here to not break other things.

	IOverlayInputClient* pOverlayInputClient = mView->GetOverlayInputClient();

	bool handledByOverlayInputClient = false;
	if(pOverlayInputClient)
	{
		EA::WebKit::ButtonEvent btnEvent;
		switch(direction)
		{
			/*
			case EA::WebKit::JumpLeft:
			{
			btnEvent.mID = EA::WebKit::kButton0;
			handledByOverlayInputClient = pOverlayInputClient->OnButtonEvent(btnEvent);
			}
			*/
		case EA::WebKit::JumpUp:
			{
				btnEvent.mID = EA::WebKit::kButton1;
				handledByOverlayInputClient =  pOverlayInputClient->OnButtonEvent(btnEvent);
				break;
			}
			/*
			case EA::WebKit::JumpRight:
			{
			btnEvent.mID = EA::WebKit::kButton2;
			handledByOverlayInputClient =  pOverlayInputClient->OnButtonEvent(btnEvent);
			}
			*/
		case EA::WebKit::JumpDown:
			{
				btnEvent.mID = EA::WebKit::kButton3;
				handledByOverlayInputClient =  pOverlayInputClient->OnButtonEvent(btnEvent);
				break;
			}
		default:
			// We don't return and allow any other button press to go to the main View. At the same time, we make the SELECT element lose focus.
			{
				pOverlayInputClient->OnFocusChangeEvent(false);
				break;
			}
		}
	}

	if(handledByOverlayInputClient)
		return true;

	int lastX, lastY;
	mView->GetCursorPosition(lastX, lastY);

	// Following is a shortcut to drive navigation from a page.
	switch (direction)
	{
	case EA::WebKit::JumpRight:
		if (GetFixedString(mCachedNavigationRightId)->compare(""))
		{
			if (!GetFixedString(mCachedNavigationRightId)->compare("ignore"))
			{
				return false;
			}

			if (JumpToId(GetFixedString(mCachedNavigationRightId)->c_str()))
			{
				return true;
			}
		}
		break;

	case EA::WebKit::JumpDown:
		if (GetFixedString(mCachedNavigationDownId)->compare(""))
		{
			if (!GetFixedString(mCachedNavigationDownId)->compare("ignore"))
			{
				return false;
			}

			if (JumpToId(GetFixedString(mCachedNavigationDownId)->c_str()))
			{
				return true;
			}
		}
		break;

	case EA::WebKit::JumpLeft:
		if (GetFixedString(mCachedNavigationLeftId)->compare(""))
		{
			if (!GetFixedString(mCachedNavigationLeftId)->compare("ignore"))
			{
				return false;
			}

			if (JumpToId(GetFixedString(mCachedNavigationLeftId)->c_str()))
			{
				return true;
			}
		}
		break;

	case EA::WebKit::JumpUp:
		if (GetFixedString(mCachedNavigationUpId)->compare(""))
		{
			if (!GetFixedString(mCachedNavigationUpId)->compare("ignore"))
			{
				return false;
			}

			if (JumpToId(GetFixedString(mCachedNavigationUpId)->c_str()))
			{
				return true;
			}
		}
		break;

	default:
		EAW_FAIL_MSG("Should not have got here\n");
	}


	// Iterate over all the frames and find the closest element in any of all the frames.
	WebCore::Frame* pFrame		= mView->GetFrame();
	float currentRadialDistance = FLT_MAX; // A high value to start with so that the max distance between any two elements in the surface is under it.
	WebCore::Node* currentBestNode = NULL;
	while(pFrame)
	{
		WebCore::Document* document = pFrame->document();
		EAW_ASSERT(document);

		if(document)
		{
			WebCore::FrameView* pFrameView = document->view();
			WebCore::IntPoint scrollOffset;
			if(pFrameView)
			{
 				scrollOffset.setX(pFrameView->scrollOffset().width());
 				scrollOffset.setY(pFrameView->scrollOffset().height());
			}

			// We figure out the start position(It is center of the currently hovered element almost all the time but can be slightly different 
			// due to scroll sometimes).
			mCentreX = lastX + scrollOffset.x();
			mCentreY = lastY + scrollOffset.y();

			DocumentNavigator navigator(mView, document, direction, WebCore::IntPoint(mCentreX, mCentreY), mBestNodeX, mBestNodeY, mBestNodeWidth, mBestNodeHeight, mJumpNavigationParams.mNavigationTheta, mJumpNavigationParams.mStrictAxesCheck, currentRadialDistance);
			navigator.FindBestNode(document);

			if(navigator.GetBestNode())
			{
				currentBestNode			= navigator.GetBestNode();
				currentRadialDistance	= navigator.GetBestNodeRadialDistance();
			}

		}

		pFrame = pFrame->tree()->traverseNext();
	}

	bool foundSomething = false;
	if (currentBestNode) //We found the node to navigate. Move the cursor and we are done.
	{
		foundSomething = true;
		MoveMouseCursorToNode(currentBestNode, false);
	}
	else if(scrollIfElementNotFound)// Node is not found. 
	{
		// Based on the intended direction of movement, scroll so that some newer elements are visible.
		
		int cursorPosBeforeScrollX, cursorPosBeforeScrollY;
		mView->GetCursorPosition(cursorPosBeforeScrollX, cursorPosBeforeScrollY);

		switch(direction)
		{
		case EA::WebKit::JumpDown:
			{
				ScrollOnJump(true, -120, mJumpNavigationParams.mNumLinesToAutoScroll);
				break;
			}

		case EA::WebKit::JumpUp:
			{
				ScrollOnJump(true, 120, mJumpNavigationParams.mNumLinesToAutoScroll);
				break;
			}
		case EA::WebKit::JumpRight:
			{
				ScrollOnJump(false, -120, mJumpNavigationParams.mNumLinesToAutoScroll);
				break;
			}
		case EA::WebKit::JumpLeft:
			{
				ScrollOnJump(false, 120, mJumpNavigationParams.mNumLinesToAutoScroll);
				break;
			}
		default:
			{
				EAW_ASSERT_MSG(false, "Should not reach here\n");
			}
		}

		// We move the mouse cursor back to the location where the last best node was found. This is so that we don't end up with the cursor being in no man's land. While that may work 
		// for ordinary sites, it may not work well with customized pages that leverage CSS to visually indicate current position rather than a cursor graphic.
		// We don't call MoveMouseCursorToNode() with last cached node as there are edge cases where we may be holding an invalid node. Using a cached frame and checking against the
		// current valid frames safeguards against that.

		WebCore::IntSize scrollOffset;
		WebCore::Frame* pFrame1	= mView->GetFrame();
		while(pFrame1)
		{
			if(pFrame1 == mBestNodeFrame)//Find the frame where last best node existed.
			{
				if(pFrame1->view())
				{
					scrollOffset = pFrame1->view()->scrollOffset();//We read scroll offset here as it could have changed in the switch statement above.
					break;
				}
			}
			pFrame1 = pFrame1->tree()->traverseNext();
		}
		
		int targetcursorPosAfterScrollX, targetcursorPosAfterScrollY;
		targetcursorPosAfterScrollX = mBestNodeX + mBestNodeWidth / 2 - scrollOffset.width();
		targetcursorPosAfterScrollY = mBestNodeY + mBestNodeHeight/ 2 - scrollOffset.height();

		EA::WebKit::MouseMoveEvent moveEvent;
		memset( &moveEvent, 0, sizeof(moveEvent) );
		
		const int cursorInset = 5;// Make cursor stay inside 5 pixels from boundaries. No known issues but added this as a safety measure so that we do not lose cursor ever.
		
		int width = mView->GetSize().mWidth;
		int height = mView->GetSize().mHeight;

		moveEvent.mX	= Clamp( cursorInset, targetcursorPosAfterScrollX, width - cursorInset );
		moveEvent.mY	= Clamp( cursorInset, targetcursorPosAfterScrollY, height - cursorInset );


		mView->OnMouseMoveEvent(moveEvent);
		// We intentionally don't call JumpToNearestElement(direction, false) here to avoid recursion. We do it in the overloaded function above.
	}
		
	return foundSomething;
}
예제 #30
0
// We need to draw the glyphBuffer glyphs/advances with the pSimpleFontData font onto the 
// pGraphicsContext pSurface. We draw glyphCount glyphs starting at the glyphIndexBegin.
void Font::drawGlyphs(GraphicsContext* pGraphicsContext, const SimpleFontData* pSimpleFontData, const GlyphBuffer& glyphBuffer,
                        int glyphIndexBegin, int glyphCount, const FloatPoint& point) const
{
    // 11/09/09 CSidhall Added notify start of process to user
	NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusStarted);
	
    #if defined(EA_DEBUG) && defined(AUTHOR_PPEDRIANA_DISABLED) && defined(EA_PLATFORM_WINDOWS)
        TraceGlyphBufferToString(pSimpleFontData, glyphBuffer, glyphIndexBegin, glyphCount, point);
    #endif

    GlyphBufferGlyph*               glyphs      = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(glyphIndexBegin));
    float                           offset      = 0;   
    int                             x_offset    = 0;
    EA::Internal::IFont*            pFont       = pSimpleFontData->m_font.mpFont;
    EA::Internal::IGlyphCache*      pGlyphCache = EA::WebKit::GetGlyphCache(); 
    EAW_ASSERT_MSG(pGlyphCache, "GlyphCache is not set");
	if(!pGlyphCache)
	{
		NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusEnded);
		return;
	}
    
    EA::Internal::ITextureInfo*     pTI         = pGlyphCache->GetTextureInfo(0); // Right now we hard-code usage of what is the only texture.
	EAW_ASSERT_MSG(pTI, "GlyphCache is not initialized with enough number of textures");
	if(!pTI)
	{
		NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusEnded);
		return;
	}

	const int32_t                   textureSize = (int32_t)pTI->GetSize();
    EA::Internal::IGlyphTextureInfo gti;
    EA::Internal::GlyphMetrics      glyphMetrics;
    GlyphDrawInfoArray              gdiArray((size_t)(unsigned)glyphCount);

    // Walk through the list of glyphs and build up render info for each one.
    for (int i = 0; i < glyphCount; i++)
    {
        EA::Internal::GlyphId g = glyphs[i];

        if(!pFont->GetGlyphMetrics(g, glyphMetrics))
        {
            EAW_ASSERT_MSG(false, "Font::drawGlyphs: invalid glyph/Font combo.");
            pFont->GetGlyphIds(L"?", 1, &g, true);
            pFont->GetGlyphMetrics(g, glyphMetrics);
        }

        if(!pGlyphCache->GetGlyphTextureInfo(pFont, g, gti))
        {
            const EA::Internal::GlyphBitmap* pGlyphBitmap;

            if(pFont->RenderGlyphBitmap(&pGlyphBitmap, g))
            {
                if(pGlyphCache->AddGlyphTexture(pFont, g, pGlyphBitmap->mpData, pGlyphBitmap->mnWidth, pGlyphBitmap->mnHeight, 
                                                              pGlyphBitmap->mnStride, (uint32_t)pGlyphBitmap->mBitmapFormat, gti))
                {
                    pGlyphCache->EndUpdate(gti.mpTextureInfo);
                }
                else
                {
                    EAW_ASSERT_MSG(false, "Font::drawGlyphs: AddGlyphTexture failed.");
                    gti.mX1 = gti.mX2 = 0; // Make this an empty glyph. Normally this should never execute.
                }

                pFont->DoneGlyphBitmap(pGlyphBitmap);
            } 
            else
            {
                EAW_ASSERT_MSG(false, "Font::drawGlyphs: invalid glyph/Font combo.");
                gti.mX1 = gti.mX2 = 0; // Make this an empty glyph. Normally this should never execute.
            }
        }

        // Apply kerning.
        // Note by Paul Pedriana: Can we really apply kerning here at the render stage without it looking 
        // wrong? It seems to me this cannot work unless kerning is also taken into account at the 
        // layout stage. To do: See if in fact kerning is taken into account at the layout stage.
        EA::Internal::Kerning kerning;

        if((i > 0) && pFont->GetKerning(glyphs[i - 1], g, kerning, 0))
            offset += kerning.mfKernX;

        // The values we calculate here are relative to the current pen position at the 
        // baseline position of [xoffset, 0], where +X is rightward and +Y is upward.
        gdiArray[i].x1 = (int)(offset + glyphMetrics.mfHBearingX);
        gdiArray[i].x2 = (int)(offset + glyphMetrics.mfHBearingX + glyphMetrics.mfSizeX);
        gdiArray[i].y1 = (int)(glyphMetrics.mfHBearingY);
        gdiArray[i].y2 = (int)(glyphMetrics.mfHBearingY - glyphMetrics.mfSizeY);
        gdiArray[i].tx = (int)(gti.mX1 * textureSize); // Convert [0..1] to [0..textureSize]
        gdiArray[i].ty = (int)(gti.mY1 * textureSize);

        // advanceAt should return a value that is usually equivalent to glyphMetrics.mfHAdvanceX, at least 
        // for most simple Western text. A case where it would be different would be Arabic combining glyphs,
        // and custom kerning, though kerning adjustments are handled above.
        offset += glyphBuffer.advanceAt(glyphIndexBegin + i);
    
        // Free wrapper
        if(gti.mpTextureInfo)
            gti.mpTextureInfo->DestroyWrapper();
    
    }

	// Find the X and Y minima and maxima of the glyph boxes.
    // To do: We can improve the efficiency of this code in a couple of ways, including moving the 
    // min/max tests up into the glyphMetrics code above.
    int xMin = gdiArray[0].x1;
    int xMax = gdiArray[0].x2;
    int yMin = gdiArray[0].y2;    // y2 is min because y goes upward.
    int yMax = gdiArray[0].y1;

    for (GlyphDrawInfoArray::const_iterator it = gdiArray.begin(); it != gdiArray.end(); ++it)
    {
        const GlyphDrawInfo& gdi = *it;

        // We assume tha x1 is always <= x2.
        if (gdi.x1 < xMin)
            xMin = gdi.x1;

        if (gdi.x2 > xMax)
            xMax = gdi.x2;

        // if (gdi.y1 < yMin)  // We normally don't need this check, because y2 will usually (or always?) be less than y1.
        //     yMin = gdi.y1;

        if (gdi.y2 < yMin)
            yMin = gdi.y2;

        if (gdi.y1 > yMax)
            yMax = gdi.y1;

        // if (gdi.y2 > yMax)  // We normally don't need this check, because y1 will usually (or always?) be greater than y2.
        //     yMax = gdi.y2;
    }

    const uint16_t destWidth  = (abs(xMin) + xMax);  // abs(xMin) because it's possible the left of the first glyph is to the left of the origin. Note by Paul Pedriana: Shouldn't this instead be (xMax - min(xMin, 0))?
    const uint16_t destHeight = (yMax - yMin);

    if(destWidth && destHeight)  // (If we are drawing just space chars (which often happens), then destWidth and/or destHeight will be zero)
    {
        // Question by Paul Pedriana: What is the following code doing? I copied this from the 
        // WebKit Freetype equivalent of this function assuming it must be useful. It seems to 
        // me that it is chopping off any glyph pixels to the left of zero. This is probably 
        // going to usually be OK, because it is abnormal for the first char of just about any
        // written language to be a combining char (and thus drawn to the left of the pen position).
        if (gdiArray[0].x1 < 0)
        {
            x_offset = gdiArray[0].x1;
            gdiArray[0].x1 = 0;
        }

        EA::Raster::Surface* const pSurface = pGraphicsContext->platformContext();
        const Color                penColor = pGraphicsContext->fillColor();

        // Write the glyphs into a linear buffer.
        // To consider: See if it's possible to often get away with using stack space for this by
        //              using Vector<uint32_t, N> in order to avoid a memory allocation. A typical
        //              width is ~400 pixels and a typical height ~16 pixels, which is 25600 bytes.
        //              So unless the string is small there won't be any benefit to this.
        Vector<uint32_t> glyphRGBABuffer(destWidth * destHeight);
        const int        penA   = penColor.alpha();
        const int        penR   = penColor.red();
        const int        penG   = penColor.green();
        const int        penB   = penColor.blue();
        const int        penRGB = (penR << 16) | (penG << 8) | penB;

        glyphRGBABuffer.fill(0);

		for (int i = 0; i < glyphCount; i++)
        {
			const GlyphDrawInfo& gdi         = gdiArray[i];
            const uint8_t*       pGlyphAlpha = (pTI->GetData()) + (gdi.ty * pTI->GetStride()) + gdi.tx;
            const int            yOffset     = (destHeight + yMin) - gdi.y1;
			// Note by Arpit Baldeva: Old index calculation below caused a memory overrun(or I should say underrun on http://get.adobe.com/flashplayer/).
			// Basically, yOffset * destWidth) + gdi.x1 could end up being negative if the yOffset is 0 and gdi.x1 is negative. Since I do want
			// to make sure that index is positive, I just force it to be at least 0. There is not enough understanding about this code as of now
			// and Paul said that he would take a look at this along with other Font problems he is currently looking at.
			const int bufferIndex = (yOffset * destWidth) + gdi.x1;
			EAW_ASSERT_FORMATTED(bufferIndex>=0, "Buffer Index is negative. This would corrupt memory. yOffset:%d,destWidth:%u,gdi.x1:%d",yOffset,destWidth,gdi.x1);
			uint32_t*            pDestColor  = glyphRGBABuffer.data() + (bufferIndex >= 0 ? bufferIndex : 0);//Old Index calculation- (yOffset * destWidth) + gdi.x1;
            const int            glyphWidth  = (gdi.x2 - gdi.x1);
            const int            glyphHeight = (gdi.y1 - gdi.y2);

			for (int y = 0; y < glyphHeight; ++y)
            {
				for (int x = 0; x < glyphWidth; ++x)
				{
					//+ 1/5/10 CSidhall - When building the text string texture map, kerning can make certain letters overlap and stomp over the alpha of previous letters so 
                    // we need to preserve texels that were aleady set. Should be able to OR herer because we have a clean buffer and penRGB is the same.
                    // Old code:
                    // pDestColor[x] = ((penA * pGlyphAlpha[x] / 255) << 24) | penRGB;
                    // New code:
                    pDestColor[x] |= ((penA * pGlyphAlpha[x] / 255) << 24) | penRGB;
                    // -CS
				}
                
                pDestColor  += destWidth;
                pGlyphAlpha += pTI->GetStride();
            }

        }

        // It would probably be faster if we kept around a surface for multiple usage instead of 
        // continually recreating this one.
        EA::Raster::Surface* const pGlyphSurface = EA::Raster::CreateSurface((void*)glyphRGBABuffer.data(), destWidth, destHeight, destWidth * 4, EA::Raster::kPixelFormatTypeARGB, false, false);
        EA::Raster::Rect rectSrc;
        EA::Raster::Rect rectDest;

        rectSrc.w  = destWidth;
        rectSrc.h  = destHeight;
        rectSrc.x  = 0;
        rectSrc.y  = 0;
        rectDest.x = (int)point.x() + x_offset + pGraphicsContext->origin().width();
        rectDest.y = (int)point.y() - yMax     + pGraphicsContext->origin().height();

        if (pGraphicsContext->transparencyLayer() == 1.0)
            EA::Raster::Blit(pGlyphSurface, &rectSrc, pSurface, &rectDest);
        else
        {
            const float fTransparency = pGraphicsContext->transparencyLayer();
            EA::Raster::Surface* const pSurfaceWithAlpha = EA::Raster::CreateTransparentSurface(pGlyphSurface, (int)(fTransparency * 255));
            EA::Raster::Blit(pSurfaceWithAlpha, &rectSrc, pSurface, &rectDest);
            EA::Raster::DestroySurface(pSurfaceWithAlpha);
        }

        EA::Raster::DestroySurface(pGlyphSurface);
    }
    pTI->DestroyWrapper();

	NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusEnded);
}