+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/window-system/common/ecore-indicator-impl.h>
-
-// EXTERNAL INCLUDES
-// Ecore is littered with C style cast
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-#include <Ecore.h>
-#include <Evas.h>
-#ifdef WAYLAND
-#include <Ecore_Wayland.h>
-#else
-#include <Ecore_X.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <iomanip>
-#include <fstream>
-
-#include <dali/public-api/images/native-image.h>
-#include <dali/public-api/events/touch-event.h>
-#include <dali/public-api/events/touch-point.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/images/buffer-image.h>
-#include <dali/public-api/images/pixel.h>
-
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/adaptor/common/adaptor-impl.h>
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-#include <dali/public-api/adaptor-framework/native-image-source.h>
-
-using Dali::Vector4;
-
-#if defined(DEBUG_ENABLED)
-#define STATE_DEBUG_STRING(state) (state==DISCONNECTED?"DISCONNECTED":state==CONNECTED?"CONNECTED":"UNKNOWN")
-#endif
-
-namespace
-{
-
-const float SLIDING_ANIMATION_DURATION( 0.2f ); // 200 milli seconds
-const float AUTO_INDICATOR_STAY_DURATION(3.0f); // 3 seconds
-const float SHOWING_DISTANCE_HEIGHT_RATE(0.34f); // 20 pixels
-
-enum
-{
- KEEP_SHOWING = -1,
- HIDE_NOW = 0
-};
-
-const int NUM_GRADIENT_INTERVALS(5); // Number of gradient intervals
-const float GRADIENT_ALPHA[NUM_GRADIENT_INTERVALS+1] = { 0.6f, 0.38f, 0.20f, 0.08f, 0.0f, 0.0f };
-
-#define MAKE_SHADER(A)#A
-
-const char* BACKGROUND_VERTEX_SHADER = MAKE_SHADER(
- attribute mediump vec2 aPosition;
- attribute mediump float aAlpha;
- varying mediump float vAlpha;
- uniform mediump mat4 uMvpMatrix;
- uniform mediump vec3 uSize;
-
- void main()
- {
- mediump vec4 vertexPosition = vec4( aPosition * uSize.xy, 0.0, 1.0 );
- vertexPosition = uMvpMatrix * vertexPosition;
-
- vAlpha = aAlpha;
- gl_Position = vertexPosition;
- }
-);
-
-const char* BACKGROUND_FRAGMENT_SHADER = MAKE_SHADER(
- uniform lowp vec4 uColor;
- varying mediump float vAlpha;
-
- void main()
- {
- gl_FragColor = uColor;
- gl_FragColor.a *= vAlpha;
- }
-);
-
-const char* FOREGROUND_VERTEX_SHADER = DALI_COMPOSE_SHADER(
- attribute mediump vec2 aPosition;\n
- varying mediump vec2 vTexCoord;\n
- uniform mediump mat4 uMvpMatrix;\n
- uniform mediump vec3 uSize;\n
- uniform mediump vec4 sTextureRect;\n
- \n
- void main()\n
- {\n
- gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n
- vTexCoord = aPosition + vec2(0.5);\n
- }\n
-);
-
-const char* FOREGROUND_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
- varying mediump vec2 vTexCoord;\n
- uniform sampler2D sTexture;\n
- \n
- void main()\n
- {\n
- gl_FragColor = texture2D( sTexture, vTexCoord );\n // the foreground does not apply actor color
- }\n
-);
-
-Dali::Geometry CreateQuadGeometry()
-{
- Dali::Property::Map quadVertexFormat;
- quadVertexFormat["aPosition"] = Dali::Property::VECTOR2;
- Dali::PropertyBuffer vertexData = Dali::PropertyBuffer::New( quadVertexFormat );
-
- const float halfQuadSize = .5f;
- struct QuadVertex { Dali::Vector2 position; };
- QuadVertex quadVertexData[4] = {
- { Dali::Vector2(-halfQuadSize, -halfQuadSize) },
- { Dali::Vector2(-halfQuadSize, halfQuadSize) },
- { Dali::Vector2( halfQuadSize, -halfQuadSize) },
- { Dali::Vector2( halfQuadSize, halfQuadSize) } };
- vertexData.SetData(quadVertexData, 4);
-
- Dali::Geometry quad = Dali::Geometry::New();
- quad.AddVertexBuffer( vertexData );
- quad.SetType( Dali::Geometry::TRIANGLE_STRIP );
- return quad;
-}
-
-const float OPAQUE_THRESHOLD(0.99f);
-const float TRANSPARENT_THRESHOLD(0.05f);
-
-// indicator service name
-const char* INDICATOR_SERVICE_NAME("elm_indicator");
-
-// Copied from ecore_evas_extn_engine.h
-
-#define NBUF 2
-
-enum // opcodes
-{
- OP_RESIZE,
- OP_SHOW,
- OP_HIDE,
- OP_FOCUS,
- OP_UNFOCUS,
- OP_UPDATE,
- OP_UPDATE_DONE,
- OP_SHM_REF0,
- OP_SHM_REF1,
- OP_SHM_REF2,
- OP_PROFILE_CHANGE_REQUEST,
- OP_PROFILE_CHANGE_DONE,
- OP_EV_MOUSE_IN,
- OP_EV_MOUSE_OUT,
- OP_EV_MOUSE_UP,
- OP_EV_MOUSE_DOWN,
- OP_EV_MOUSE_MOVE,
- OP_EV_MOUSE_WHEEL,
- OP_EV_MULTI_UP,
- OP_EV_MULTI_DOWN,
- OP_EV_MULTI_MOVE,
- OP_EV_KEY_UP,
- OP_EV_KEY_DOWN,
- OP_EV_HOLD,
- OP_MSG_PARENT,
- OP_MSG,
- OP_PIXMAP_REF,
-};
-
-// Copied from elm_conform.c
-
-const int MSG_DOMAIN_CONTROL_INDICATOR( 0x10001 );
-const int MSG_ID_INDICATOR_REPEAT_EVENT( 0x10002 );
-const int MSG_ID_INDICATOR_ROTATION( 0x10003 );
-const int MSG_ID_INDICATOR_OPACITY( 0X1004 );
-const int MSG_ID_INDICATOR_TYPE( 0X1005 );
-const int MSG_ID_INDICATOR_START_ANIMATION( 0X10006 );
-
-struct IpcDataUpdate
-{
- int x, w, y, h;
-};
-
-struct IpcDataResize
-{
- int w, h;
-};
-
-struct IpcIndicatorDataAnimation
-{
- unsigned int xwin;
- double duration;
-};
-
-struct IpcDataEvMouseUp
-{
- int b;
- Evas_Button_Flags flags;
- int mask;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
-
- IpcDataEvMouseUp(unsigned long timestamp)
- : b(1),
- flags(EVAS_BUTTON_NONE),
- mask(0),
- timestamp(static_cast<unsigned int>(timestamp)),
- event_flags(EVAS_EVENT_FLAG_NONE)
- {
- }
-};
-
-struct IpcDataEvMouseDown
-{
- int b;
- Evas_Button_Flags flags;
- int mask;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
-
- IpcDataEvMouseDown(unsigned long timestamp)
- : b(1),
- flags(EVAS_BUTTON_NONE),
- mask(0),
- timestamp(static_cast<unsigned int>(timestamp)),
- event_flags(EVAS_EVENT_FLAG_NONE)
- {
- }
-};
-
-struct IpcDataEvMouseMove
-{
- int x, y;
- Evas_Button_Flags flags;
- int mask;
- unsigned int timestamp;
- Evas_Event_Flags event_flags;
-
- IpcDataEvMouseMove(const Dali::Vector2& touchPoint, unsigned long timestamp)
- : x(static_cast<Evas_Coord>(touchPoint.x)),
- y(static_cast<Evas_Coord>(touchPoint.y)),
- flags(EVAS_BUTTON_NONE),
- mask(0),
- timestamp(static_cast<unsigned int>(timestamp)),
- event_flags(EVAS_EVENT_FLAG_NONE)
- {
- }
-};
-
-struct IpcDataEvMouseOut
-{
- unsigned int timestamp;
- int mask;
- Evas_Event_Flags event_flags;
-
- IpcDataEvMouseOut(unsigned long timestamp)
- : timestamp(static_cast<unsigned int>(timestamp)),
- mask(0),
- event_flags(EVAS_EVENT_FLAG_NONE)
- {
- }
-};
-
-#ifdef ENABLE_INDICATOR_IMAGE_SAVING
-
-void SaveIndicatorImage( Dali::NativeImageSourcePtr nativeImageSource )
-{
- // Save image data to disk in BMP form.
- static int gFilenameCounter = 0;
- static const char bmpHeader[] = {
- 0x42, 0x4d, 0x0a, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x7c, 0x00,
- 0x00, 0x00,
- 0xe0, 0x01, 0x00, 0x00, // Width (480)
- 0x1b, 0x00, 0x00, 0x00, // Height ( 27)
- 0x01, 0x00, 0x20, 0x00, 0x03, 0x00,
- 0x00, 0x00, 0x80, 0xca, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- // This is a BMP header with width & height hard-coded in.
- // The data was first determined by dumping the raw data and inspecting in GIMP, before creating this header data.
- std::vector<unsigned char> buffer;
- unsigned int w = 0;
- unsigned int h = 0;
- Dali::Pixel::Format pixelFormat;
- if( nativeImageSource->GetPixels( buffer, w, h, pixelFormat ) )
- {
- int imageSize = w * h * 4;
- std::stringstream fileName;
- // Give each file an incremental filename.
- fileName << "/opt/usr/media/Images/out-" << std::setfill( '0' ) << std::setw( 5 ) << gFilenameCounter << ".bmp";
-
- std::ofstream outfile( fileName.str().c_str(), std::ofstream::binary );
- if( outfile.is_open() )
- {
- DALI_LOG_WARNING( "Saving Indicator Image w:%d, h:%d, %s\n", w, h, fileName.str().c_str() );
-
- outfile.write( bmpHeader, sizeof( bmpHeader ) / sizeof( bmpHeader[0] ) ); // Size of the BMP header.
- outfile.write( (const char*)buffer.data(), imageSize );
- outfile.close();
- gFilenameCounter++;
- }
- else
- {
- DALI_LOG_ERROR( "COULD NOT OPEN FOR SAVING: %s\n", fileName.str().c_str() );
- }
- }
-}
-
-#endif
-
-} // anonymous namespace
-
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gIndicatorLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_INDICATOR");
-#endif
-
-// Impl to hide EFL implementation.
-
-struct Indicator::Impl
-{
- enum // operation mode
- {
- INDICATOR_HIDE,
- INDICATOR_STAY_WITH_DURATION
- };
-
- /**
- * Constructor
- */
- Impl(Indicator* indicator)
- : mIndicator(indicator),
- mEcoreEventHandler(NULL)
- {
-#if defined(DALI_PROFILE_MOBILE)
-#if defined(WAYLAND)
- mEcoreEventHandler = ecore_event_handler_add(ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this);
-#else
- mEcoreEventHandler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, EcoreEventClientMessage, this);
-#endif
-#endif // WAYLAND && DALI_PROFILE_MOBILE
- }
-
- /**
- * Destructor
- */
- ~Impl()
- {
- if ( mEcoreEventHandler )
- {
- ecore_event_handler_del(mEcoreEventHandler);
- }
- }
-
- static void SetIndicatorVisibility( void* data, int operation )
- {
- Indicator::Impl* indicatorImpl((Indicator::Impl*)data);
-
- if ( indicatorImpl == NULL || indicatorImpl->mIndicator == NULL)
- {
- return;
- }
- if ( operation == INDICATOR_STAY_WITH_DURATION )
- {
- // if indicator is not showing, INDICATOR_FLICK_DONE is given
- if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO &&
- !indicatorImpl->mIndicator->mIsShowing )
- {
- indicatorImpl->mIndicator->ShowIndicator( AUTO_INDICATOR_STAY_DURATION );
- }
- }
- else if( operation == INDICATOR_HIDE )
- {
- if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO &&
- indicatorImpl->mIndicator->mIsShowing )
- {
- indicatorImpl->mIndicator->ShowIndicator( HIDE_NOW );
- }
- }
- }
-#if defined(DALI_PROFILE_MOBILE)
-#if defined(WAYLAND)
- /**
- * Called when the Ecore indicator event is received.
- */
- static Eina_Bool EcoreEventIndicator( void* data, int type, void* event )
- {
- SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION );
- return ECORE_CALLBACK_PASS_ON;
- }
-#else
- /**
- * Called when the client messages (i.e. quick panel state) are received.
- */
- static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
- {
- Ecore_X_Event_Client_Message* clientMessageEvent((Ecore_X_Event_Client_Message*)event);
-
- if ( clientMessageEvent != NULL )
- {
- if (clientMessageEvent->message_type == ECORE_X_ATOM_E_INDICATOR_FLICK_DONE)
- {
- SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION );
- }
- else if ( clientMessageEvent->message_type == ECORE_X_ATOM_E_MOVE_QUICKPANEL_STATE )
- {
- SetIndicatorVisibility( data, INDICATOR_HIDE );
- }
- }
- return ECORE_CALLBACK_PASS_ON;
- }
-#endif
-#endif // WAYLAND && DALI_PROFILE_MOBILE
-
- // Data
- Indicator* mIndicator;
- Ecore_Event_Handler* mEcoreEventHandler;
-};
-
-Indicator::LockFile::LockFile(const std::string filename)
-: mFilename(filename),
- mErrorThrown(false)
-{
- mFileDescriptor = open(filename.c_str(), O_RDWR);
- if( mFileDescriptor == -1 )
- {
- mFileDescriptor = 0;
- mErrorThrown = true;
- DALI_LOG_ERROR( "### Cannot open %s for indicator lock ###\n", mFilename.c_str() );
- }
-}
-
-Indicator::LockFile::~LockFile()
-{
- // Closing file descriptor also unlocks file.
- if( mFileDescriptor > 0 )
- {
- close( mFileDescriptor );
- }
-}
-
-bool Indicator::LockFile::Lock()
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- bool locked = false;
- if( mFileDescriptor > 0 )
- {
- struct flock filelock;
-
- filelock.l_type = F_RDLCK;
- filelock.l_whence = SEEK_SET;
- filelock.l_start = 0;
- filelock.l_len = 0;
- if( fcntl( mFileDescriptor, F_SETLKW, &filelock ) == -1 )
- {
- mErrorThrown = true;
- DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() );
- }
- else
- {
- locked = true;
- }
- }
- else
- {
- mErrorThrown = true;
- DALI_LOG_ERROR( "### Invalid fd ###\n" );
- }
-
- return locked;
-}
-
-void Indicator::LockFile::Unlock()
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- if( mFileDescriptor > 0 )
- {
- struct flock filelock;
-
- filelock.l_type = F_UNLCK;
- filelock.l_whence = SEEK_SET;
- filelock.l_start = 0;
- filelock.l_len = 0;
- if (fcntl(mFileDescriptor, F_SETLKW, &filelock) == -1)
- {
- mErrorThrown = true;
- DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() );
- }
- }
-}
-
-bool Indicator::LockFile::RetrieveAndClearErrorStatus()
-{
- bool error = mErrorThrown;
- mErrorThrown = false;
- return error;
-}
-
-Indicator::ScopedLock::ScopedLock(LockFile* lockFile)
-: mLockFile(lockFile),
- mLocked(false)
-{
- if(mLockFile)
- {
- mLocked = mLockFile->Lock();
- }
-}
-
-Indicator::ScopedLock::~ScopedLock()
-{
- if( mLockFile )
- {
- mLockFile->Unlock();
- }
-}
-
-bool Indicator::ScopedLock::IsLocked()
-{
- return mLocked;
-}
-
-Indicator::Indicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer )
-: mPixmap( 0 ),
- mGestureDeltaY( 0.0f ),
- mGestureDetected( false ),
- mConnection( this ),
- mOpacityMode( Dali::Window::OPAQUE ),
- mState( DISCONNECTED ),
- mAdaptor(adaptor),
- mServerConnection( NULL ),
- mObserver( observer ),
- mOrientation( orientation ),
- mImageWidth( 0 ),
- mImageHeight( 0 ),
- mVisible( Dali::Window::INVISIBLE ),
- mIsShowing( true ),
- mIsAnimationPlaying( false ),
- mCurrentSharedFile( 0 ),
- mSharedBufferType( BUFFER_TYPE_SHM ),
- mImpl( NULL ),
- mBackgroundVisible( false ),
- mTopMargin( 0 )
-{
- mIndicatorContentActor = Dali::Actor::New();
- mIndicatorContentActor.SetParentOrigin( ParentOrigin::TOP_CENTER );
- mIndicatorContentActor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
-
- // Indicator image handles the touch event including "leave"
- mIndicatorContentActor.SetLeaveRequired( true );
- mIndicatorContentActor.TouchSignal().Connect( this, &Indicator::OnTouch );
- mIndicatorContentActor.SetColor( Color::BLACK );
-
- mIndicatorActor = Dali::Actor::New();
- mIndicatorActor.Add( mIndicatorContentActor );
-
- // Event handler to find out flick down gesture
- mEventActor = Dali::Actor::New();
- mEventActor.SetParentOrigin( ParentOrigin::TOP_CENTER );
- mEventActor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- mIndicatorActor.Add( mEventActor );
-
- // Attach pan gesture to find flick down during hiding.
- // It can prevent the problem that scrollview gets pan gesture even indicator area is touched,
- // since it consumes the pan gesture in advance.
- mPanDetector = Dali::PanGestureDetector::New();
- mPanDetector.DetectedSignal().Connect( this, &Indicator::OnPan );
- mPanDetector.Attach( mEventActor );
-
- Open( orientation );
-
- // register indicator to accessibility adaptor
- Dali::AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get();
- if(accessibilityAdaptor)
- {
- AccessibilityAdaptor::GetImplementation( accessibilityAdaptor ).SetIndicator( this );
- }
- // hide the indicator by default
- mIndicatorActor.SetVisible( false );
-
- // create impl to handle ecore event
- mImpl = new Impl(this);
-}
-
-Indicator::~Indicator()
-{
- if(mImpl)
- {
- delete mImpl;
- mImpl = NULL;
- }
-
- if(mEventActor)
- {
- mEventActor.TouchSignal().Disconnect( this, &Indicator::OnTouch );
- }
- Disconnect();
-}
-
-void Indicator::SetAdaptor(Adaptor* adaptor)
-{
- mAdaptor = adaptor;
- mIndicatorBuffer->SetAdaptor( adaptor );
-}
-
-Dali::Actor Indicator::GetActor()
-{
- return mIndicatorActor;
-}
-
-void Indicator::Open( Dali::Window::WindowOrientation orientation )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // Calls from Window should be set up to ensure we are in a
- // disconnected state before opening a second time.
- DALI_ASSERT_DEBUG( mState == DISCONNECTED );
-
- mOrientation = orientation;
-
- Connect();
-
- // Change background visibility depending on orientation
- if( mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE )
- {
- if( mBackgroundRenderer )
- {
- mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer );
- mBackgroundVisible = false;
- }
- }
- else
- {
- SetOpacityMode( mOpacityMode );
- }
-}
-
-void Indicator::Close()
-{
- DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s", STATE_DEBUG_STRING(mState) );
-
- if( mState == CONNECTED )
- {
- Disconnect();
- if( mObserver != NULL )
- {
- mObserver->IndicatorClosed( this );
- }
- }
-
- Dali::Texture emptyTexture;
- SetForegroundImage( emptyTexture );
-}
-
-void Indicator::SetOpacityMode( Dali::Window::IndicatorBgOpacity mode )
-{
- mOpacityMode = mode;
-
- Dali::Geometry geometry = CreateBackgroundGeometry();
- if( geometry )
- {
- if( mBackgroundRenderer )
- {
- if( mBackgroundRenderer.GetGeometry() != geometry )
- {
- mBackgroundRenderer.SetGeometry( geometry );
- }
- }
- else
- {
- if( !mBackgroundShader )
- {
- mBackgroundShader = Dali::Shader::New( BACKGROUND_VERTEX_SHADER, BACKGROUND_FRAGMENT_SHADER, Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT );
- }
-
- mBackgroundRenderer = Dali::Renderer::New( geometry, mBackgroundShader );
- }
-
- if( !mBackgroundVisible )
- {
- mIndicatorContentActor.AddRenderer( mBackgroundRenderer );
- mBackgroundVisible = true;
- }
- }
- else if( mBackgroundRenderer )
- {
- mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer );
- mBackgroundVisible = false;
- }
- UpdateTopMargin();
-}
-
-void Indicator::SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate )
-{
- if ( visibleMode != mVisible || forceUpdate )
- {
- // If we were previously hidden, then we should update the image data before we display the indicator
- if ( mVisible == Dali::Window::INVISIBLE )
- {
- UpdateImageData( mCurrentSharedFile );
- }
-
- if ( visibleMode == Dali::Window::INVISIBLE )
- {
- if (mServerConnection)
- {
- mServerConnection->SendEvent( OP_HIDE, NULL, 0 );
- }
- }
- else
- {
- mIndicatorActor.SetVisible( true );
-
- if( mServerConnection )
- {
- mServerConnection->SendEvent( OP_SHOW, NULL, 0 );
- }
- }
-
- mVisible = visibleMode;
- UpdateTopMargin();
-
- if( mForegroundRenderer && mForegroundRenderer.GetTextures().GetTexture( 0u ) )
- {
- if( CheckVisibleState() && mVisible == Dali::Window::AUTO )
- {
- // hide indicator
- ShowIndicator( AUTO_INDICATOR_STAY_DURATION /* stay n sec */ );
- }
- else if( CheckVisibleState() && mVisible == Dali::Window::VISIBLE )
- {
- // show indicator
- ShowIndicator( KEEP_SHOWING );
- }
- else
- {
- // hide indicator
- ShowIndicator( HIDE_NOW );
- }
- }
- else
- {
- mIsShowing = false;
- }
- }
-}
-
-bool Indicator::IsConnected()
-{
- return ( mState == CONNECTED );
-}
-
-bool Indicator::SendMessage( int messageDomain, int messageId, const void *data, int size )
-{
- if(IsConnected())
- {
- return mServerConnection->SendEvent( OP_MSG, messageDomain, messageId, data, size );
- }
- else
- {
- return false;
- }
-}
-
-bool Indicator::OnTouch(Dali::Actor indicator, const Dali::TouchData& touchData)
-{
- if( mServerConnection )
- {
- // Send touch event to indicator server when indicator is showing
- if( CheckVisibleState() || mIsShowing )
- {
- switch( touchData.GetState(0) )
- {
- case Dali::PointState::DOWN:
- {
- IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
- IpcDataEvMouseDown ipcDown( touchData.GetTime() );
- mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
- mServerConnection->SendEvent( OP_EV_MOUSE_DOWN, &ipcDown, sizeof(ipcDown) );
-
- if( mVisible == Dali::Window::AUTO )
- {
- // Stop hiding indicator
- ShowIndicator( KEEP_SHOWING );
- }
- }
- break;
-
- case Dali::PointState::MOTION:
- {
- IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
- mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
- }
- break;
-
- case Dali::PointState::UP:
- case Dali::PointState::INTERRUPTED:
- {
- IpcDataEvMouseUp ipcUp( touchData.GetTime() );
- mServerConnection->SendEvent( OP_EV_MOUSE_UP, &ipcUp, sizeof(ipcUp) );
-
- if( mVisible == Dali::Window::AUTO )
- {
- // Hide indicator
- ShowIndicator( 0.5f /* hide after 0.5 sec */ );
- }
- }
- break;
-
- case Dali::TouchPoint::Leave:
- {
- IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
- mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
- IpcDataEvMouseUp ipcOut( touchData.GetTime() );
- mServerConnection->SendEvent( OP_EV_MOUSE_OUT, &ipcOut, sizeof(ipcOut) );
- }
- break;
-
- default:
- break;
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-bool Indicator::Connect()
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- DALI_ASSERT_DEBUG( mState == DISCONNECTED );
-
- bool connected = false;
-
- mServerConnection = new ServerConnection( INDICATOR_SERVICE_NAME, 0, false, this );
- if( mServerConnection )
- {
- connected = mServerConnection->IsConnected();
- if( ! connected )
- {
- delete mServerConnection;
- mServerConnection = NULL;
- }
- }
-
- if( !connected )
- {
- StartReconnectionTimer();
- }
- else
- {
- mState = CONNECTED;
- }
-
- return connected;
-}
-
-void Indicator::StartReconnectionTimer()
-{
- if( ! mReconnectTimer )
- {
- mReconnectTimer = Dali::Timer::New(1000);
- mConnection.DisconnectAll();
- mReconnectTimer.TickSignal().Connect( mConnection, &Indicator::OnReconnectTimer );
- }
- mReconnectTimer.Start();
-}
-
-bool Indicator::OnReconnectTimer()
-{
- bool retry = false;
-
- if( mState == DISCONNECTED )
- {
- if( !Connect() )
- {
- retry = true;
- }
- }
-
- return retry;
-}
-
-void Indicator::Disconnect()
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- mState = DISCONNECTED;
-
- delete mServerConnection;
- mServerConnection = NULL;
-
- ClearSharedFileInfo();
-}
-
-void Indicator::Resize( int width, int height )
-{
- if( width < 1 )
- {
- width = 1;
- }
- if( height < 1 )
- {
- height = 1;
- }
-
- if( mImageWidth != width || mImageHeight != height )
- {
- mImageWidth = width;
- mImageHeight = height;
-
- mIndicatorContentActor.SetSize( mImageWidth, mImageHeight );
- mIndicatorActor.SetSize( mImageWidth, mImageHeight );
- mEventActor.SetSize(mImageWidth, mImageHeight);
- UpdateTopMargin();
- }
-}
-
-void Indicator::SetLockFileInfo( Ecore_Ipc_Event_Server_Data *epcEvent )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // epcEvent->ref == w
- // epcEvent->ref_to == h
- // epcEvent->response == buffer num
- // epcEvent->data = lockfile + nul byte
-
- if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) && (epcEvent->data) &&
- (((unsigned char *)epcEvent->data)[epcEvent->size - 1] == 0) )
- {
- int n = epcEvent->response;
-
- if( n >= 0 && n < SHARED_FILE_NUMBER )
- {
- mCurrentSharedFile = n;
-
- mSharedFileInfo[n].mImageWidth = epcEvent->ref;
- mSharedFileInfo[n].mImageHeight = epcEvent->ref_to;
-
- mSharedFileInfo[n].mLockFileName.clear();
-
- mSharedFileInfo[n].mLockFileName = static_cast< char* >( epcEvent->data );
-
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "SetLockFileInfo: buffer num = %d, w = %d, h = %d, lock = %s\n",
- n, mSharedFileInfo[n].mImageWidth, mSharedFileInfo[n].mImageHeight, mSharedFileInfo[n].mLockFileName.c_str() );
- }
- }
-}
-
-void Indicator::SetSharedImageInfo( Ecore_Ipc_Event_Server_Data *epcEvent )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // epcEvent->ref == shm id
- // epcEvent->ref_to == shm num
- // epcEvent->response == buffer num
- // epcEvent->data = shm ref string + nul byte
-
- if ( (epcEvent->data) &&
- (epcEvent->size > 0) &&
- (((unsigned char *)epcEvent->data)[epcEvent->size - 1] == 0) )
- {
- int n = epcEvent->response;
-
- if( n >= 0 && n < SHARED_FILE_NUMBER )
- {
- mCurrentSharedFile = n;
-
- mSharedFileInfo[n].mSharedFileName.clear();
-
- mSharedFileInfo[n].mSharedFileName = static_cast< char* >( epcEvent->data );
-
- mSharedFileInfo[n].mSharedFileID = epcEvent->ref;
- mSharedFileInfo[n].mSharedFileNumber = epcEvent->ref_to;
-
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "SetSharedImageInfo: buffer num %d, shared file = %s, id = %d, num = %d\n",
- n, mSharedFileInfo[n].mSharedFileName.c_str(), mSharedFileInfo[n].mSharedFileID, mSharedFileInfo[n].mSharedFileNumber );
- }
- }
-}
-
-void Indicator::LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // epcEvent->ref == alpha
- // epcEvent->ref_to == sys
- // epcEvent->response == buffer num
-
- if ( mSharedBufferType != BUFFER_TYPE_SHM )
- {
- return ;
- }
-
- int n = epcEvent->response;
-
- if( n >= 0 && n < SHARED_FILE_NUMBER )
- {
- mCurrentSharedFile = n;
-
- delete mSharedFileInfo[n].mSharedFile;
- mSharedFileInfo[n].mSharedFile = NULL;
-
- delete mSharedFileInfo[n].mLock;
- mSharedFileInfo[n].mLock = NULL;
-
- std::stringstream sharedFileID;
- std::stringstream sharedFileNumber;
-
- sharedFileID << mSharedFileInfo[n].mSharedFileID;
- sharedFileNumber << mSharedFileInfo[n].mSharedFileNumber;
-
- std::string sharedFilename = "/" + mSharedFileInfo[n].mSharedFileName + "-" + sharedFileID.str() + "." + sharedFileNumber.str();
-
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "LoadSharedImage: file name = %s\n", sharedFilename.c_str() );
-
- mSharedFileInfo[n].mSharedFile = SharedFile::New( sharedFilename.c_str(), mSharedFileInfo[n].mImageWidth * mSharedFileInfo[n].mImageWidth * 4, true );
- if( mSharedFileInfo[n].mSharedFile != NULL )
- {
- mSharedFileInfo[n].mLock = new Indicator::LockFile( mSharedFileInfo[n].mLockFileName );
- if( mSharedFileInfo[n].mLock->RetrieveAndClearErrorStatus() )
- {
- DALI_LOG_ERROR( "### Indicator error: Cannot open lock file %s ###\n", mSharedFileInfo[n].mLockFileName.c_str() );
- }
- else
- {
- CreateNewImage( n );
- UpdateVisibility();
- }
- }
- }
-}
-
-void Indicator::LoadPixmapImage( Ecore_Ipc_Event_Server_Data *epcEvent )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // epcEvent->ref == pixmap id
- // epcEvent->ref_to == type
- // epcEvent->response == buffer num
-
- if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) )
- {
- mSharedBufferType = (BufferType)(epcEvent->ref_to);
-
- ClearSharedFileInfo();
-
- mPixmap = static_cast<PixmapId>(epcEvent->ref);
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "mPixmap [%x]", mPixmap);
-
- CreateNewPixmapImage();
- UpdateVisibility();
- }
-}
-
-void Indicator::UpdateTopMargin()
-{
- int newMargin = (mVisible == Dali::Window::VISIBLE && mOpacityMode == Dali::Window::OPAQUE) ? mImageHeight : 0;
- if (mTopMargin != newMargin)
- {
- mTopMargin = newMargin;
- mAdaptor->IndicatorSizeChanged( mTopMargin );
- }
-}
-
-void Indicator::UpdateVisibility()
-{
- if( CheckVisibleState() )
- {
- // set default indicator type (enable the quick panel)
- OnIndicatorTypeChanged( INDICATOR_TYPE_1 );
- }
- else
- {
- // set default indicator type (disable the quick panel)
- OnIndicatorTypeChanged( INDICATOR_TYPE_2 );
- }
-
- if( !mIsShowing )
- {
- mIndicatorContentActor.SetPosition( 0.0f, -mImageHeight, 0.0f );
- }
-
- SetVisible(mVisible, true);
-}
-
-void Indicator::UpdateImageData( int bufferNumber )
-{
- DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s mVisible: %s", STATE_DEBUG_STRING(mState), mVisible?"T":"F" );
-
- if( mState == CONNECTED && mVisible )
- {
- if(mPixmap == 0)
- {
- // in case of shm indicator (not pixmap), not sure we can skip it when mIsShowing is false
- CopyToBuffer( bufferNumber );
- }
- else
- {
- if(mIsShowing)
- {
- mAdaptor->RequestUpdateOnce();
- }
- }
- }
-}
-
-bool Indicator::CopyToBuffer( int bufferNumber )
-{
- bool success = false;
-
- if( mSharedFileInfo[bufferNumber].mLock )
- {
- Indicator::ScopedLock scopedLock(mSharedFileInfo[bufferNumber].mLock);
- if( mSharedFileInfo[bufferNumber].mLock->RetrieveAndClearErrorStatus() )
- {
- // Do nothing here.
- }
- else if( scopedLock.IsLocked() )
- {
- unsigned char *src = mSharedFileInfo[bufferNumber].mSharedFile->GetAddress();
- size_t size = static_cast< size_t >( mSharedFileInfo[bufferNumber].mImageWidth ) * mSharedFileInfo[bufferNumber].mImageHeight * 4;
-
- if( mIndicatorBuffer->UpdatePixels( src, size ) )
- {
- mAdaptor->RequestUpdateOnce();
- success = true;
- }
- }
- }
-
- return success;
-}
-
-void Indicator::CreateNewPixmapImage()
-{
- DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d", mImageWidth, mImageHeight );
- Dali::NativeImageSourcePtr nativeImageSource = Dali::NativeImageSource::New( mPixmap );
-
-#ifdef ENABLE_INDICATOR_IMAGE_SAVING
- SaveIndicatorImage( nativeImageSource );
-#endif
-
- if( nativeImageSource )
- {
- Dali::Texture texture = Dali::Texture::New( *nativeImageSource );
- SetForegroundImage( texture );
- mIndicatorContentActor.SetSize( mImageWidth, mImageHeight );
- mIndicatorActor.SetSize( mImageWidth, mImageHeight );
- mEventActor.SetSize( mImageWidth, mImageHeight );
- UpdateTopMargin();
- }
- else
- {
- DALI_LOG_WARNING("### Cannot create indicator image - disconnecting ###\n");
- Disconnect();
- if( mObserver != NULL )
- {
- mObserver->IndicatorClosed( this );
- }
- // Don't do connection in this callback - strange things happen!
- StartReconnectionTimer();
- }
-}
-
-void Indicator::CreateNewImage( int bufferNumber )
-{
- DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d", mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight );
- mIndicatorBuffer = new IndicatorBuffer( mAdaptor, mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight, Pixel::BGRA8888 );
- bool success = false;
-
- if( CopyToBuffer( bufferNumber ) ) // Only create images if we have valid image buffer
- {
- Dali::Texture texture = Dali::Texture::New( mIndicatorBuffer->GetNativeImage() );
- if( texture )
- {
- SetForegroundImage( texture );
- success = true;
- }
- }
-
- if( !success )
- {
- DALI_LOG_WARNING("### Cannot create indicator image ###\n");
- }
-}
-
-Dali::Geometry Indicator::CreateBackgroundGeometry()
-{
- switch( mOpacityMode )
- {
- case Dali::Window::TRANSLUCENT:
- if( !mTranslucentGeometry )
- {
- // Construct 5 interval mesh
- // 0 +---+ 1
- // | \ |
- // 2 +---+ 3
- // | \ |
- // 4 +---+ 5
- // | \ |
- // 6 +---+ 7
- // | \ |
- // 8 +---+ 9
- // | \ |
- // 10 +---+ 11
-
- // Create vertices
- struct BackgroundVertex
- {
- Vector2 mPosition;
- float mAlpha;
- };
-
- unsigned int numVertices = 2 * ( NUM_GRADIENT_INTERVALS + 1 );
- BackgroundVertex vertices[ numVertices ];
-
- float d = -0.5f;
- float delta = 1.0f / NUM_GRADIENT_INTERVALS;
- BackgroundVertex* currentVertex = vertices;
- for( int y = 0; y < NUM_GRADIENT_INTERVALS + 1; ++y, d += delta )
- {
- currentVertex->mPosition = Vector2( -0.5f, d );
- currentVertex->mAlpha = GRADIENT_ALPHA[ y ];
- currentVertex++;
-
- currentVertex->mPosition = Vector2( 0.5f, d );
- currentVertex->mAlpha = GRADIENT_ALPHA[ y ];
- currentVertex++;
- }
-
- // Create indices
- unsigned int numIndices = 2 * 3 * NUM_GRADIENT_INTERVALS;
- unsigned short indices[ numIndices ];
-
- unsigned short* currentIndex = indices;
- for( int y = 0; y < NUM_GRADIENT_INTERVALS; ++y )
- {
- *currentIndex++ = (2 * y);
- *currentIndex++ = (2 * y) + 3;
- *currentIndex++ = (2 * y) + 1;
-
- *currentIndex++ = (2 * y);
- *currentIndex++ = (2 * y) + 2;
- *currentIndex++ = (2 * y) + 3;
- }
-
- Dali::Property::Map vertexFormat;
- vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2;
- vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT;
- Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat );
- vertexPropertyBuffer.SetData( vertices, numVertices );
-
- // Create the geometry object
- mTranslucentGeometry = Dali::Geometry::New();
- mTranslucentGeometry.AddVertexBuffer( vertexPropertyBuffer );
- mTranslucentGeometry.SetIndexBuffer( &indices[0], numIndices );
- }
-
- return mTranslucentGeometry;
- case Dali::Window::OPAQUE:
-
- if( !mSolidGeometry )
- {
- // Create vertices
- struct BackgroundVertex
- {
- Vector2 mPosition;
- float mAlpha;
- };
-
- BackgroundVertex vertices[ 4 ] = { { Vector2( -0.5f, -0.5f ), 1.0f }, { Vector2( 0.5f, -0.5f ), 1.0f },
- { Vector2( -0.5f, 0.5f ), 1.0f }, { Vector2( 0.5f, 0.5f ), 1.0f } };
-
- // Create indices
- unsigned short indices[ 6 ] = { 0, 3, 1, 0, 2, 3 };
-
- Dali::Property::Map vertexFormat;
- vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2;
- vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT;
- Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat );
- vertexPropertyBuffer.SetData( vertices, 4 );
-
-
- // Create the geometry object
- mSolidGeometry = Dali::Geometry::New();
- mSolidGeometry.AddVertexBuffer( vertexPropertyBuffer );
- mSolidGeometry.SetIndexBuffer( &indices[0], 6 );
- }
-
- return mSolidGeometry;
- case Dali::Window::TRANSPARENT:
- break;
- }
-
- return Dali::Geometry();
-}
-
-void Indicator::SetForegroundImage( Dali::Texture texture )
-{
- if( !mForegroundRenderer && texture )
- {
- // Create Shader
- Dali::Shader shader = Dali::Shader::New( FOREGROUND_VERTEX_SHADER, FOREGROUND_FRAGMENT_SHADER );
-
- // Create renderer from geometry and material
- Dali::Geometry quad = CreateQuadGeometry();
- mForegroundRenderer = Dali::Renderer::New( quad, shader );
- // Make sure the foreground stays in front of the background
- mForegroundRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, 1.f );
-
- // Set blend function
- mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB, Dali::BlendFactor::ONE );
- mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB, Dali::BlendFactor::ONE_MINUS_SRC_ALPHA );
- mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA, Dali::BlendFactor::ONE );
- mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA, Dali::BlendFactor::ONE );
-
- // Create a texture-set and add to renderer
-
- Dali::TextureSet textureSet = Dali::TextureSet::New();
- textureSet.SetTexture( 0u, texture );
- mForegroundRenderer.SetTextures( textureSet );
-
- mIndicatorContentActor.AddRenderer( mForegroundRenderer );
- }
- else if( mForegroundRenderer )
- {
- Dali::TextureSet textureSet = mForegroundRenderer.GetTextures();
- textureSet.SetTexture( 0u, texture );
- }
-
- if( mImageWidth == 0 && mImageHeight == 0 && texture)
- {
- Resize( texture.GetWidth(), texture.GetHeight() );
- }
-}
-
-void Indicator::OnIndicatorTypeChanged( Type indicatorType )
-{
- if( mObserver != NULL )
- {
- mObserver->IndicatorTypeChanged( indicatorType );
- }
-}
-
-void Indicator::DataReceived( void* event )
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
- Ecore_Ipc_Event_Server_Data *epcEvent = static_cast<Ecore_Ipc_Event_Server_Data *>( event );
-
- switch( epcEvent->minor )
- {
- case OP_UPDATE:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE\n" );
- if( mIsShowing )
- {
- mAdaptor->RequestUpdateOnce();
- }
- break;
- }
- case OP_UPDATE_DONE:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE_DONE [%d]\n", epcEvent->response );
- // epcEvent->response == display buffer #
- UpdateImageData( epcEvent->response );
- break;
- }
- case OP_SHM_REF0:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF0\n" );
- SetSharedImageInfo( epcEvent );
- break;
- }
- case OP_SHM_REF1:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF1\n" );
- SetLockFileInfo( epcEvent );
- break;
- }
- case OP_SHM_REF2:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF2\n" );
- LoadSharedImage( epcEvent );
- break;
- }
- case OP_PIXMAP_REF:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_PIXMAP_REF\n" );
- LoadPixmapImage( epcEvent );
- break;
- }
- case OP_RESIZE:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_RESIZE\n" );
-
- if( (epcEvent->data) && (epcEvent->size >= (int)sizeof(IpcDataResize)) )
- {
- IpcDataResize *newSize = static_cast<IpcDataResize*>( epcEvent->data );
- Resize( newSize->w, newSize->h );
- }
- break;
- }
- case OP_MSG_PARENT:
- {
- int msgDomain = epcEvent->ref;
- int msgId = epcEvent->ref_to;
-
- void *msgData = NULL;
- int msgDataSize = 0;
- msgData = epcEvent->data;
- msgDataSize = epcEvent->size;
-
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_MSG_PARENT. msgDomain = %d\n", msgDomain );
-
- if( msgDomain == MSG_DOMAIN_CONTROL_INDICATOR )
- {
- switch( msgId )
- {
- case MSG_ID_INDICATOR_TYPE:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_MSG_PARENT, INDICATOR_TYPE\n" );
- Type* indicatorType = static_cast<Type*>( epcEvent->data );
- OnIndicatorTypeChanged( *indicatorType );
- break;
- }
-
- case MSG_ID_INDICATOR_START_ANIMATION:
- {
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: MSG_ID_INDICATOR_START_ANIMATION\n" );
-
- if (msgDataSize != (int)sizeof(IpcIndicatorDataAnimation))
- {
- DALI_LOG_ERROR("Message data is incorrect\n");
- break;
- }
-
- IpcIndicatorDataAnimation *animData = static_cast<IpcIndicatorDataAnimation*>(msgData);
-
- if(!CheckVisibleState())
- {
- ShowIndicator( animData->duration /* n sec */ );
- }
- break;
- }
- }
- }
- break;
- }
- }
-}
-
-void Indicator::ConnectionClosed()
-{
- DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
-
- // Will get this callback if the server connection failed to start up.
- delete mServerConnection;
- mServerConnection = NULL;
- mState = DISCONNECTED;
-
- // Attempt to re-connect
- Connect();
-}
-
-bool Indicator::CheckVisibleState()
-{
- if( mOrientation == Dali::Window::LANDSCAPE
- || mOrientation == Dali::Window::LANDSCAPE_INVERSE
- || (mVisible == Dali::Window::INVISIBLE)
- || (mVisible == Dali::Window::AUTO && !mIsShowing) )
- {
- return false;
- }
-
- return true;
-}
-
-void Indicator::ClearSharedFileInfo()
-{
- for( int i = 0; i < SHARED_FILE_NUMBER; i++ )
- {
- delete mSharedFileInfo[i].mLock;
- mSharedFileInfo[i].mLock = NULL;
-
- delete mSharedFileInfo[i].mSharedFile;
- mSharedFileInfo[i].mSharedFile = NULL;
-
- mSharedFileInfo[i].mLockFileName.clear();
- mSharedFileInfo[i].mSharedFileName.clear();
- }
-}
-
-/**
- * duration can be this
- *
- * enum
- * {
- * KEEP_SHOWING = -1,
- * HIDE_NOW = 0
- * };
- */
-void Indicator::ShowIndicator(float duration)
-{
- if( !mIndicatorAnimation )
- {
- mIndicatorAnimation = Dali::Animation::New(SLIDING_ANIMATION_DURATION);
- mIndicatorAnimation.FinishedSignal().Connect(this, &Indicator::OnAnimationFinished);
- }
-
- if(mIsShowing && !EqualsZero(duration))
- {
- // If need to show during showing, do nothing.
- // In 2nd phase (below) will update timer
- }
- else if(!mIsShowing && mIsAnimationPlaying && EqualsZero(duration))
- {
- // If need to hide during hiding or hidden already, do nothing
- }
- else
- {
- mIndicatorAnimation.Clear();
-
- if( EqualsZero(duration) )
- {
- mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, -mImageHeight, 0), Dali::AlphaFunction::EASE_OUT );
-
- mIsShowing = false;
-
- OnIndicatorTypeChanged( INDICATOR_TYPE_2 ); // un-toucable
- }
- else
- {
- mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, 0, 0), Dali::AlphaFunction::EASE_OUT );
-
- mIsShowing = true;
-
- OnIndicatorTypeChanged( INDICATOR_TYPE_1 ); // touchable
- }
-
- mIndicatorAnimation.Play();
- mIsAnimationPlaying = true;
- }
-
- if(duration > 0)
- {
- if(!mShowTimer)
- {
- mShowTimer = Dali::Timer::New(1000 * duration);
- mShowTimer.TickSignal().Connect(this, &Indicator::OnShowTimer);
- }
- mShowTimer.SetInterval(1000* duration);
- mShowTimer.Start();
-
- if( mVisible == Dali::Window::AUTO )
- {
- // check the stage touch
- Dali::Stage::GetCurrent().TouchSignal().Connect( this, &Indicator::OnStageTouch );
- }
- }
- else
- {
- if(mShowTimer && mShowTimer.IsRunning())
- {
- mShowTimer.Stop();
- }
-
- if( mVisible == Dali::Window::AUTO )
- {
- // check the stage touch
- Dali::Stage::GetCurrent().TouchSignal().Disconnect( this, &Indicator::OnStageTouch );
- }
- }
-}
-
-bool Indicator::OnShowTimer()
-{
- // after time up, hide indicator
- ShowIndicator( HIDE_NOW );
-
- return false;
-}
-
-void Indicator::OnAnimationFinished(Dali::Animation& animation)
-{
- mIsAnimationPlaying = false;
- // once animation is finished and indicator is hidden, take it off stage
- if( mObserver != NULL )
- {
- mObserver->IndicatorVisibilityChanged( mIsShowing ); // is showing?
- }
-}
-
-void Indicator::OnPan( Dali::Actor actor, const Dali::PanGesture& gesture )
-{
- // Nothing to do, but we still want to consume pan
-}
-
-void Indicator::OnStageTouch(const Dali::TouchData& touchData)
-{
- // when stage is touched while indicator is showing temporary, hide it
- if( mIsShowing && ( CheckVisibleState() == false || mVisible == Dali::Window::AUTO ) )
- {
- switch( touchData.GetState(0) )
- {
- case Dali::PointState::DOWN:
- {
- // if touch point is inside the indicator, indicator is not hidden
- if( mImageHeight < int( touchData.GetScreenPosition(0).y ) )
- {
- ShowIndicator( HIDE_NOW );
- }
- break;
- }
-
- default:
- break;
- }
- }
-}
-
-} // Adaptor
-
-} // Internal
-
-} // Dali
-
-#pragma GCC diagnostic pop
+++ /dev/null
-#ifndef __DALI_INTERNAL_ECORE_INDICATOR_H__
-#define __DALI_INTERNAL_ECORE_INDICATOR_H__
-
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/animation/animation.h>
-#include <dali/public-api/events/pan-gesture.h>
-#include <dali/public-api/events/pan-gesture-detector.h>
-#include <dali/public-api/events/touch-data.h>
-#include <dali/public-api/rendering/renderer.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/window-system/common/indicator-interface.h>
-#include <dali/internal/window-system/common/indicator-buffer.h>
-#include <dali/internal/window-system/common/ecore-server-connection.h>
-#include <dali/internal/system/common/shared-file.h>
-#include <dali/public-api/adaptor-framework/timer.h>
-#include <dali/public-api/adaptor-framework/window.h>
-
-namespace Dali
-{
-namespace Integration
-{
-class Core;
-}
-
-namespace Internal
-{
-namespace Adaptor
-{
-class Adaptor;
-
-typedef unsigned int PixmapId;
-
-/**
- * The Indicator class connects to the indicator server, and gets and draws the indicator
- * for the given orientation.
- */
-class Indicator : public ConnectionTracker, public ServerConnection::Observer, public IndicatorInterface
-{
-public:
-
- enum State
- {
- DISCONNECTED,
- CONNECTED
- };
-
- /**
- * copied from ecore_evas_extn_engine.h
- */
- enum BufferType
- {
- BUFFER_TYPE_SHM = 0, ///< shared memory-based buffer backend
- BUFFER_TYPE_DRI2_PIXMAP, ///< dri2 pixmap-based buffer backend
- BUFFER_TYPE_EVASGL_PIXMAP, ///< pixmap backend for Evas GL only (DEPRECATED)
- BUFFER_TYPE_GL_PIXMAP, ///< double buffered GL pixmap backend
- };
-
-protected:
- /**
- * Class to encapsulate lock file
- */
- class LockFile
- {
- public:
- /**
- * Constructor. open lock file
- */
- LockFile(const std::string filename);
-
- /**
- * Close lock file
- */
- ~LockFile();
-
- /**
- * Grab an exclusive lock on this file
- * @return true if the lock succeeded, false if it failed
- */
- bool Lock();
-
- /**
- * Remove the lock
- */
- void Unlock();
-
- /**
- * Test if there is an error with the lock file, and clears
- * the error flag;
- * @return true if an error was thrown
- */
- bool RetrieveAndClearErrorStatus();
-
- private:
- std::string mFilename;
- int mFileDescriptor;
- bool mErrorThrown;
- };
-
- /**
- * Class to ensure lock/unlock through object destruction
- */
- class ScopedLock
- {
- public:
- /**
- * Constructor - creates a lock on the lockfile
- * @param[in] lockFile The lockfile to use
- */
- ScopedLock( LockFile* lockFile );
-
- /**
- * Destructor - removes the lock (if any) on the lockfile
- */
- ~ScopedLock();
-
- /**
- * Method to test if the locking succeeded
- * @return TRUE if locked
- */
- bool IsLocked();
-
- private:
- LockFile* mLockFile; ///< The lock file to use
- bool mLocked; ///< Whether the lock succeeded
- };
-
-
-public: // Dali::Internal::Adaptor::IndicicatorInterface
- /**
- * @copydoc Dali::Internal::IndicatorInterface::IndicatorInterface
- */
- Indicator( Adaptor* adaptor,
- Dali::Window::WindowOrientation orientation,
- IndicatorInterface::Observer* observer );
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::~IndicatorInterface
- */
- virtual ~Indicator();
-
-
- virtual void SetAdaptor(Adaptor* adaptor);
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::GetActor
- */
- virtual Dali::Actor GetActor();
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::Open
- */
- virtual void Open( Dali::Window::WindowOrientation orientation );
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::Close
- */
- virtual void Close();
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::SetOpacityMode
- */
- virtual void SetOpacityMode( Dali::Window::IndicatorBgOpacity mode );
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::SetVisible
- */
- virtual void SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate = false );
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::IsConnected
- */
- virtual bool IsConnected();
-
- /**
- * @copydoc Dali::Internal::IndicatorInterface::SendMessage
- */
- virtual bool SendMessage( int messageDomain, int messageId, const void *data, int size );
-
-private:
- /**
- * Initialize the indicator actors
- */
- void Initialize();
-
- /**
- * Constructs the renderers used for the background
- */
- Dali::Geometry CreateBackgroundGeometry();
-
- /**
- * Set the texture to be rendered as indicator foreground
- * @param[in] texture The foreground texture.
- */
- void SetForegroundImage( Dali::Texture texture );
-
- /**
- * Touch event callback.
- * It should pass the valid touch event to indicator server
- *
- * @param[in] indicator The indicator actor that was touched
- * @param[in] touchEvent The touch data
- */
- bool OnTouch(Dali::Actor indicator, const Dali::TouchData& touchData);
-
- /**
- * Pan gesture callback.
- * It finds flick down gesture to show hidden indicator image
- *
- * @param[in] actor The actor for gesture
- * @param[in] gesture The gesture event
- */
- void OnPan( Dali::Actor actor, const Dali::PanGesture& gesture );
-
- /**
- * Touch event callback on stage.
- * If stage is touched, hide showing indicator image
- *
- * @param[in] touchEvent The touch data
- */
- void OnStageTouch(const Dali::TouchData& touchData);
-
- /**
- * Connect to the indicator service
- */
- bool Connect();
-
- /**
- * Start the reconnection timer. This will run every second until we reconnect to
- * the indicator service.
- */
- void StartReconnectionTimer();
-
- /**
- * If connection failed, attempt to re-connect every second
- */
- bool OnReconnectTimer();
-
- /**
- * Disconnect from the indicator service
- */
- void Disconnect();
-
- /**
- * Handle Resize event
- * @param[in] width The new width
- * @param[in] height The new height
- */
- void Resize( int width, int height );
-
- /**
- * Set the lock file info.
- * @param[in] epcEvent Current ecore event.
- */
- void SetLockFileInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
-
- /**
- * Set the shared indicator image info
- * @param[in] epcEvent The event containing the image data
- */
- void SetSharedImageInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
-
- /**
- * Load the shared indicator image
- * @param[in] epcEvent The event containing the image data
- */
- void LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent );
-
- /**
- * Load the pixmap indicator image
- * @param[in] epcEvent The event containing the image data
- */
- void LoadPixmapImage( Ecore_Ipc_Event_Server_Data *epcEvent );
-
- /**
- * Update top margin of the stage as much as indicator height
- */
- void UpdateTopMargin();
-
- /**
- * Update the visibility and position of the actors
- */
- void UpdateVisibility();
-
- /**
- * Inform dali that the indicator data has been updated.
- * @param[in] bufferNumber The shared file number
- */
- void UpdateImageData( int bufferNumber );
-
- /**
- * Lock the temporary file, Copy the shared image into IndicatorBuffer
- * and then unlock the temporary file.
- * Caller should ensure we are not writing image to gl texture.
- * @param[in] bufferNumber The shared file number
- */
- bool CopyToBuffer( int bufferNumber );
-
- /**
- * Create a new image for the indicator, and set up signal handling for it.
- * @param[in] bufferNumber The shared file number
- */
- void CreateNewImage( int bufferNumber );
-
- /**
- * Create a new pixmap image for the indicator, and set up signal handling for it.
- */
- void CreateNewPixmapImage();
-
- /**
- * Indicator type has changed.
- * Inform observer
- * @param[in] type The new indicator type
- */
- void OnIndicatorTypeChanged( Type type );
-
- /**
- * Check whether the indicator could be visible or invisible
- * @return true if indicator should be shown
- */
- bool CheckVisibleState();
-
- /**
- * Show/Hide indicator actor with effect
- * @param[in] duration how long need to show the indicator,
- * if it equal to 0, hide the indicator
- * if it less than 0, show always
- */
- void ShowIndicator( float duration );
-
- /**
- * Showing timer callback
- */
- bool OnShowTimer();
-
- /**
- * Showing animation finished callback
- * @param[in] animation
- */
- void OnAnimationFinished( Dali::Animation& animation );
-
-private: // Implementation of ServerConnection::Observer
- /**
- * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
- */
- virtual void DataReceived( void* event );
-
- /**
- * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
- */
- virtual void ConnectionClosed();
-
-private:
-
- /**
- * Clear shared file info
- */
- void ClearSharedFileInfo();
-
-private:
-
- struct SharedFileInfo
- {
- SharedFileInfo()
- : mLock( NULL ),
- mSharedFile( NULL ),
- mImageWidth( 0 ),
- mImageHeight( 0 ),
- mLockFileName(),
- mSharedFileName(),
- mSharedFileID( 0 ),
- mSharedFileNumber( 0 )
- {
- }
-
- LockFile* mLock; ///< File lock for the shared file
- SharedFile* mSharedFile; ///< Shared file
-
- int mImageWidth; ///< Shared image width
- int mImageHeight; ///< Shared image height
-
- std::string mLockFileName; ///< Lock file name
- std::string mSharedFileName; ///< Shared file name
- int mSharedFileID; ///< Shared file ID
- int mSharedFileNumber; ///< Shared file number
- };
-
- static const int SHARED_FILE_NUMBER = 2; ///< Shared file number
-
- Dali::Geometry mTranslucentGeometry; ///< Geometry used for rendering the translucent background
- Dali::Geometry mSolidGeometry; ///< Geometry used for rendering the opaque background
- Dali::Shader mBackgroundShader; ///< Shader used for rendering the background
-
- IndicatorBufferPtr mIndicatorBuffer; ///< class which handles indicator rendering
- PixmapId mPixmap; ///< Pixmap including indicator content
- Dali::Renderer mForegroundRenderer; ///< Renderer renders the indicator foreground
- Dali::Renderer mBackgroundRenderer; ///< Renderer renders the indicator background
-
- Dali::Actor mIndicatorContentActor; ///< Actor container for image and background
- Dali::Actor mIndicatorActor; ///< Handle to topmost indicator actor
- Dali::Actor mEventActor; ///< Handle to event
- Dali::PanGestureDetector mPanDetector; ///< Pan detector to find flick gesture for hidden indicator
- float mGestureDeltaY; ///< Checking how much panning moved
- bool mGestureDetected; ///< Whether find the flick gesture
-
- Dali::Timer mReconnectTimer; ///< Reconnection timer
- SlotDelegate< Indicator > mConnection;
-
- Dali::Window::IndicatorBgOpacity mOpacityMode; ///< Opacity enum for background
- Indicator::State mState; ///< The connection state
-
- Adaptor* mAdaptor;
- ServerConnection* mServerConnection;
- IndicatorInterface::Observer* mObserver; ///< Upload observer
-
- Dali::Window::WindowOrientation mOrientation;
- int mImageWidth;
- int mImageHeight;
- Dali::Window::IndicatorVisibleMode mVisible; ///< Whether the indicator is visible
-
- Dali::Timer mShowTimer; ///< Timer to show indicator
- bool mIsShowing; ///< Whether the indicator is showing on the screen
- Dali::Animation mIndicatorAnimation; ///< Animation to show/hide indicator image
-
- bool mIsAnimationPlaying; ///< Whether the animation is playing
-
- int mCurrentSharedFile; ///< Current shared file number
- SharedFileInfo mSharedFileInfo[SHARED_FILE_NUMBER]; ///< Table to store shared file info
-
- BufferType mSharedBufferType; ///< Shared buffer type which is used to render indicator
-
- struct Impl; ///< Contains Ecore specific information
- Impl* mImpl; ///< Created on construction and destroyed on destruction.
-
- bool mBackgroundVisible; ///< Indicate whether background is visible
- int mTopMargin; ///< Top margin of the stage for indicator
-};
-
-} // Adaptor
-} // Internal
-} // Dali
-
-#endif
namespace Adaptor
{
#if defined(DEBUG_ENABLED)
-extern Debug::Filter* gIndicatorLogFilter;
+Debug::Filter* gServerConnectionLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SERVER_CONNECTION");
#endif
ServerConnection::ServerConnection(
ipctype = ECORE_IPC_LOCAL_SYSTEM;
}
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "ServerConnection: Connecting to %s %d\n", mService.name, mService.num );
+ DALI_LOG_INFO( gServerConnectionLogFilter, Debug::General, "ServerConnection: Connecting to %s %d\n", mService.name, mService.num );
mIpcServer = ecore_ipc_server_connect( ipctype, (char *)mService.name, mService.num, this );
if( !mIpcServer )
{
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "mIpcServer is null\n" );
+ DALI_LOG_INFO( gServerConnectionLogFilter, Debug::General, "mIpcServer is null\n" );
ecore_ipc_shutdown();
}
else
Eina_Bool ServerConnection::IpcServerAdd( void *data, int /*type*/, void *event )
{
- DALI_LOG_INFO(gIndicatorLogFilter, Debug::General, "ServerConnection: IpcServerAdd\n" );
+ DALI_LOG_INFO(gServerConnectionLogFilter, Debug::General, "ServerConnection: IpcServerAdd\n" );
return ECORE_CALLBACK_PASS_ON;
}
Eina_Bool ServerConnection::IpcServerDel( void *data, int /*type*/, void *event )
{
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "ServerConnection: IpcServerDel\n" );
+ DALI_LOG_INFO( gServerConnectionLogFilter, Debug::General, "ServerConnection: IpcServerDel\n" );
Ecore_Ipc_Event_Server_Del *e = static_cast<Ecore_Ipc_Event_Server_Del *>( event );
ServerConnection* connection = static_cast<ServerConnection*>( data );
Eina_Bool ServerConnection::IpcServerData( void *data, int /*type*/, void *event )
{
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "ServerConnection: IpcServerData\n" );
+ DALI_LOG_INFO( gServerConnectionLogFilter, Debug::General, "ServerConnection: IpcServerData\n" );
Ecore_Ipc_Event_Server_Data *e = static_cast<Ecore_Ipc_Event_Server_Data *>( event );
ServerConnection* connection = static_cast<ServerConnection*>( data );
{
if( mConnected )
{
- DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "ServerConnection: CloseConnection\n" );
+ DALI_LOG_INFO( gServerConnectionLogFilter, Debug::General, "ServerConnection: CloseConnection\n" );
if( mIpcServer )
{
} // Dali
-#pragma GCC diagnostic pop
\ No newline at end of file
+#pragma GCC diagnostic pop
+++ /dev/null
-#ifndef DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_BASE_FACTORY_H
-#define DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_BASE_FACTORY_H
-
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <memory>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-
-class WindowBase;
-class Window;
-class WindowRenderSurface;
-
-class WindowBaseFactory
-{
-public:
-
- WindowBaseFactory() = default;
- virtual ~WindowBaseFactory() = default;
-
- virtual std::unique_ptr< Dali::Internal::Adaptor::WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) = 0;
-};
-
-extern std::unique_ptr< WindowBaseFactory > GetWindowBaseFactory();
-
-} // namespace Adaptor
-} // namespace Internal
-} // namespace Dali
-
-#endif // DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_BASE_FACTORY_H
--- /dev/null
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_FACTORY_H
+#define DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_FACTORY_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/window.h>
+#include <dali/internal/window-system/common/indicator-interface.h>
+
+// EXTERNAL INCLUDES
+#include <memory>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+class Adaptor;
+class WindowBase;
+class Window;
+class WindowRenderSurface;
+
+class WindowFactory
+{
+public:
+
+ WindowFactory() = default;
+ virtual ~WindowFactory() = default;
+
+ virtual std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) = 0;
+
+ virtual std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) = 0;
+};
+
+extern std::unique_ptr< WindowFactory > GetWindowFactory();
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
+
+#endif // DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_FACTORY_H
// INTERNAL HEADERS
#include <dali/internal/input/common/drag-and-drop-detector-impl.h>
-#include <dali/internal/window-system/common/ecore-indicator-impl.h>
#include <dali/internal/window-system/common/window-visibility-observer.h>
#include <dali/internal/window-system/common/orientation-impl.h>
#include <dali/internal/window-system/common/render-surface-factory.h>
-#include <dali/internal/window-system/common/window-base-factory.h>
+#include <dali/internal/window-system/common/window-factory.h>
#include <dali/internal/window-system/common/window-base.h>
#include <dali/internal/window-system/common/window-render-surface.h>
mIconified( false ),
mOpaqueState( false ),
mResizeEnabled( false ),
- mIndicator( NULL ),
+ mIndicator(),
mIndicatorOrientation( Dali::Window::PORTRAIT ),
mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
mIndicatorOpacityMode( Dali::Window::OPAQUE ),
Dali::RenderTask indicatorTask = taskList.GetTask(0);
mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
mIndicator->Close();
- delete mIndicator;
}
if ( mAdaptor )
mSurface = windowRenderSurface.release();
// create a window base
- auto windowBaseFactory = Dali::Internal::Adaptor::GetWindowBaseFactory();
- mWindowBase = windowBaseFactory->CreateWindowBase( this, mSurface );
+ auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
+ mWindowBase = windowFactory->CreateWindowBase( this, mSurface );
mWindowBase->Initialize();
{
if( mIndicatorVisible != Dali::Window::INVISIBLE )
{
- mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
- mIndicator->SetOpacityMode( mIndicatorOpacityMode );
- Dali::Actor actor = mIndicator->GetActor();
- SetIndicatorActorRotation();
- mOverlay->Add(actor);
+ auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
+ mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
+ if( mIndicator )
+ {
+ mIndicator->SetOpacityMode( mIndicatorOpacityMode );
+ Dali::Actor actor = mIndicator->GetActor();
+ SetIndicatorActorRotation();
+ mOverlay->Add(actor);
+ }
}
// else don't create a hidden indicator
}
{
mShowRotatedIndicatorOnClose = true;
mNextIndicatorOrientation = orientation;
- mIndicator->Close(); // May synchronously call IndicatorClosed() callback
+ if( mIndicator )
+ {
+ mIndicator->Close(); // May synchronously call IndicatorClosed() callback
+ }
}
else
{
void Window::SetIndicatorActorRotation()
{
DALI_LOG_TRACE_METHOD( gWindowLogFilter );
- DALI_ASSERT_DEBUG( mIndicator != NULL );
-
- Dali::Actor actor = mIndicator->GetActor();
- switch( mIndicatorOrientation )
+ if( mIndicator )
{
- case Dali::Window::PORTRAIT:
- actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
- actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- actor.SetOrientation( Degree(0), Vector3::ZAXIS );
- break;
- case Dali::Window::PORTRAIT_INVERSE:
- actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
- actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- actor.SetOrientation( Degree(180), Vector3::ZAXIS );
- break;
- case Dali::Window::LANDSCAPE:
- actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
- actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- actor.SetOrientation( Degree(270), Vector3::ZAXIS );
- break;
- case Dali::Window::LANDSCAPE_INVERSE:
- actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
- actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- actor.SetOrientation( Degree(90), Vector3::ZAXIS );
- break;
+ Dali::Actor actor = mIndicator->GetActor();
+ switch( mIndicatorOrientation )
+ {
+ case Dali::Window::PORTRAIT:
+ actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ actor.SetOrientation( Degree(0), Vector3::ZAXIS );
+ break;
+ case Dali::Window::PORTRAIT_INVERSE:
+ actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ actor.SetOrientation( Degree(180), Vector3::ZAXIS );
+ break;
+ case Dali::Window::LANDSCAPE:
+ actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ actor.SetOrientation( Degree(270), Vector3::ZAXIS );
+ break;
+ case Dali::Window::LANDSCAPE_INVERSE:
+ actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
+ actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ actor.SetOrientation( Degree(90), Vector3::ZAXIS );
+ break;
+ }
}
}
mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
}
-void Window::IndicatorTypeChanged(Indicator::Type type)
+void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
{
mWindowBase->IndicatorTypeChanged( type );
}
if( mShowRotatedIndicatorOnClose )
{
Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
- mIndicator->Open( mNextIndicatorOrientation );
+ if( mIndicator )
+ {
+ mIndicator->Open( mNextIndicatorOrientation );
+ }
mIndicatorOrientation = mNextIndicatorOrientation;
SetIndicatorActorRotation();
DoShowIndicator( currentOrientation );
mIndicator->Close();
}
- delete mIndicator;
- mIndicator = NULL;
+ mIndicator.release();
}
void Window::OnDestroy()
-#ifndef __DALI_INTERNAL_WINDOW_H__
-#define __DALI_INTERNAL_WINDOW_H__
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_IMPL_H
+#define DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_IMPL_H
/*
* Copyright (c) 2018 Samsung Electronics Co., Ltd.
private:
- WindowRenderSurface* mSurface;
- std::unique_ptr< WindowBase > mWindowBase;
- Dali::Window::IndicatorVisibleMode mIndicatorVisible; ///< public state
- bool mIndicatorIsShown:1; ///< private state
- bool mShowRotatedIndicatorOnClose:1;
- bool mStarted:1;
- bool mIsTransparent:1;
- bool mIsFocusAcceptable:1;
- bool mVisible:1;
- bool mIconified:1;
- bool mOpaqueState:1;
- bool mResizeEnabled:1;
- IndicatorInterface* mIndicator;
- Dali::Window::WindowOrientation mIndicatorOrientation;
- Dali::Window::WindowOrientation mNextIndicatorOrientation;
- Dali::Window::IndicatorBgOpacity mIndicatorOpacityMode;
- Integration::SystemOverlay* mOverlay;
- Adaptor* mAdaptor;
- Dali::DragAndDropDetector mDragAndDropDetector;
- Dali::Window::Type mType;
+ WindowRenderSurface* mSurface;
+ std::unique_ptr< WindowBase > mWindowBase;
+ Dali::Window::IndicatorVisibleMode mIndicatorVisible; ///< public state
+ bool mIndicatorIsShown:1; ///< private state
+ bool mShowRotatedIndicatorOnClose:1;
+ bool mStarted:1;
+ bool mIsTransparent:1;
+ bool mIsFocusAcceptable:1;
+ bool mVisible:1;
+ bool mIconified:1;
+ bool mOpaqueState:1;
+ bool mResizeEnabled:1;
+ std::unique_ptr< IndicatorInterface > mIndicator;
+ Dali::Window::WindowOrientation mIndicatorOrientation;
+ Dali::Window::WindowOrientation mNextIndicatorOrientation;
+ Dali::Window::IndicatorBgOpacity mIndicatorOpacityMode;
+ Integration::SystemOverlay* mOverlay;
+ Adaptor* mAdaptor;
+ Dali::DragAndDropDetector mDragAndDropDetector;
+ Dali::Window::Type mType;
OrientationPtr mOrientation;
std::vector<Dali::Window::WindowOrientation> mAvailableOrientations;
} // namespace Dali
-#endif // __DALI_INTERNAL_WINDOW_H__
+#endif // DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_IMPL_H
# module: window-system, backend: common
adaptor_window_system_common_src_files=\
${adaptor_window_system_dir}/common/display-connection.cpp \
- ${adaptor_window_system_dir}/common/ecore-indicator-impl.cpp \
${adaptor_window_system_dir}/common/ecore-server-connection.cpp \
${adaptor_window_system_dir}/common/indicator-buffer.cpp \
${adaptor_window_system_dir}/common/native-render-surface-factory.cpp \
${adaptor_window_system_dir}/tizen-wayland/display-connection-factory-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/display-connection-impl-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/event-handler-ecore-wl.cpp \
+ ${adaptor_window_system_dir}/tizen-wayland/indicator-impl-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/native-render-surface-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/render-surface-factory-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/window-render-surface-ecore-wl.cpp \
${adaptor_window_system_dir}/tizen-wayland/window-base-ecore-wl.cpp \
- ${adaptor_window_system_dir}/tizen-wayland/window-base-factory-ecore-wl.cpp
+ ${adaptor_window_system_dir}/tizen-wayland/window-factory-ecore-wl.cpp
# module: window-system, backend: ubuntu-x11
adaptor_window_system_ubuntu_x11_src_files=\
${adaptor_window_system_dir}/ubuntu-x11/window-interface-ecore-x.cpp \
${adaptor_window_system_dir}/ubuntu-x11/window-render-surface-ecore-x.cpp \
${adaptor_window_system_dir}/ubuntu-x11/window-base-ecore-x.cpp \
- ${adaptor_window_system_dir}/ubuntu-x11/window-base-factory-ecore-x.cpp
+ ${adaptor_window_system_dir}/ubuntu-x11/window-factory-ecore-x.cpp
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h>
+
+// EXTERNAL INCLUDES
+// Ecore is littered with C style cast
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#include <Ecore.h>
+#include <Evas.h>
+#include <Ecore_Wayland.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <dali/public-api/images/native-image.h>
+#include <dali/public-api/events/touch-point.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/pixel.h>
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/adaptor/common/adaptor-impl.h>
+#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
+
+#if defined(DEBUG_ENABLED)
+#define STATE_DEBUG_STRING(state) (state==DISCONNECTED?"DISCONNECTED":state==CONNECTED?"CONNECTED":"UNKNOWN")
+#endif
+
+namespace
+{
+
+const float SLIDING_ANIMATION_DURATION( 0.2f ); // 200 milli seconds
+const float AUTO_INDICATOR_STAY_DURATION( 3.0f ); // 3 seconds
+
+enum
+{
+ KEEP_SHOWING = -1,
+ HIDE_NOW = 0
+};
+
+const int NUM_GRADIENT_INTERVALS(5); // Number of gradient intervals
+const float GRADIENT_ALPHA[NUM_GRADIENT_INTERVALS+1] = { 0.6f, 0.38f, 0.20f, 0.08f, 0.0f, 0.0f };
+
+#define MAKE_SHADER(A)#A
+
+const char* BACKGROUND_VERTEX_SHADER = MAKE_SHADER(
+ attribute mediump vec2 aPosition;
+ attribute mediump float aAlpha;
+ varying mediump float vAlpha;
+ uniform mediump mat4 uMvpMatrix;
+ uniform mediump vec3 uSize;
+
+ void main()
+ {
+ mediump vec4 vertexPosition = vec4( aPosition * uSize.xy, 0.0, 1.0 );
+ vertexPosition = uMvpMatrix * vertexPosition;
+
+ vAlpha = aAlpha;
+ gl_Position = vertexPosition;
+ }
+);
+
+const char* BACKGROUND_FRAGMENT_SHADER = MAKE_SHADER(
+ uniform lowp vec4 uColor;
+ varying mediump float vAlpha;
+
+ void main()
+ {
+ gl_FragColor = uColor;
+ gl_FragColor.a *= vAlpha;
+ }
+);
+
+const char* FOREGROUND_VERTEX_SHADER = DALI_COMPOSE_SHADER(
+ attribute mediump vec2 aPosition;\n
+ varying mediump vec2 vTexCoord;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump vec4 sTextureRect;\n
+ \n
+ void main()\n
+ {\n
+ gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n
+ vTexCoord = aPosition + vec2(0.5);\n
+ }\n
+);
+
+const char* FOREGROUND_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+ varying mediump vec2 vTexCoord;\n
+ uniform sampler2D sTexture;\n
+ \n
+ void main()\n
+ {\n
+ gl_FragColor = texture2D( sTexture, vTexCoord );\n // the foreground does not apply actor color
+ }\n
+);
+
+Dali::Geometry CreateQuadGeometry()
+{
+ Dali::Property::Map quadVertexFormat;
+ quadVertexFormat["aPosition"] = Dali::Property::VECTOR2;
+ Dali::PropertyBuffer vertexData = Dali::PropertyBuffer::New( quadVertexFormat );
+
+ const float halfQuadSize = .5f;
+ struct QuadVertex { Dali::Vector2 position; };
+ QuadVertex quadVertexData[4] = {
+ { Dali::Vector2(-halfQuadSize, -halfQuadSize) },
+ { Dali::Vector2(-halfQuadSize, halfQuadSize) },
+ { Dali::Vector2( halfQuadSize, -halfQuadSize) },
+ { Dali::Vector2( halfQuadSize, halfQuadSize) } };
+ vertexData.SetData(quadVertexData, 4);
+
+ Dali::Geometry quad = Dali::Geometry::New();
+ quad.AddVertexBuffer( vertexData );
+ quad.SetType( Dali::Geometry::TRIANGLE_STRIP );
+ return quad;
+}
+
+// indicator service name
+const char* INDICATOR_SERVICE_NAME("elm_indicator");
+
+// Copied from ecore_evas_extn_engine.h
+
+enum // opcodes
+{
+ OP_RESIZE,
+ OP_SHOW,
+ OP_HIDE,
+ OP_FOCUS,
+ OP_UNFOCUS,
+ OP_UPDATE,
+ OP_UPDATE_DONE,
+ OP_SHM_REF0,
+ OP_SHM_REF1,
+ OP_SHM_REF2,
+ OP_PROFILE_CHANGE_REQUEST,
+ OP_PROFILE_CHANGE_DONE,
+ OP_EV_MOUSE_IN,
+ OP_EV_MOUSE_OUT,
+ OP_EV_MOUSE_UP,
+ OP_EV_MOUSE_DOWN,
+ OP_EV_MOUSE_MOVE,
+ OP_EV_MOUSE_WHEEL,
+ OP_EV_MULTI_UP,
+ OP_EV_MULTI_DOWN,
+ OP_EV_MULTI_MOVE,
+ OP_EV_KEY_UP,
+ OP_EV_KEY_DOWN,
+ OP_EV_HOLD,
+ OP_MSG_PARENT,
+ OP_MSG,
+};
+
+// Copied from elm_conform.c
+
+const int MSG_DOMAIN_CONTROL_INDICATOR( 0x10001 );
+const int MSG_ID_INDICATOR_REPEAT_EVENT( 0x10002 );
+const int MSG_ID_INDICATOR_ROTATION( 0x10003 );
+const int MSG_ID_INDICATOR_OPACITY( 0X1004 );
+const int MSG_ID_INDICATOR_TYPE( 0X1005 );
+const int MSG_ID_INDICATOR_START_ANIMATION( 0X10006 );
+
+struct IpcDataResize
+{
+ int w, h;
+};
+
+struct IpcIndicatorDataAnimation
+{
+ unsigned int xwin;
+ double duration;
+};
+
+struct IpcDataEvMouseUp
+{
+ int b;
+ Evas_Button_Flags flags;
+ int mask;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+
+ IpcDataEvMouseUp(unsigned long timestamp)
+ : b(1),
+ flags(EVAS_BUTTON_NONE),
+ mask(0),
+ timestamp(static_cast<unsigned int>(timestamp)),
+ event_flags(EVAS_EVENT_FLAG_NONE)
+ {
+ }
+};
+
+struct IpcDataEvMouseDown
+{
+ int b;
+ Evas_Button_Flags flags;
+ int mask;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+
+ IpcDataEvMouseDown(unsigned long timestamp)
+ : b(1),
+ flags(EVAS_BUTTON_NONE),
+ mask(0),
+ timestamp(static_cast<unsigned int>(timestamp)),
+ event_flags(EVAS_EVENT_FLAG_NONE)
+ {
+ }
+};
+
+struct IpcDataEvMouseMove
+{
+ int x, y;
+ Evas_Button_Flags flags;
+ int mask;
+ unsigned int timestamp;
+ Evas_Event_Flags event_flags;
+
+ IpcDataEvMouseMove(const Dali::Vector2& touchPoint, unsigned long timestamp)
+ : x(static_cast<Evas_Coord>(touchPoint.x)),
+ y(static_cast<Evas_Coord>(touchPoint.y)),
+ flags(EVAS_BUTTON_NONE),
+ mask(0),
+ timestamp(static_cast<unsigned int>(timestamp)),
+ event_flags(EVAS_EVENT_FLAG_NONE)
+ {
+ }
+};
+
+struct IpcDataEvMouseOut
+{
+ unsigned int timestamp;
+ int mask;
+ Evas_Event_Flags event_flags;
+
+ IpcDataEvMouseOut(unsigned long timestamp)
+ : timestamp(static_cast<unsigned int>(timestamp)),
+ mask(0),
+ event_flags(EVAS_EVENT_FLAG_NONE)
+ {
+ }
+};
+
+#ifdef ENABLE_INDICATOR_IMAGE_SAVING
+
+void SaveIndicatorImage( Dali::NativeImageSourcePtr nativeImageSource )
+{
+ // Save image data to disk in BMP form.
+ static int gFilenameCounter = 0;
+ static const char bmpHeader[] = {
+ 0x42, 0x4d, 0x0a, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x7c, 0x00,
+ 0x00, 0x00,
+ 0xe0, 0x01, 0x00, 0x00, // Width (480)
+ 0x1b, 0x00, 0x00, 0x00, // Height ( 27)
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x80, 0xca, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ // This is a BMP header with width & height hard-coded in.
+ // The data was first determined by dumping the raw data and inspecting in GIMP, before creating this header data.
+ std::vector<unsigned char> buffer;
+ unsigned int w = 0;
+ unsigned int h = 0;
+ Dali::Pixel::Format pixelFormat;
+ if( nativeImageSource->GetPixels( buffer, w, h, pixelFormat ) )
+ {
+ int imageSize = w * h * 4;
+ std::stringstream fileName;
+ // Give each file an incremental filename.
+ fileName << "/opt/usr/media/Images/out-" << std::setfill( '0' ) << std::setw( 5 ) << gFilenameCounter << ".bmp";
+
+ std::ofstream outfile( fileName.str().c_str(), std::ofstream::binary );
+ if( outfile.is_open() )
+ {
+ DALI_LOG_WARNING( "Saving Indicator Image w:%d, h:%d, %s\n", w, h, fileName.str().c_str() );
+
+ outfile.write( bmpHeader, sizeof( bmpHeader ) / sizeof( bmpHeader[0] ) ); // Size of the BMP header.
+ outfile.write( (const char*)buffer.data(), imageSize );
+ outfile.close();
+ gFilenameCounter++;
+ }
+ else
+ {
+ DALI_LOG_ERROR( "COULD NOT OPEN FOR SAVING: %s\n", fileName.str().c_str() );
+ }
+ }
+}
+
+#endif
+
+} // anonymous namespace
+
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gIndicatorLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_INDICATOR");
+#endif
+
+// Impl to hide EFL implementation.
+
+struct IndicatorEcoreWl::Impl
+{
+ enum // operation mode
+ {
+ INDICATOR_HIDE,
+ INDICATOR_STAY_WITH_DURATION
+ };
+
+ /**
+ * Constructor
+ */
+ Impl(IndicatorEcoreWl* indicator)
+ : mIndicator(indicator),
+ mEcoreEventHandler(NULL)
+ {
+#if defined(DALI_PROFILE_MOBILE)
+ mEcoreEventHandler = ecore_event_handler_add(ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this);
+#endif // DALI_PROFILE_MOBILE
+ }
+
+ /**
+ * Destructor
+ */
+ ~Impl()
+ {
+ if ( mEcoreEventHandler )
+ {
+ ecore_event_handler_del(mEcoreEventHandler);
+ }
+ }
+
+ static void SetIndicatorVisibility( void* data, int operation )
+ {
+ IndicatorEcoreWl::Impl* indicatorImpl((IndicatorEcoreWl::Impl*)data);
+
+ if ( indicatorImpl == NULL || indicatorImpl->mIndicator == NULL)
+ {
+ return;
+ }
+ if ( operation == INDICATOR_STAY_WITH_DURATION )
+ {
+ // if indicator is not showing, INDICATOR_FLICK_DONE is given
+ if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO &&
+ !indicatorImpl->mIndicator->mIsShowing )
+ {
+ indicatorImpl->mIndicator->ShowIndicator( AUTO_INDICATOR_STAY_DURATION );
+ }
+ }
+ else if( operation == INDICATOR_HIDE )
+ {
+ if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO &&
+ indicatorImpl->mIndicator->mIsShowing )
+ {
+ indicatorImpl->mIndicator->ShowIndicator( HIDE_NOW );
+ }
+ }
+ }
+
+#if defined(DALI_PROFILE_MOBILE)
+ /**
+ * Called when the Ecore indicator event is received.
+ */
+ static Eina_Bool EcoreEventIndicator( void* data, int type, void* event )
+ {
+ SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION );
+ return ECORE_CALLBACK_PASS_ON;
+ }
+#endif // DALI_PROFILE_MOBILE
+
+ // Data
+ IndicatorEcoreWl* mIndicator;
+ Ecore_Event_Handler* mEcoreEventHandler;
+};
+
+IndicatorEcoreWl::LockFile::LockFile(const std::string filename)
+: mFilename(filename),
+ mErrorThrown(false)
+{
+ mFileDescriptor = open(filename.c_str(), O_RDWR);
+ if( mFileDescriptor == -1 )
+ {
+ mFileDescriptor = 0;
+ mErrorThrown = true;
+ DALI_LOG_ERROR( "### Cannot open %s for indicator lock ###\n", mFilename.c_str() );
+ }
+}
+
+IndicatorEcoreWl::LockFile::~LockFile()
+{
+ // Closing file descriptor also unlocks file.
+ if( mFileDescriptor > 0 )
+ {
+ close( mFileDescriptor );
+ }
+}
+
+bool IndicatorEcoreWl::LockFile::Lock()
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ bool locked = false;
+ if( mFileDescriptor > 0 )
+ {
+ struct flock filelock;
+
+ filelock.l_type = F_RDLCK;
+ filelock.l_whence = SEEK_SET;
+ filelock.l_start = 0;
+ filelock.l_len = 0;
+ if( fcntl( mFileDescriptor, F_SETLKW, &filelock ) == -1 )
+ {
+ mErrorThrown = true;
+ DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() );
+ }
+ else
+ {
+ locked = true;
+ }
+ }
+ else
+ {
+ mErrorThrown = true;
+ DALI_LOG_ERROR( "### Invalid fd ###\n" );
+ }
+
+ return locked;
+}
+
+void IndicatorEcoreWl::LockFile::Unlock()
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ if( mFileDescriptor > 0 )
+ {
+ struct flock filelock;
+
+ filelock.l_type = F_UNLCK;
+ filelock.l_whence = SEEK_SET;
+ filelock.l_start = 0;
+ filelock.l_len = 0;
+ if (fcntl(mFileDescriptor, F_SETLKW, &filelock) == -1)
+ {
+ mErrorThrown = true;
+ DALI_LOG_ERROR( "### Failed to lock with fd : %s ###\n", mFilename.c_str() );
+ }
+ }
+}
+
+bool IndicatorEcoreWl::LockFile::RetrieveAndClearErrorStatus()
+{
+ bool error = mErrorThrown;
+ mErrorThrown = false;
+ return error;
+}
+
+IndicatorEcoreWl::ScopedLock::ScopedLock(LockFile* lockFile)
+: mLockFile(lockFile),
+ mLocked(false)
+{
+ if(mLockFile)
+ {
+ mLocked = mLockFile->Lock();
+ }
+}
+
+IndicatorEcoreWl::ScopedLock::~ScopedLock()
+{
+ if( mLockFile )
+ {
+ mLockFile->Unlock();
+ }
+}
+
+bool IndicatorEcoreWl::ScopedLock::IsLocked()
+{
+ return mLocked;
+}
+
+IndicatorEcoreWl::IndicatorEcoreWl( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer )
+: mConnection( this ),
+ mOpacityMode( Dali::Window::OPAQUE ),
+ mState( DISCONNECTED ),
+ mAdaptor(adaptor),
+ mServerConnection( NULL ),
+ mObserver( observer ),
+ mOrientation( orientation ),
+ mImageWidth( 0 ),
+ mImageHeight( 0 ),
+ mVisible( Dali::Window::INVISIBLE ),
+ mIsShowing( true ),
+ mIsAnimationPlaying( false ),
+ mCurrentSharedFile( 0 ),
+ mImpl( NULL ),
+ mBackgroundVisible( false ),
+ mTopMargin( 0 )
+{
+ mIndicatorContentActor = Dali::Actor::New();
+ mIndicatorContentActor.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ mIndicatorContentActor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+
+ // Indicator image handles the touch event including "leave"
+ mIndicatorContentActor.SetLeaveRequired( true );
+ mIndicatorContentActor.TouchSignal().Connect( this, &IndicatorEcoreWl::OnTouch );
+ mIndicatorContentActor.SetColor( Color::BLACK );
+
+ mIndicatorActor = Dali::Actor::New();
+ mIndicatorActor.Add( mIndicatorContentActor );
+
+ // Event handler to find out flick down gesture
+ mEventActor = Dali::Actor::New();
+ mEventActor.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ mEventActor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ mIndicatorActor.Add( mEventActor );
+
+ // Attach pan gesture to find flick down during hiding.
+ // It can prevent the problem that scrollview gets pan gesture even indicator area is touched,
+ // since it consumes the pan gesture in advance.
+ mPanDetector = Dali::PanGestureDetector::New();
+ mPanDetector.DetectedSignal().Connect( this, &IndicatorEcoreWl::OnPan );
+ mPanDetector.Attach( mEventActor );
+
+ Open( orientation );
+
+ // register indicator to accessibility adaptor
+ Dali::AccessibilityAdaptor accessibilityAdaptor = AccessibilityAdaptor::Get();
+ if(accessibilityAdaptor)
+ {
+ AccessibilityAdaptor::GetImplementation( accessibilityAdaptor ).SetIndicator( this );
+ }
+ // hide the indicator by default
+ mIndicatorActor.SetVisible( false );
+
+ // create impl to handle ecore event
+ mImpl = new Impl(this);
+}
+
+IndicatorEcoreWl::~IndicatorEcoreWl()
+{
+ if(mImpl)
+ {
+ delete mImpl;
+ mImpl = NULL;
+ }
+
+ if(mEventActor)
+ {
+ mEventActor.TouchSignal().Disconnect( this, &IndicatorEcoreWl::OnTouch );
+ }
+ Disconnect();
+}
+
+void IndicatorEcoreWl::SetAdaptor(Adaptor* adaptor)
+{
+ mAdaptor = adaptor;
+ mIndicatorBuffer->SetAdaptor( adaptor );
+}
+
+Dali::Actor IndicatorEcoreWl::GetActor()
+{
+ return mIndicatorActor;
+}
+
+void IndicatorEcoreWl::Open( Dali::Window::WindowOrientation orientation )
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ // Calls from Window should be set up to ensure we are in a
+ // disconnected state before opening a second time.
+ DALI_ASSERT_DEBUG( mState == DISCONNECTED );
+
+ mOrientation = orientation;
+
+ Connect();
+
+ // Change background visibility depending on orientation
+ if( mOrientation == Dali::Window::LANDSCAPE || mOrientation == Dali::Window::LANDSCAPE_INVERSE )
+ {
+ if( mBackgroundRenderer )
+ {
+ mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer );
+ mBackgroundVisible = false;
+ }
+ }
+ else
+ {
+ SetOpacityMode( mOpacityMode );
+ }
+}
+
+void IndicatorEcoreWl::Close()
+{
+ DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s", STATE_DEBUG_STRING(mState) );
+
+ if( mState == CONNECTED )
+ {
+ Disconnect();
+ if( mObserver != NULL )
+ {
+ mObserver->IndicatorClosed( this );
+ }
+ }
+
+ Dali::Texture emptyTexture;
+ SetForegroundImage( emptyTexture );
+}
+
+void IndicatorEcoreWl::SetOpacityMode( Dali::Window::IndicatorBgOpacity mode )
+{
+ mOpacityMode = mode;
+
+ Dali::Geometry geometry = CreateBackgroundGeometry();
+ if( geometry )
+ {
+ if( mBackgroundRenderer )
+ {
+ if( mBackgroundRenderer.GetGeometry() != geometry )
+ {
+ mBackgroundRenderer.SetGeometry( geometry );
+ }
+ }
+ else
+ {
+ if( !mBackgroundShader )
+ {
+ mBackgroundShader = Dali::Shader::New( BACKGROUND_VERTEX_SHADER, BACKGROUND_FRAGMENT_SHADER, Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT );
+ }
+
+ mBackgroundRenderer = Dali::Renderer::New( geometry, mBackgroundShader );
+ }
+
+ if( !mBackgroundVisible )
+ {
+ mIndicatorContentActor.AddRenderer( mBackgroundRenderer );
+ mBackgroundVisible = true;
+ }
+ }
+ else if( mBackgroundRenderer )
+ {
+ mIndicatorContentActor.RemoveRenderer( mBackgroundRenderer );
+ mBackgroundVisible = false;
+ }
+ UpdateTopMargin();
+}
+
+void IndicatorEcoreWl::SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate )
+{
+ if ( visibleMode != mVisible || forceUpdate )
+ {
+ // If we were previously hidden, then we should update the image data before we display the indicator
+ if ( mVisible == Dali::Window::INVISIBLE )
+ {
+ UpdateImageData( mCurrentSharedFile );
+ }
+
+ if ( visibleMode == Dali::Window::INVISIBLE )
+ {
+ if (mServerConnection)
+ {
+ mServerConnection->SendEvent( OP_HIDE, NULL, 0 );
+ }
+ }
+ else
+ {
+ mIndicatorActor.SetVisible( true );
+
+ if( mServerConnection )
+ {
+ mServerConnection->SendEvent( OP_SHOW, NULL, 0 );
+ }
+ }
+
+ mVisible = visibleMode;
+ UpdateTopMargin();
+
+ if( mForegroundRenderer && mForegroundRenderer.GetTextures().GetTexture( 0u ) )
+ {
+ if( CheckVisibleState() && mVisible == Dali::Window::AUTO )
+ {
+ // hide indicator
+ ShowIndicator( AUTO_INDICATOR_STAY_DURATION /* stay n sec */ );
+ }
+ else if( CheckVisibleState() && mVisible == Dali::Window::VISIBLE )
+ {
+ // show indicator
+ ShowIndicator( KEEP_SHOWING );
+ }
+ else
+ {
+ // hide indicator
+ ShowIndicator( HIDE_NOW );
+ }
+ }
+ else
+ {
+ mIsShowing = false;
+ }
+ }
+}
+
+bool IndicatorEcoreWl::IsConnected()
+{
+ return ( mState == CONNECTED );
+}
+
+bool IndicatorEcoreWl::SendMessage( int messageDomain, int messageId, const void *data, int size )
+{
+ if(IsConnected())
+ {
+ return mServerConnection->SendEvent( OP_MSG, messageDomain, messageId, data, size );
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool IndicatorEcoreWl::OnTouch(Dali::Actor indicator, const Dali::TouchData& touchData)
+{
+ if( mServerConnection )
+ {
+ // Send touch event to indicator server when indicator is showing
+ if( CheckVisibleState() || mIsShowing )
+ {
+ switch( touchData.GetState(0) )
+ {
+ case Dali::PointState::DOWN:
+ {
+ IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
+ IpcDataEvMouseDown ipcDown( touchData.GetTime() );
+ mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
+ mServerConnection->SendEvent( OP_EV_MOUSE_DOWN, &ipcDown, sizeof(ipcDown) );
+
+ if( mVisible == Dali::Window::AUTO )
+ {
+ // Stop hiding indicator
+ ShowIndicator( KEEP_SHOWING );
+ }
+ }
+ break;
+
+ case Dali::PointState::MOTION:
+ {
+ IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
+ mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
+ }
+ break;
+
+ case Dali::PointState::UP:
+ case Dali::PointState::INTERRUPTED:
+ {
+ IpcDataEvMouseUp ipcUp( touchData.GetTime() );
+ mServerConnection->SendEvent( OP_EV_MOUSE_UP, &ipcUp, sizeof(ipcUp) );
+
+ if( mVisible == Dali::Window::AUTO )
+ {
+ // Hide indicator
+ ShowIndicator( 0.5f /* hide after 0.5 sec */ );
+ }
+ }
+ break;
+
+ case Dali::TouchPoint::Leave:
+ {
+ IpcDataEvMouseMove ipcMove( touchData.GetLocalPosition(0), touchData.GetTime() );
+ mServerConnection->SendEvent( OP_EV_MOUSE_MOVE, &ipcMove, sizeof(ipcMove) );
+ IpcDataEvMouseUp ipcOut( touchData.GetTime() );
+ mServerConnection->SendEvent( OP_EV_MOUSE_OUT, &ipcOut, sizeof(ipcOut) );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool IndicatorEcoreWl::Connect()
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ DALI_ASSERT_DEBUG( mState == DISCONNECTED );
+
+ bool connected = false;
+
+ mServerConnection = new ServerConnection( INDICATOR_SERVICE_NAME, 0, false, this );
+ if( mServerConnection )
+ {
+ connected = mServerConnection->IsConnected();
+ if( ! connected )
+ {
+ delete mServerConnection;
+ mServerConnection = NULL;
+ }
+ }
+
+ if( !connected )
+ {
+ StartReconnectionTimer();
+ }
+ else
+ {
+ mState = CONNECTED;
+ }
+
+ return connected;
+}
+
+void IndicatorEcoreWl::StartReconnectionTimer()
+{
+ if( ! mReconnectTimer )
+ {
+ mReconnectTimer = Dali::Timer::New(1000);
+ mConnection.DisconnectAll();
+ mReconnectTimer.TickSignal().Connect( mConnection, &IndicatorEcoreWl::OnReconnectTimer );
+ }
+ mReconnectTimer.Start();
+}
+
+bool IndicatorEcoreWl::OnReconnectTimer()
+{
+ bool retry = false;
+
+ if( mState == DISCONNECTED )
+ {
+ if( !Connect() )
+ {
+ retry = true;
+ }
+ }
+
+ return retry;
+}
+
+void IndicatorEcoreWl::Disconnect()
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ mState = DISCONNECTED;
+
+ delete mServerConnection;
+ mServerConnection = NULL;
+
+ ClearSharedFileInfo();
+}
+
+void IndicatorEcoreWl::Resize( int width, int height )
+{
+ if( width < 1 )
+ {
+ width = 1;
+ }
+ if( height < 1 )
+ {
+ height = 1;
+ }
+
+ if( mImageWidth != width || mImageHeight != height )
+ {
+ mImageWidth = width;
+ mImageHeight = height;
+
+ mIndicatorContentActor.SetSize( mImageWidth, mImageHeight );
+ mIndicatorActor.SetSize( mImageWidth, mImageHeight );
+ mEventActor.SetSize(mImageWidth, mImageHeight);
+ UpdateTopMargin();
+ }
+}
+
+void IndicatorEcoreWl::SetLockFileInfo( Ecore_Ipc_Event_Server_Data *epcEvent )
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ // epcEvent->ref == w
+ // epcEvent->ref_to == h
+ // epcEvent->response == buffer num
+ // epcEvent->data = lockfile + nul byte
+
+ if( (epcEvent->ref > 0) && (epcEvent->ref_to > 0) && (epcEvent->data) &&
+ (((unsigned char *)epcEvent->data)[epcEvent->size - 1] == 0) )
+ {
+ int n = epcEvent->response;
+
+ if( n >= 0 && n < SHARED_FILE_NUMBER )
+ {
+ mCurrentSharedFile = n;
+
+ mSharedFileInfo[n].mImageWidth = epcEvent->ref;
+ mSharedFileInfo[n].mImageHeight = epcEvent->ref_to;
+
+ mSharedFileInfo[n].mLockFileName.clear();
+
+ mSharedFileInfo[n].mLockFileName = static_cast< char* >( epcEvent->data );
+
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "SetLockFileInfo: buffer num = %d, w = %d, h = %d, lock = %s\n",
+ n, mSharedFileInfo[n].mImageWidth, mSharedFileInfo[n].mImageHeight, mSharedFileInfo[n].mLockFileName.c_str() );
+ }
+ }
+}
+
+void IndicatorEcoreWl::SetSharedImageInfo( Ecore_Ipc_Event_Server_Data *epcEvent )
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ // epcEvent->ref == shm id
+ // epcEvent->ref_to == shm num
+ // epcEvent->response == buffer num
+ // epcEvent->data = shm ref string + nul byte
+
+ if ( (epcEvent->data) &&
+ (epcEvent->size > 0) &&
+ (((unsigned char *)epcEvent->data)[epcEvent->size - 1] == 0) )
+ {
+ int n = epcEvent->response;
+
+ if( n >= 0 && n < SHARED_FILE_NUMBER )
+ {
+ mCurrentSharedFile = n;
+
+ mSharedFileInfo[n].mSharedFileName.clear();
+
+ mSharedFileInfo[n].mSharedFileName = static_cast< char* >( epcEvent->data );
+
+ mSharedFileInfo[n].mSharedFileID = epcEvent->ref;
+ mSharedFileInfo[n].mSharedFileNumber = epcEvent->ref_to;
+
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "SetSharedImageInfo: buffer num %d, shared file = %s, id = %d, num = %d\n",
+ n, mSharedFileInfo[n].mSharedFileName.c_str(), mSharedFileInfo[n].mSharedFileID, mSharedFileInfo[n].mSharedFileNumber );
+ }
+ }
+}
+
+void IndicatorEcoreWl::LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent )
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ // epcEvent->ref == alpha
+ // epcEvent->ref_to == sys
+ // epcEvent->response == buffer num
+
+ int n = epcEvent->response;
+
+ if( n >= 0 && n < SHARED_FILE_NUMBER )
+ {
+ mCurrentSharedFile = n;
+
+ delete mSharedFileInfo[n].mSharedFile;
+ mSharedFileInfo[n].mSharedFile = NULL;
+
+ delete mSharedFileInfo[n].mLock;
+ mSharedFileInfo[n].mLock = NULL;
+
+ std::stringstream sharedFileID;
+ std::stringstream sharedFileNumber;
+
+ sharedFileID << mSharedFileInfo[n].mSharedFileID;
+ sharedFileNumber << mSharedFileInfo[n].mSharedFileNumber;
+
+ std::string sharedFilename = "/" + mSharedFileInfo[n].mSharedFileName + "-" + sharedFileID.str() + "." + sharedFileNumber.str();
+
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "LoadSharedImage: file name = %s\n", sharedFilename.c_str() );
+
+ mSharedFileInfo[n].mSharedFile = SharedFile::New( sharedFilename.c_str(), mSharedFileInfo[n].mImageWidth * mSharedFileInfo[n].mImageWidth * 4, true );
+ if( mSharedFileInfo[n].mSharedFile != NULL )
+ {
+ mSharedFileInfo[n].mLock = new IndicatorEcoreWl::LockFile( mSharedFileInfo[n].mLockFileName );
+ if( mSharedFileInfo[n].mLock->RetrieveAndClearErrorStatus() )
+ {
+ DALI_LOG_ERROR( "### Indicator error: Cannot open lock file %s ###\n", mSharedFileInfo[n].mLockFileName.c_str() );
+ }
+ else
+ {
+ CreateNewImage( n );
+ UpdateVisibility();
+ }
+ }
+ }
+}
+
+void IndicatorEcoreWl::UpdateTopMargin()
+{
+ int newMargin = (mVisible == Dali::Window::VISIBLE && mOpacityMode == Dali::Window::OPAQUE) ? mImageHeight : 0;
+ if (mTopMargin != newMargin)
+ {
+ mTopMargin = newMargin;
+ mAdaptor->IndicatorSizeChanged( mTopMargin );
+ }
+}
+
+void IndicatorEcoreWl::UpdateVisibility()
+{
+ if( CheckVisibleState() )
+ {
+ // set default indicator type (enable the quick panel)
+ OnIndicatorTypeChanged( INDICATOR_TYPE_1 );
+ }
+ else
+ {
+ // set default indicator type (disable the quick panel)
+ OnIndicatorTypeChanged( INDICATOR_TYPE_2 );
+ }
+
+ if( !mIsShowing )
+ {
+ mIndicatorContentActor.SetPosition( 0.0f, -mImageHeight, 0.0f );
+ }
+
+ SetVisible(mVisible, true);
+}
+
+void IndicatorEcoreWl::UpdateImageData( int bufferNumber )
+{
+ DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "State: %s mVisible: %s", STATE_DEBUG_STRING(mState), mVisible?"T":"F" );
+
+ if( mState == CONNECTED && mVisible )
+ {
+ // not sure we can skip it when mIsShowing is false
+ CopyToBuffer( bufferNumber );
+ }
+}
+
+bool IndicatorEcoreWl::CopyToBuffer( int bufferNumber )
+{
+ bool success = false;
+
+ if( mSharedFileInfo[bufferNumber].mLock )
+ {
+ IndicatorEcoreWl::ScopedLock scopedLock(mSharedFileInfo[bufferNumber].mLock);
+ if( mSharedFileInfo[bufferNumber].mLock->RetrieveAndClearErrorStatus() )
+ {
+ // Do nothing here.
+ }
+ else if( scopedLock.IsLocked() )
+ {
+ unsigned char *src = mSharedFileInfo[bufferNumber].mSharedFile->GetAddress();
+ size_t size = static_cast< size_t >( mSharedFileInfo[bufferNumber].mImageWidth ) * mSharedFileInfo[bufferNumber].mImageHeight * 4;
+
+ if( mIndicatorBuffer->UpdatePixels( src, size ) )
+ {
+ mAdaptor->RequestUpdateOnce();
+ success = true;
+ }
+ }
+ }
+
+ return success;
+}
+
+void IndicatorEcoreWl::CreateNewImage( int bufferNumber )
+{
+ DALI_LOG_TRACE_METHOD_FMT( gIndicatorLogFilter, "W:%d H:%d", mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight );
+ mIndicatorBuffer = new IndicatorBuffer( mAdaptor, mSharedFileInfo[bufferNumber].mImageWidth, mSharedFileInfo[bufferNumber].mImageHeight, Pixel::BGRA8888 );
+ bool success = false;
+
+ if( CopyToBuffer( bufferNumber ) ) // Only create images if we have valid image buffer
+ {
+ Dali::Texture texture = Dali::Texture::New( mIndicatorBuffer->GetNativeImage() );
+ if( texture )
+ {
+ SetForegroundImage( texture );
+ success = true;
+ }
+ }
+
+ if( !success )
+ {
+ DALI_LOG_WARNING("### Cannot create indicator image ###\n");
+ }
+}
+
+Dali::Geometry IndicatorEcoreWl::CreateBackgroundGeometry()
+{
+ switch( mOpacityMode )
+ {
+ case Dali::Window::TRANSLUCENT:
+ if( !mTranslucentGeometry )
+ {
+ // Construct 5 interval mesh
+ // 0 +---+ 1
+ // | \ |
+ // 2 +---+ 3
+ // | \ |
+ // 4 +---+ 5
+ // | \ |
+ // 6 +---+ 7
+ // | \ |
+ // 8 +---+ 9
+ // | \ |
+ // 10 +---+ 11
+
+ // Create vertices
+ struct BackgroundVertex
+ {
+ Vector2 mPosition;
+ float mAlpha;
+ };
+
+ unsigned int numVertices = 2 * ( NUM_GRADIENT_INTERVALS + 1 );
+ BackgroundVertex vertices[ numVertices ];
+
+ float d = -0.5f;
+ float delta = 1.0f / NUM_GRADIENT_INTERVALS;
+ BackgroundVertex* currentVertex = vertices;
+ for( int y = 0; y < NUM_GRADIENT_INTERVALS + 1; ++y, d += delta )
+ {
+ currentVertex->mPosition = Vector2( -0.5f, d );
+ currentVertex->mAlpha = GRADIENT_ALPHA[ y ];
+ currentVertex++;
+
+ currentVertex->mPosition = Vector2( 0.5f, d );
+ currentVertex->mAlpha = GRADIENT_ALPHA[ y ];
+ currentVertex++;
+ }
+
+ // Create indices
+ unsigned int numIndices = 2 * 3 * NUM_GRADIENT_INTERVALS;
+ unsigned short indices[ numIndices ];
+
+ unsigned short* currentIndex = indices;
+ for( int y = 0; y < NUM_GRADIENT_INTERVALS; ++y )
+ {
+ *currentIndex++ = (2 * y);
+ *currentIndex++ = (2 * y) + 3;
+ *currentIndex++ = (2 * y) + 1;
+
+ *currentIndex++ = (2 * y);
+ *currentIndex++ = (2 * y) + 2;
+ *currentIndex++ = (2 * y) + 3;
+ }
+
+ Dali::Property::Map vertexFormat;
+ vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2;
+ vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT;
+ Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat );
+ vertexPropertyBuffer.SetData( vertices, numVertices );
+
+ // Create the geometry object
+ mTranslucentGeometry = Dali::Geometry::New();
+ mTranslucentGeometry.AddVertexBuffer( vertexPropertyBuffer );
+ mTranslucentGeometry.SetIndexBuffer( &indices[0], numIndices );
+ }
+
+ return mTranslucentGeometry;
+ case Dali::Window::OPAQUE:
+
+ if( !mSolidGeometry )
+ {
+ // Create vertices
+ struct BackgroundVertex
+ {
+ Vector2 mPosition;
+ float mAlpha;
+ };
+
+ BackgroundVertex vertices[ 4 ] = { { Vector2( -0.5f, -0.5f ), 1.0f }, { Vector2( 0.5f, -0.5f ), 1.0f },
+ { Vector2( -0.5f, 0.5f ), 1.0f }, { Vector2( 0.5f, 0.5f ), 1.0f } };
+
+ // Create indices
+ unsigned short indices[ 6 ] = { 0, 3, 1, 0, 2, 3 };
+
+ Dali::Property::Map vertexFormat;
+ vertexFormat[ "aPosition" ] = Dali::Property::VECTOR2;
+ vertexFormat[ "aAlpha" ] = Dali::Property::FLOAT;
+ Dali::PropertyBuffer vertexPropertyBuffer = Dali::PropertyBuffer::New( vertexFormat );
+ vertexPropertyBuffer.SetData( vertices, 4 );
+
+
+ // Create the geometry object
+ mSolidGeometry = Dali::Geometry::New();
+ mSolidGeometry.AddVertexBuffer( vertexPropertyBuffer );
+ mSolidGeometry.SetIndexBuffer( &indices[0], 6 );
+ }
+
+ return mSolidGeometry;
+ case Dali::Window::TRANSPARENT:
+ break;
+ }
+
+ return Dali::Geometry();
+}
+
+void IndicatorEcoreWl::SetForegroundImage( Dali::Texture texture )
+{
+ if( !mForegroundRenderer && texture )
+ {
+ // Create Shader
+ Dali::Shader shader = Dali::Shader::New( FOREGROUND_VERTEX_SHADER, FOREGROUND_FRAGMENT_SHADER );
+
+ // Create renderer from geometry and material
+ Dali::Geometry quad = CreateQuadGeometry();
+ mForegroundRenderer = Dali::Renderer::New( quad, shader );
+ // Make sure the foreground stays in front of the background
+ mForegroundRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, 1.f );
+
+ // Set blend function
+ mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB, Dali::BlendFactor::ONE );
+ mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB, Dali::BlendFactor::ONE_MINUS_SRC_ALPHA );
+ mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA, Dali::BlendFactor::ONE );
+ mForegroundRenderer.SetProperty( Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA, Dali::BlendFactor::ONE );
+
+ // Create a texture-set and add to renderer
+
+ Dali::TextureSet textureSet = Dali::TextureSet::New();
+ textureSet.SetTexture( 0u, texture );
+ mForegroundRenderer.SetTextures( textureSet );
+
+ mIndicatorContentActor.AddRenderer( mForegroundRenderer );
+ }
+ else if( mForegroundRenderer )
+ {
+ Dali::TextureSet textureSet = mForegroundRenderer.GetTextures();
+ textureSet.SetTexture( 0u, texture );
+ }
+
+ if( mImageWidth == 0 && mImageHeight == 0 && texture)
+ {
+ Resize( texture.GetWidth(), texture.GetHeight() );
+ }
+}
+
+void IndicatorEcoreWl::OnIndicatorTypeChanged( Type indicatorType )
+{
+ if( mObserver != NULL )
+ {
+ mObserver->IndicatorTypeChanged( indicatorType );
+ }
+}
+
+void IndicatorEcoreWl::DataReceived( void* event )
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+ Ecore_Ipc_Event_Server_Data *epcEvent = static_cast<Ecore_Ipc_Event_Server_Data *>( event );
+
+ switch( epcEvent->minor )
+ {
+ case OP_UPDATE:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE\n" );
+ if( mIsShowing )
+ {
+ mAdaptor->RequestUpdateOnce();
+ }
+ break;
+ }
+ case OP_UPDATE_DONE:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_UPDATE_DONE [%d]\n", epcEvent->response );
+ // epcEvent->response == display buffer #
+ UpdateImageData( epcEvent->response );
+ break;
+ }
+ case OP_SHM_REF0:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF0\n" );
+ SetSharedImageInfo( epcEvent );
+ break;
+ }
+ case OP_SHM_REF1:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF1\n" );
+ SetLockFileInfo( epcEvent );
+ break;
+ }
+ case OP_SHM_REF2:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_SHM_REF2\n" );
+ LoadSharedImage( epcEvent );
+ break;
+ }
+ case OP_RESIZE:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_RESIZE\n" );
+
+ if( (epcEvent->data) && (epcEvent->size >= (int)sizeof(IpcDataResize)) )
+ {
+ IpcDataResize *newSize = static_cast<IpcDataResize*>( epcEvent->data );
+ Resize( newSize->w, newSize->h );
+ }
+ break;
+ }
+ case OP_MSG_PARENT:
+ {
+ int msgDomain = epcEvent->ref;
+ int msgId = epcEvent->ref_to;
+
+ void *msgData = NULL;
+ int msgDataSize = 0;
+ msgData = epcEvent->data;
+ msgDataSize = epcEvent->size;
+
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_MSG_PARENT. msgDomain = %d\n", msgDomain );
+
+ if( msgDomain == MSG_DOMAIN_CONTROL_INDICATOR )
+ {
+ switch( msgId )
+ {
+ case MSG_ID_INDICATOR_TYPE:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: OP_MSG_PARENT, INDICATOR_TYPE\n" );
+ Type* indicatorType = static_cast<Type*>( epcEvent->data );
+ OnIndicatorTypeChanged( *indicatorType );
+ break;
+ }
+
+ case MSG_ID_INDICATOR_START_ANIMATION:
+ {
+ DALI_LOG_INFO( gIndicatorLogFilter, Debug::General, "Indicator client received: MSG_ID_INDICATOR_START_ANIMATION\n" );
+
+ if (msgDataSize != (int)sizeof(IpcIndicatorDataAnimation))
+ {
+ DALI_LOG_ERROR("Message data is incorrect\n");
+ break;
+ }
+
+ IpcIndicatorDataAnimation *animData = static_cast<IpcIndicatorDataAnimation*>(msgData);
+
+ if(!CheckVisibleState())
+ {
+ ShowIndicator( animData->duration /* n sec */ );
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+void IndicatorEcoreWl::ConnectionClosed()
+{
+ DALI_LOG_TRACE_METHOD( gIndicatorLogFilter );
+
+ // Will get this callback if the server connection failed to start up.
+ delete mServerConnection;
+ mServerConnection = NULL;
+ mState = DISCONNECTED;
+
+ // Attempt to re-connect
+ Connect();
+}
+
+bool IndicatorEcoreWl::CheckVisibleState()
+{
+ if( mOrientation == Dali::Window::LANDSCAPE
+ || mOrientation == Dali::Window::LANDSCAPE_INVERSE
+ || (mVisible == Dali::Window::INVISIBLE)
+ || (mVisible == Dali::Window::AUTO && !mIsShowing) )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void IndicatorEcoreWl::ClearSharedFileInfo()
+{
+ for( int i = 0; i < SHARED_FILE_NUMBER; i++ )
+ {
+ delete mSharedFileInfo[i].mLock;
+ mSharedFileInfo[i].mLock = NULL;
+
+ delete mSharedFileInfo[i].mSharedFile;
+ mSharedFileInfo[i].mSharedFile = NULL;
+
+ mSharedFileInfo[i].mLockFileName.clear();
+ mSharedFileInfo[i].mSharedFileName.clear();
+ }
+}
+
+/**
+ * duration can be this
+ *
+ * enum
+ * {
+ * KEEP_SHOWING = -1,
+ * HIDE_NOW = 0
+ * };
+ */
+void IndicatorEcoreWl::ShowIndicator(float duration)
+{
+ if( !mIndicatorAnimation )
+ {
+ mIndicatorAnimation = Dali::Animation::New(SLIDING_ANIMATION_DURATION);
+ mIndicatorAnimation.FinishedSignal().Connect(this, &IndicatorEcoreWl::OnAnimationFinished);
+ }
+
+ if(mIsShowing && !EqualsZero(duration))
+ {
+ // If need to show during showing, do nothing.
+ // In 2nd phase (below) will update timer
+ }
+ else if(!mIsShowing && mIsAnimationPlaying && EqualsZero(duration))
+ {
+ // If need to hide during hiding or hidden already, do nothing
+ }
+ else
+ {
+ mIndicatorAnimation.Clear();
+
+ if( EqualsZero(duration) )
+ {
+ mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, -mImageHeight, 0), Dali::AlphaFunction::EASE_OUT );
+
+ mIsShowing = false;
+
+ OnIndicatorTypeChanged( INDICATOR_TYPE_2 ); // un-toucable
+ }
+ else
+ {
+ mIndicatorAnimation.AnimateTo( Property( mIndicatorContentActor, Dali::Actor::Property::POSITION ), Vector3(0, 0, 0), Dali::AlphaFunction::EASE_OUT );
+
+ mIsShowing = true;
+
+ OnIndicatorTypeChanged( INDICATOR_TYPE_1 ); // touchable
+ }
+
+ mIndicatorAnimation.Play();
+ mIsAnimationPlaying = true;
+ }
+
+ if(duration > 0)
+ {
+ if(!mShowTimer)
+ {
+ mShowTimer = Dali::Timer::New(1000 * duration);
+ mShowTimer.TickSignal().Connect(this, &IndicatorEcoreWl::OnShowTimer);
+ }
+ mShowTimer.SetInterval(1000* duration);
+ mShowTimer.Start();
+
+ if( mVisible == Dali::Window::AUTO )
+ {
+ // check the stage touch
+ Dali::Stage::GetCurrent().TouchSignal().Connect( this, &IndicatorEcoreWl::OnStageTouch );
+ }
+ }
+ else
+ {
+ if(mShowTimer && mShowTimer.IsRunning())
+ {
+ mShowTimer.Stop();
+ }
+
+ if( mVisible == Dali::Window::AUTO )
+ {
+ // check the stage touch
+ Dali::Stage::GetCurrent().TouchSignal().Disconnect( this, &IndicatorEcoreWl::OnStageTouch );
+ }
+ }
+}
+
+bool IndicatorEcoreWl::OnShowTimer()
+{
+ // after time up, hide indicator
+ ShowIndicator( HIDE_NOW );
+
+ return false;
+}
+
+void IndicatorEcoreWl::OnAnimationFinished(Dali::Animation& animation)
+{
+ mIsAnimationPlaying = false;
+ // once animation is finished and indicator is hidden, take it off stage
+ if( mObserver != NULL )
+ {
+ mObserver->IndicatorVisibilityChanged( mIsShowing ); // is showing?
+ }
+}
+
+void IndicatorEcoreWl::OnPan( Dali::Actor actor, const Dali::PanGesture& gesture )
+{
+ // Nothing to do, but we still want to consume pan
+}
+
+void IndicatorEcoreWl::OnStageTouch(const Dali::TouchData& touchData)
+{
+ // when stage is touched while indicator is showing temporary, hide it
+ if( mIsShowing && ( CheckVisibleState() == false || mVisible == Dali::Window::AUTO ) )
+ {
+ switch( touchData.GetState(0) )
+ {
+ case Dali::PointState::DOWN:
+ {
+ // if touch point is inside the indicator, indicator is not hidden
+ if( mImageHeight < int( touchData.GetScreenPosition(0).y ) )
+ {
+ ShowIndicator( HIDE_NOW );
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+
+} // Adaptor
+
+} // Internal
+
+} // Dali
+
+#pragma GCC diagnostic pop
--- /dev/null
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_INDICATOR_IMPL_ECORE_WL_H
+#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_INDICATOR_IMPL_ECORE_WL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/events/pan-gesture.h>
+#include <dali/public-api/events/pan-gesture-detector.h>
+#include <dali/public-api/events/touch-data.h>
+#include <dali/public-api/rendering/renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/window-system/common/indicator-interface.h>
+#include <dali/internal/window-system/common/indicator-buffer.h>
+#include <dali/internal/window-system/common/ecore-server-connection.h>
+#include <dali/internal/system/common/shared-file.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/adaptor-framework/window.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+class Adaptor;
+
+/**
+ * The Indicator class connects to the indicator server, and gets and draws the indicator
+ * for the given orientation.
+ */
+class IndicatorEcoreWl : public ConnectionTracker, public ServerConnection::Observer, public IndicatorInterface
+{
+public:
+
+ enum State
+ {
+ DISCONNECTED,
+ CONNECTED
+ };
+
+protected:
+ /**
+ * Class to encapsulate lock file
+ */
+ class LockFile
+ {
+ public:
+ /**
+ * Constructor. open lock file
+ */
+ LockFile(const std::string filename);
+
+ /**
+ * Close lock file
+ */
+ ~LockFile();
+
+ /**
+ * Grab an exclusive lock on this file
+ * @return true if the lock succeeded, false if it failed
+ */
+ bool Lock();
+
+ /**
+ * Remove the lock
+ */
+ void Unlock();
+
+ /**
+ * Test if there is an error with the lock file, and clears
+ * the error flag;
+ * @return true if an error was thrown
+ */
+ bool RetrieveAndClearErrorStatus();
+
+ private:
+ std::string mFilename;
+ int mFileDescriptor;
+ bool mErrorThrown;
+ };
+
+ /**
+ * Class to ensure lock/unlock through object destruction
+ */
+ class ScopedLock
+ {
+ public:
+ /**
+ * Constructor - creates a lock on the lockfile
+ * @param[in] lockFile The lockfile to use
+ */
+ ScopedLock( LockFile* lockFile );
+
+ /**
+ * Destructor - removes the lock (if any) on the lockfile
+ */
+ ~ScopedLock();
+
+ /**
+ * Method to test if the locking succeeded
+ * @return TRUE if locked
+ */
+ bool IsLocked();
+
+ private:
+ LockFile* mLockFile; ///< The lock file to use
+ bool mLocked; ///< Whether the lock succeeded
+ };
+
+
+public: // Dali::Internal::Adaptor::IndicicatorInterface
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::IndicatorInterface
+ */
+ IndicatorEcoreWl( Adaptor* adaptor,
+ Dali::Window::WindowOrientation orientation,
+ IndicatorInterface::Observer* observer );
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::~IndicatorInterface
+ */
+ virtual ~IndicatorEcoreWl();
+
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::SetAdaptor
+ */
+ virtual void SetAdaptor(Adaptor* adaptor);
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::GetActor
+ */
+ virtual Dali::Actor GetActor();
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::Open
+ */
+ virtual void Open( Dali::Window::WindowOrientation orientation );
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::Close
+ */
+ virtual void Close();
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::SetOpacityMode
+ */
+ virtual void SetOpacityMode( Dali::Window::IndicatorBgOpacity mode );
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::SetVisible
+ */
+ virtual void SetVisible( Dali::Window::IndicatorVisibleMode visibleMode, bool forceUpdate = false );
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::IsConnected
+ */
+ virtual bool IsConnected();
+
+ /**
+ * @copydoc Dali::Internal::IndicatorInterface::SendMessage
+ */
+ virtual bool SendMessage( int messageDomain, int messageId, const void *data, int size );
+
+private:
+ /**
+ * Initialize the indicator actors
+ */
+ void Initialize();
+
+ /**
+ * Constructs the renderers used for the background
+ */
+ Dali::Geometry CreateBackgroundGeometry();
+
+ /**
+ * Set the texture to be rendered as indicator foreground
+ * @param[in] texture The foreground texture.
+ */
+ void SetForegroundImage( Dali::Texture texture );
+
+ /**
+ * Touch event callback.
+ * It should pass the valid touch event to indicator server
+ *
+ * @param[in] indicator The indicator actor that was touched
+ * @param[in] touchEvent The touch data
+ */
+ bool OnTouch(Dali::Actor indicator, const Dali::TouchData& touchData);
+
+ /**
+ * Pan gesture callback.
+ * It finds flick down gesture to show hidden indicator image
+ *
+ * @param[in] actor The actor for gesture
+ * @param[in] gesture The gesture event
+ */
+ void OnPan( Dali::Actor actor, const Dali::PanGesture& gesture );
+
+ /**
+ * Touch event callback on stage.
+ * If stage is touched, hide showing indicator image
+ *
+ * @param[in] touchEvent The touch data
+ */
+ void OnStageTouch(const Dali::TouchData& touchData);
+
+ /**
+ * Connect to the indicator service
+ */
+ bool Connect();
+
+ /**
+ * Start the reconnection timer. This will run every second until we reconnect to
+ * the indicator service.
+ */
+ void StartReconnectionTimer();
+
+ /**
+ * If connection failed, attempt to re-connect every second
+ */
+ bool OnReconnectTimer();
+
+ /**
+ * Disconnect from the indicator service
+ */
+ void Disconnect();
+
+ /**
+ * Handle Resize event
+ * @param[in] width The new width
+ * @param[in] height The new height
+ */
+ void Resize( int width, int height );
+
+ /**
+ * Set the lock file info.
+ * @param[in] epcEvent Current ecore event.
+ */
+ void SetLockFileInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
+
+ /**
+ * Set the shared indicator image info
+ * @param[in] epcEvent The event containing the image data
+ */
+ void SetSharedImageInfo( Ecore_Ipc_Event_Server_Data *epcEvent );
+
+ /**
+ * Load the shared indicator image
+ * @param[in] epcEvent The event containing the image data
+ */
+ void LoadSharedImage( Ecore_Ipc_Event_Server_Data *epcEvent );
+
+ /**
+ * Update top margin of the stage as much as indicator height
+ */
+ void UpdateTopMargin();
+
+ /**
+ * Update the visibility and position of the actors
+ */
+ void UpdateVisibility();
+
+ /**
+ * Inform dali that the indicator data has been updated.
+ * @param[in] bufferNumber The shared file number
+ */
+ void UpdateImageData( int bufferNumber );
+
+ /**
+ * Lock the temporary file, Copy the shared image into IndicatorBuffer
+ * and then unlock the temporary file.
+ * Caller should ensure we are not writing image to gl texture.
+ * @param[in] bufferNumber The shared file number
+ */
+ bool CopyToBuffer( int bufferNumber );
+
+ /**
+ * Create a new image for the indicator, and set up signal handling for it.
+ * @param[in] bufferNumber The shared file number
+ */
+ void CreateNewImage( int bufferNumber );
+
+ /**
+ * Indicator type has changed.
+ * Inform observer
+ * @param[in] type The new indicator type
+ */
+ void OnIndicatorTypeChanged( Type type );
+
+ /**
+ * Check whether the indicator could be visible or invisible
+ * @return true if indicator should be shown
+ */
+ bool CheckVisibleState();
+
+ /**
+ * Show/Hide indicator actor with effect
+ * @param[in] duration how long need to show the indicator,
+ * if it equal to 0, hide the indicator
+ * if it less than 0, show always
+ */
+ void ShowIndicator( float duration );
+
+ /**
+ * Showing timer callback
+ */
+ bool OnShowTimer();
+
+ /**
+ * Showing animation finished callback
+ * @param[in] animation
+ */
+ void OnAnimationFinished( Dali::Animation& animation );
+
+private: // Implementation of ServerConnection::Observer
+ /**
+ * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
+ */
+ virtual void DataReceived( void* event );
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::ServerConnection::Observer::DataReceived()
+ */
+ virtual void ConnectionClosed();
+
+private:
+
+ /**
+ * Clear shared file info
+ */
+ void ClearSharedFileInfo();
+
+private:
+
+ struct SharedFileInfo
+ {
+ SharedFileInfo()
+ : mLock( NULL ),
+ mSharedFile( NULL ),
+ mImageWidth( 0 ),
+ mImageHeight( 0 ),
+ mLockFileName(),
+ mSharedFileName(),
+ mSharedFileID( 0 ),
+ mSharedFileNumber( 0 )
+ {
+ }
+
+ LockFile* mLock; ///< File lock for the shared file
+ SharedFile* mSharedFile; ///< Shared file
+
+ int mImageWidth; ///< Shared image width
+ int mImageHeight; ///< Shared image height
+
+ std::string mLockFileName; ///< Lock file name
+ std::string mSharedFileName; ///< Shared file name
+ int mSharedFileID; ///< Shared file ID
+ int mSharedFileNumber; ///< Shared file number
+ };
+
+ static const int SHARED_FILE_NUMBER = 2; ///< Shared file number
+
+ Dali::Geometry mTranslucentGeometry; ///< Geometry used for rendering the translucent background
+ Dali::Geometry mSolidGeometry; ///< Geometry used for rendering the opaque background
+ Dali::Shader mBackgroundShader; ///< Shader used for rendering the background
+
+ IndicatorBufferPtr mIndicatorBuffer; ///< class which handles indicator rendering
+ Dali::Renderer mForegroundRenderer; ///< Renderer renders the indicator foreground
+ Dali::Renderer mBackgroundRenderer; ///< Renderer renders the indicator background
+
+ Dali::Actor mIndicatorContentActor; ///< Actor container for image and background
+ Dali::Actor mIndicatorActor; ///< Handle to topmost indicator actor
+ Dali::Actor mEventActor; ///< Handle to event
+ Dali::PanGestureDetector mPanDetector; ///< Pan detector to find flick gesture for hidden indicator
+
+ Dali::Timer mReconnectTimer; ///< Reconnection timer
+ SlotDelegate< IndicatorEcoreWl > mConnection;
+
+ Dali::Window::IndicatorBgOpacity mOpacityMode; ///< Opacity enum for background
+ IndicatorEcoreWl::State mState; ///< The connection state
+
+ Adaptor* mAdaptor;
+ ServerConnection* mServerConnection;
+ IndicatorInterface::Observer* mObserver; ///< Upload observer
+
+ Dali::Window::WindowOrientation mOrientation;
+ int mImageWidth;
+ int mImageHeight;
+ Dali::Window::IndicatorVisibleMode mVisible; ///< Whether the indicator is visible
+
+ Dali::Timer mShowTimer; ///< Timer to show indicator
+ bool mIsShowing; ///< Whether the indicator is showing on the screen
+ Dali::Animation mIndicatorAnimation; ///< Animation to show/hide indicator image
+
+ bool mIsAnimationPlaying; ///< Whether the animation is playing
+
+ int mCurrentSharedFile; ///< Current shared file number
+ SharedFileInfo mSharedFileInfo[SHARED_FILE_NUMBER]; ///< Table to store shared file info
+
+ struct Impl; ///< Contains Ecore specific information
+ Impl* mImpl; ///< Created on construction and destroyed on destruction.
+
+ bool mBackgroundVisible; ///< Indicate whether background is visible
+ int mTopMargin; ///< Top margin of the stage for indicator
+};
+
+} // Adaptor
+} // Internal
+} // Dali
+
+#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_INDICATOR_IMPL_ECORE_WL_H
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/window-system/tizen-wayland/window-base-factory-ecore-wl.h>
-
-// INTERNAL HEADERS
-#include <dali/internal/window-system/tizen-wayland/window-base-ecore-wl.h>
-#include <dali/internal/window-system/common/display-utils.h>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-
-std::unique_ptr< Dali::Internal::Adaptor::WindowBase > WindowBaseFactoryEcoreWl::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface )
-{
- return Utils::MakeUnique< WindowBaseEcoreWl >( window, windowRenderSurface );
-}
-
-// this should be created from somewhere
-std::unique_ptr< WindowBaseFactory > GetWindowBaseFactory()
-{
- // returns WindowBase factory
- return Utils::MakeUnique< WindowBaseFactoryEcoreWl >();
-}
-
-} // namespace Adaptor
-} // namespace Internal
-} // namespace Dali
+++ /dev/null
-#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_FACTORY_ECORE_WL_H
-#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_FACTORY_ECORE_WL_H
-
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <dali/internal/window-system/common/window-base-factory.h>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-
-class WindowBaseFactoryEcoreWl : public WindowBaseFactory
-{
-public:
- std::unique_ptr< Dali::Internal::Adaptor::WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override;
-};
-
-} // namespace Adaptor
-} // namespace Internal
-} // namespace Dali
-
-#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_FACTORY_ECORE_WL_H
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.h>
+
+// INTERNAL HEADERS
+#include <dali/internal/window-system/tizen-wayland/window-base-ecore-wl.h>
+#include <dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h>
+#include <dali/internal/window-system/common/display-utils.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+std::unique_ptr< WindowBase > WindowFactoryEcoreWl::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface )
+{
+ return Utils::MakeUnique< WindowBaseEcoreWl >( window, windowRenderSurface );
+}
+
+std::unique_ptr< IndicatorInterface > WindowFactoryEcoreWl::CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer )
+{
+ return Utils::MakeUnique< IndicatorEcoreWl >( adaptor, orientation, observer );
+}
+
+// this should be created from Window impl
+std::unique_ptr< WindowFactory > GetWindowFactory()
+{
+ // returns Window factory
+ return Utils::MakeUnique< WindowFactoryEcoreWl >();
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL_H
+#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/internal/window-system/common/window-factory.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+class WindowFactoryEcoreWl : public WindowFactory
+{
+public:
+ std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override;
+
+ std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) override;
+};
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
+
+#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL_H
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/window-system/ubuntu-x11/window-base-factory-ecore-x.h>
-
-// INTERNAL HEADERS
-#include <dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h>
-#include <dali/internal/window-system/common/display-utils.h>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-
-std::unique_ptr< Dali::Internal::Adaptor::WindowBase > WindowBaseFactoryEcoreX::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface )
-{
- return Utils::MakeUnique< WindowBaseEcoreX >( window, windowRenderSurface );
-}
-
-// this should be created from somewhere
-std::unique_ptr< WindowBaseFactory > GetWindowBaseFactory()
-{
- // returns WindowBase factory
- return Utils::MakeUnique< WindowBaseFactoryEcoreX >();
-}
-
-} // namespace Adaptor
-} // namespace Internal
-} // namespace Dali
+++ /dev/null
-#ifndef DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H
-#define DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H
-
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <dali/internal/window-system/common/window-base-factory.h>
-
-namespace Dali
-{
-namespace Internal
-{
-namespace Adaptor
-{
-
-class WindowBaseFactoryEcoreX : public WindowBaseFactory
-{
-public:
- std::unique_ptr< Dali::Internal::Adaptor::WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override;
-};
-
-} // namespace Adaptor
-} // namespace Internal
-} // namespace Dali
-
-#endif // DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.h>
+
+// INTERNAL HEADERS
+#include <dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h>
+#include <dali/internal/window-system/common/display-utils.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+std::unique_ptr< WindowBase > WindowFactoryEcoreX::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface )
+{
+ return Utils::MakeUnique< WindowBaseEcoreX >( window, windowRenderSurface );
+}
+
+std::unique_ptr< IndicatorInterface > WindowFactoryEcoreX::CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer )
+{
+ return std::unique_ptr< IndicatorInterface >( nullptr );
+}
+
+// this should be created from Window impl
+std::unique_ptr< WindowFactory > GetWindowFactory()
+{
+ // returns Window factory
+ return Utils::MakeUnique< WindowFactoryEcoreX >();
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H
+#define DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/internal/window-system/common/window-factory.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+class WindowFactoryEcoreX : public WindowFactory
+{
+public:
+ std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override;
+
+ std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) override;
+};
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
+
+#endif // DALI_INTERNAL_WINDOWSYSTEM_ECOREX_WINDOW_FACTORY_ECORE_X_H