[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-player-dev
Subject:    [Player-dev] CR/CN-Client: Fixing GetSeekRange() issues With
From:       Daniel Yek <dyek () real ! com>
Date:       2007-12-27 8:55:58
Message-ID: 4773689E.3000702 () real ! com
[Download RAW message or body]

This is a MIME-formatted message.  If you see this text it means that your
E-mail software does not support MIME-formatted messages.


Modified by: dyek@real.com
Date: 12/26/2007
Project: RealPlayer

Synopsis: 
Created ClientPlayerGetSuperbufferTimelineInfo() to provide 
all interesting timeline positions, including 
max-seekable-without-rebuffering.

Overview: 
This change implemented ClientPlayerGetSuperbufferTimelineInfo()
to provide: 
1. easy-to-use timeline ranges and  
2. maximum-seekable timeline position without causing client core to 
rebuffer.  

This is different from the output of hxrecordengine's GetSeekRange() 
(not hxclientkit's) which provides buffered range up to the last packet 
in the buffer; seeking to this maximum position causes the client core 
to rebuffer.

This fixed a few issues with Superbuffer timeline position values.

It also fixed the problem where seeking to the buffer end in 
a live stream caused RealPlayer for Linux to rebuffer.
With this, seeking to the end of Superbuffer will playback immediately.

With this checking, the preroll is hardcoded as 4000 as 
IHXPlayer2->GetMinimumPreroll() didn't seem to be the right function 
to call.

I'm still having problems with seeking outside the buffered region of 
an OnDemand clip causes a long pause before the client continues.

This appears to be related to hxrecordengine as disabling Superbuffer
appears to fix the problem.

Logging traces showed that clicking on a future timeline position causes
hxrecordengine to issue seek to the target timeline value on client core; 
however, when new packets arrived from core to hxrecordengine, 
the packet timestamp is much too early and thus a very long buffering
time before the timestamp catches up.

I'm wondering if timestamp fix-up is needed? 

Is hxrecordengine requesting the seek to the right timeline position 
without needing to offset/change it?



Files Modified:
player/hxclientkit/src/CHXClientPlayer.h  - Added GetSuperbufferTimelineInfo()
player/hxclientkit/src/CHXClientPlayer.cpp - Added GetSuperbufferTimelineInfo()
player/hxclientkit/src/IHXClientPlayer.h

player/hxclientkit/src/HXClientCFuncs.cpp
player/hxclientkit/pub/HXClientCFuncs.h   

player/app/gtk/hxstatuspositionslider.cpp
player/app/gtk/superbufhscale.c


Image Size and Heap Use impact (Client -Only):
None.

Platforms and Profiles Affected:
Linux

Distribution Libraries Affected:
None.

Distribution library impact and planned action:
None.

Platforms and Profiles Build Verified:
Profile: helix_client_all_define
Platform: Fedora Core 6

Platforms and Profiles Functionality verified:
Profile: helix_client_all_define
Platform: Fedora Core 6

Branch: 
hxclientkit: 150Cay
player: HEAD

Copyright assignment: I am a RealNetworks employee.




-- 
Daniel Yek.


["timelineInfo[1].diff" (text/plain)]

Index: player/hxclientkit/src/HXClientCFuncs.cpp
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/HXClientCFuncs.cpp,v
retrieving revision 1.19.6.5
diff -u -w -r1.19.6.5 HXClientCFuncs.cpp
--- player/hxclientkit/src/HXClientCFuncs.cpp	25 Jun 2007 23:58:40 -0000	1.19.6.5
+++ player/hxclientkit/src/HXClientCFuncs.cpp	26 Dec 2007 09:49:33 -0000
@@ -898,40 +898,22 @@
     return pIClientPlayer ? pIClientPlayer->GetSuperBufferSize() : 0;
 }
 
-bool ClientPlayerGetSuperBufferRange( HXClientPlayerToken clientPlayerToken, 
-                                      UInt32* pMinPosition, 
-                                      UInt32* pWritePosition, 
-                                      UInt32* pMaxPosition)
+bool ClientPlayerGetSuperbufferTimelineInfo(
+        HXClientPlayerToken clientPlayerToken, 
+        UInt32 *pMinTime,        // Min. timeline value.
+        UInt32 *pMinBuffered,    // Min. seekable without rebuffering.
+        UInt32 *pMaxSeekable,    // Seekable without rebuffering (preroll buffered)
+        UInt32 *pMaxBuffered,    // Max. buffered/current Superbuffer write \
position. +        UInt32 *pMaxTime )       // Max. timeline value.
 {
-    HX_RESULT result;
+    bool result;
     IHXClientPlayer* pIClientPlayer = ( IHXClientPlayer* ) clientPlayerToken;
-    result = pIClientPlayer? pIClientPlayer->GetBufferedRange(pMinPosition, \
                pWritePosition, pMaxPosition) : false;
-    UINT32 len = ClientPlayerGetLength(clientPlayerToken);
-
-    // TODO: Why GetBufferedRange() returns 0 for pMinPosition and pMaxPosition?
-    // Move this code into CHXClientPlayer->GetBufferedRange()? Does it affect Mac?
-    if (ClientPlayerIsSuperBufferEnabled(clientPlayerToken))
-    {
-        if (ClientPlayerIsLive(clientPlayerToken) || INFINITE_DURATION == \
                ClientPlayerGetLength(clientPlayerToken))
-        {
-            // Live 
-            UINT32 preferredSuperbufferSize = \
                ClientPlayerGetPreferredSuperBufferSize(clientPlayerToken);
-            *pMinPosition = 0;
-            *pMaxPosition = preferredSuperbufferSize;
-            if (*pWritePosition > *pMaxPosition)
-            {
-                *pMaxPosition = *pWritePosition;
-                *pMinPosition = *pMaxPosition - preferredSuperbufferSize;
-            }
-        }
-        else
-        {
-            // OnDemand
-            *pMinPosition = 0;
-            *pMaxPosition = len;
-        }
-    }
-
+    result = pIClientPlayer? pIClientPlayer->GetSuperbufferTimelineInfo(pMinTime, 
+                                                                        \
pMinBuffered,  +                                                                      \
pMaxSeekable, +                                                                       \
pMaxBuffered,  +                                                                      \
pMaxTime) : false;  return result;
 }
 
+



Index: player/hxclientkit/src/CHXClientPlayer.h
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/CHXClientPlayer.h,v
retrieving revision 1.19.6.6
diff -u -w -r1.19.6.6 CHXClientPlayer.h
--- player/hxclientkit/src/CHXClientPlayer.h	2 May 2007 09:18:19 -0000	1.19.6.6
+++ player/hxclientkit/src/CHXClientPlayer.h	26 Dec 2007 09:49:33 -0000
@@ -206,6 +206,7 @@
     virtual bool SetPreferredSuperBufferSize( UINT32 millisecs );
     virtual UINT32 GetPreferredSuperBufferSize( void ) const;
     virtual UINT32 GetSuperBufferSize( void ) const;
+    virtual bool GetSuperbufferTimelineInfo(UINT32 *pMinTime, UINT32 *pMinBuffered, \
UINT32 *pMaxSeekable, UINT32 *pMaxBuffered, UINT32 *pMaxTime ) const;  };
 
 #endif



Index: player/hxclientkit/src/CHXClientPlayer.cpp
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/CHXClientPlayer.cpp,v
retrieving revision 1.35.2.13
diff -u -w -r1.35.2.13 CHXClientPlayer.cpp
--- player/hxclientkit/src/CHXClientPlayer.cpp	10 Dec 2007 23:03:07 -0000	1.35.2.13
+++ player/hxclientkit/src/CHXClientPlayer.cpp	26 Dec 2007 09:49:33 -0000
@@ -745,6 +745,10 @@
     {
         hasBuffered = m_pClipSink->GetBufferedRange( pMinPosition, pWritePosition, \
pMaxPosition );  }
+
+    HXLOGL3(HXLOG_CNKT, "CHXClientPlayer::GetBufferedRange() MinPosition=%d \
WritePosition=%d MaxPosition=%d", +        *pMinPosition, *pWritePosition, \
*pMaxPosition); +
     return hasBuffered;
 }
 
@@ -761,7 +765,7 @@
         {
             result = SUCCEEDED( m_pIHXClientRecordService->GetSeekRange( \
*pMinPosition, *pMaxPosition ) );  
-            HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] GetSeekRange() min[0x%08x] \
max[0x%08x] IsLive=1 " +            HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] \
GetSeekRange() min[%d] max[%d] IsLive=1 "  "SuperbufferEnabled=1 result=%s\n", 
                                 this, 
                                 *pMinPosition, 
@@ -772,7 +776,7 @@
         {
             result = false;
 
-            HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] GetSeekRange() min[0x%08x] \
max[0x%08x] IsLive=1 " +            HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] \
GetSeekRange() min[%d] max[%d] IsLive=1 "  "SuperbufferEnabled=0 result=false\n", 
                                 this, 
                                 *pMinPosition, 
@@ -784,7 +788,7 @@
         *pMaxPosition = GetLength();
         result = *pMaxPosition > *pMinPosition;
 
-        HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] GetSeekRange() min[0x%08x] \
max[0x%08x] IsLive=0 " +        HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] \
GetSeekRange() min[%d] max[%d] IsLive=0 "  "SuperbufferEnabled=unknown result=%s\n", 
                             this, 
                             *pMinPosition, 
@@ -795,6 +799,108 @@
     return result;
 }
 
+// Provide timeline values convenient for use in Timeline slider.
+// Return true if seekable buffer exists.
+bool
+CHXClientPlayer::GetSuperbufferTimelineInfo(UINT32 *pMinTime,        // Min. \
timeline value. +                                            UINT32 *pMinBuffered,    \
// Min. seekable without rebuffering. +                                            \
UINT32 *pMaxSeekable,    // Seekable without rebuffering (preroll buffered) +         \
UINT32 *pMaxBuffered,    // Max. buffered/current Superbuffer write position. +       \
UINT32 *pMaxTime ) const // Max. timeline value. +{
+    HX_RESULT result = 0;
+    bool bHasSeekBuffer = false;
+    bool bSuperbufferEnabled;
+    bool bIsLive;
+    UINT32 uMinTime, uMinBuffered, uMaxSeekable, uMaxBuffered, uMaxTime;
+
+    if (!IsSuperBufferEnabled())
+    {
+        return false;   // If superbuffer not enabled, use GetLength() instead!
+    }
+
+    uMinTime = uMinBuffered = uMaxSeekable = uMaxBuffered = uMaxTime = 0;
+
+    bSuperbufferEnabled = m_pIHXClientRecordService && \
m_pIHXClientRecordService->IsSuperBufferEnabled(); +    bIsLive = IsLive();
+
+    if (bSuperbufferEnabled)
+    {
+        // Superbuffer (hxrecordengine) module's GetSeekRange() function actually \
outputs  +        // the buffered range -- that is, (packet-)seekable without \
rebuffering.  +        bHasSeekBuffer = SUCCEEDED( \
m_pIHXClientRecordService->GetSeekRange(uMinBuffered, uMaxBuffered) ); +
+        if (bHasSeekBuffer && bIsLive)
+        {
+            // Live stream
+            UINT32 uSuperbufferSize = \
m_pIHXClientRecordService->GetSuperBufferSize(); +            uMinTime = \
uMinBuffered; +            uMaxTime = uMinTime + uSuperbufferSize;
+
+            // Do we want to use PreferredSuperBufferSize() at all?
+            // UINT32 proposedMaxPosition = \
m_pIHXClientRecordService->GetPreferredSuperBufferSize(); +
+            // HACK: uMaxBuffered could grow much larger than uMaxTime calculated.
+            uMaxTime = MAX(uMaxTime, uMaxBuffered);
+            uMinTime = uMaxTime - uSuperbufferSize;
+            uMinBuffered = MAX(uMinBuffered, uMinTime);
+
+            HX_ASSERT(uMaxBuffered <= uMaxTime * 1.05);
+        }
+        else if (bHasSeekBuffer)
+        {
+            // OnDemand
+            // Note: Superbuffer is never turned on for local playback.
+
+            // Typical case; without StartParam and EndParam.
+            uMinTime = 0;
+            uMaxTime = GetLength();
+
+            if (uMinBuffered < uMinTime)
+            {
+                HXLOGL2(HXLOG_CNKT, "CHXClientPlayer::GetSuperbufferTimelineInfo() \
unexpected MinBuffered[%d] < MinTime[%d]; fixing.",  +                        \
uMinBuffered, uMinTime); +                uMinTime = uMinBuffered;
+            }
+
+            if (uMaxTime < uMaxBuffered)
+            {
+                HXLOGL2(HXLOG_CNKT, "CHXClientPlayer::GetSuperbufferTimelineInfo() \
%s MaxTime[%d] < MaxBuffered[%d]; fixing.",  +                        (uMaxBuffered - \
uMaxTime) / (double)uMaxTime > 0.1 ? "unexpected": "", // Randomly chose 10% +        \
uMaxTime, uMaxBuffered); +                uMaxTime = uMaxBuffered;
+            }
+        }
+
+        SPIHXPlayer2 spPlayer2 = m_pIHXCorePlayer;
+        UINT32 uMinPreroll = 0;
+
+        if (spPlayer2.IsValid() && \
SUCCEEDED(spPlayer2->GetMinimumPreroll(uMinPreroll))) +        {
+            HXLOGL3(HXLOG_CNKT, "CHXClientPlayer::GetSuperbufferTimelineInfo() \
MinPreroll=%d.", uMinPreroll); +            uMinPreroll = 4000;  // Remove when \
preroll is calculated reliably. +
+            uMaxSeekable = (UINT32) MAX( (INT64)uMaxBuffered - (INT64)uMinPreroll, \
0); +            uMaxSeekable = MAX(uMaxSeekable, uMinBuffered);
+        }
+    }
+
+    HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] GetSuperbufferTimelineInfo() MinTime=%d \
MinBuffered=%d MaxSeekable=%d " +        "MaxBuffered=%d MaxTime=%d IsLive=%s \
SuperbufferEnabled=%s HasSeekBuffer=%s\n",  +        this, uMinTime, uMinBuffered, \
uMaxSeekable, uMaxBuffered, uMaxTime, bIsLive? "true" : "false", +        \
bSuperbufferEnabled? "true" : "false", bHasSeekBuffer? "true" : "false"); +
+    pMinTime     ? *pMinTime = uMinTime         : 0;
+    pMinBuffered ? *pMinBuffered = uMinBuffered : 0;
+    pMaxSeekable ? *pMaxSeekable = uMaxSeekable : 0;
+    pMaxBuffered ? *pMaxBuffered = uMaxBuffered : 0;
+    pMaxTime     ? *pMaxTime = uMaxTime         : 0;
+
+    return result;
+
+}
+
+
 bool
 CHXClientPlayer::StartSeeking( void )
 {
@@ -822,7 +928,7 @@
     HX_RESULT outResult = HXR_FAIL;
     if ( m_IsActivelySeeking /*|| ( GetContentState() == kContentStateStopped )*/ ) \
// XXXSEH: See comment in CHXClientSink::SetBeginPosition()  {
-        HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] SetPosition(0x%08x) \
IsActivelySeeking=1\n", this, position); +        HXLOGL3(HXLOG_CNKT, \
"CHXClientPlayer[%p] SetPosition(%d) IsActivelySeeking=1\n", this, position);  
         // Seeking is done by grabbing the slider thumb and dragging it.
         m_PendingSeekPosition = position;
@@ -830,7 +936,7 @@
     }
     else
     {
-        HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] SetPosition(0x%08x) \
IsActivelySeeking=0\n", this, position); +        HXLOGL3(HXLOG_CNKT, \
"CHXClientPlayer[%p] SetPosition(%d) IsActivelySeeking=0\n", this, position);  
         // Seeking is accomplished with a single click.
         outResult = m_pIHXCorePlayer->Seek( position );
@@ -1654,6 +1760,7 @@
     else
     {
         HXLOGL3(HXLOG_CNKT, "CHXClientPlayer[%p] EnableSuperBuffer( disable )\n", \
this); +        // Assuming reference counting will take care of calls to unload \
RecordService in the middle of a playback!  UnloadRecordService();
     }
 }



Index: player/hxclientkit/pub/HXClientCFuncs.h
===================================================================
RCS file: /cvsroot/player/hxclientkit/pub/HXClientCFuncs.h,v
retrieving revision 1.17.6.4
diff -u -w -r1.17.6.4 HXClientCFuncs.h
--- player/hxclientkit/pub/HXClientCFuncs.h	26 Jun 2007 06:32:07 -0000	1.17.6.4
+++ player/hxclientkit/pub/HXClientCFuncs.h	26 Dec 2007 09:49:33 -0000
@@ -144,7 +144,7 @@
 bool ClientPlayerSetPreferredSuperBufferSize( HXClientPlayerToken clientPlayerToken, \
UInt32 millisecs );  UInt32 ClientPlayerGetPreferredSuperBufferSize( \
HXClientPlayerToken clientPlayerToken );  UInt32 ClientPlayerGetSuperBufferSize( \
                HXClientPlayerToken clientPlayerToken );
-bool ClientPlayerGetSuperBufferRange( HXClientPlayerToken clientPlayerToken, UInt32* \
pMinPosition, UInt32* pWritePosition, UInt32* pMaxPosition); +bool \
ClientPlayerGetSuperbufferTimelineInfo(HXClientPlayerToken clientPlayerToken, UInt32 \
*pMinTime, UInt32 *pMinBuffered, UInt32 *pMaxSeekable, UInt32 *pMaxBuffered, UInt32 \
*pMaxTime);  
 #ifdef __cplusplus
 }


Index: player/app/gtk/hxstatuspositionslider.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/hxstatuspositionslider.cpp,v
retrieving revision 1.24
diff -u -w -r1.24 hxstatuspositionslider.cpp
--- player/app/gtk/hxstatuspositionslider.cpp	19 Sep 2007 12:08:45 -0000	1.24
+++ player/app/gtk/hxstatuspositionslider.cpp	26 Dec 2007 18:58:14 -0000
@@ -220,7 +220,9 @@
     guint32 len;
     gboolean superbuf_ui_mode = false;
     UInt32 minPosition = 0;
-    UInt32 writePosition = 0;
+    UInt32 minBuffered = 0;
+    UInt32 maxSeekable = 0;
+    UInt32 maxBuffered = 0;
     UInt32 maxPosition = 0;
 
     HXStatusDisplayPositionSlider* position_status = \
HX_STATUS_DISPLAY_POSITION_SLIDER(user_data); @@ -234,89 +236,84 @@
 
     superbuf_hscale = HX_SUPERBUF_HSCALE(position_status->position_scale);
 
+    g_return_val_if_fail(superbuf_hscale, TRUE);  // Don't remove the timeout \
                callback.
     g_return_val_if_fail(!superbuf_hscale->grab_button, TRUE);  // Don't remove the \
timeout callback.  
     if(status->player)
     {
-        pos = hx_basic_playback_get_position(status->player);
-        len = hx_basic_playback_get_length(status->player);
-
         // status->player is actually HXBasicPlayback interface, not HXPlayer.
         HXPlayer* player = HX_PLAYER(status->player); 
         HXClientPlayerToken helix_client_token = hx_player_get_token(player);
         g_return_val_if_fail(helix_client_token, TRUE);  // Don't remove the timeout \
callback.  
-        superbuf_ui_mode = ClientPlayerGetSuperBufferRange(helix_client_token, 
-                                                           &minPosition, 
-                                                           &writePosition, 
-                                                           &maxPosition);
-        g_return_val_if_fail(superbuf_hscale, TRUE);  // Don't remove the timeout \
                callback.
-
-        if (superbuf_ui_mode)
-        {
             gboolean is_live_or_infinite;
 
+        pos = hx_basic_playback_get_position(status->player);
             is_live_or_infinite = hx_basic_playback_is_live(status->player) ||
                                   \
hx_basic_playback_is_infinite_duration(status->player);  
+        gboolean is_superb_enabled = \
ClientPlayerIsSuperBufferEnabled(helix_client_token); +        if (is_superb_enabled)
+        {
+            superbuf_ui_mode = \
ClientPlayerGetSuperbufferTimelineInfo(helix_client_token,  +                         \
&minPosition,  +                                                                      \
&minBuffered,  +                                                                      \
&maxSeekable, +                                                                      \
&maxBuffered, +                                                                      \
&maxPosition);  if (is_live_or_infinite)
             {
                 superbuf_hscale->buffer_mode = HX_SUPERB_MODE_LIVE;
-
-                if (writePosition == maxPosition)
+                superbuf_hscale->restrict_seek_in_buffered = TRUE;
+                if (maxBuffered == maxPosition)
                 {
-                    // Add here; subtract in superbufhscale.c
+                    // Add live bg move here; subtract in superbufhscale.c
                     superbuf_hscale->live_background_moved += (guint32) 
                         MAX( (minPosition - superbuf_hscale->adjustment->lower), 0);
                     hx_superbuf_start_animation(superbuf_hscale);
                 }
             }
-            else // OnDemand
+            else
             {
+                // Superbuffer enabled and not live == OnDemand.
                 superbuf_hscale->buffer_mode = HX_SUPERB_MODE_ONDEMAND;
+                superbuf_hscale->restrict_seek_in_buffered = FALSE;
                 superbuf_hscale->live_background_moved = 0;
                 hx_superbuf_stop_animation(superbuf_hscale);
             }
-            superbuf_hscale->restrict_seek_in_buffered = TRUE;
-
-            if (!minPosition && !pos && !maxPosition)
-            {
-                return TRUE;   // don't remove
-            }
-
-            if (minPosition > pos) 
-            {
-                g_warning("Superbuffer minPosition (%u) > pos (%u)", \
                (guint)minPosition, pos);
-            }
-            if (pos > maxPosition)
-            {
-                g_warning("Superbuffer pos (%u) > maxPosition(%u)", pos, \
                (guint)maxPosition);
-            }
 
             hx_superbuf_hscale_set(superbuf_hscale, 
                                    pos,             // value
                                    minPosition,     // lower
                                    maxPosition,     // upper
-                                   minPosition,     // buffer_min 
-                                   writePosition,   // buffer_max 
-                                   TRUE);           // restrict_seek_in_buffered 
+                                   minBuffered,     // buffer_min 
+                                   maxSeekable,     // buffer_max 
+                                   is_live_or_infinite);    // \
restrict_seek_in_buffered   
         }
-        else if(len > 0) 
+        else if (is_live_or_infinite)
+        {
+            // Superbuffer disabled and live.
+            superbuf_hscale->buffer_mode = HX_SUPERB_MODE_NON_SUPERB;
+            superbuf_hscale->live_background_moved = 0;
+            hx_superbuf_stop_animation(superbuf_hscale);
+        }
+        else
         {
             // Also non-superbuffer case.
+            len = hx_basic_playback_get_length(status->player);
+
             superbuf_hscale->buffer_mode = HX_SUPERB_MODE_NON_SUPERB;
             superbuf_hscale->live_background_moved = 0;
             hx_superbuf_stop_animation(superbuf_hscale);
 
             hx_superbuf_hscale_set(superbuf_hscale, 
                                    pos,     // value
-                                   0,       // lower
+                                   0.0,     // lower
                                    len,     // upper
                                    0.0,     // buffer_min 
                                    0.0,     // buffer_max 
                                    FALSE);  // restrict_seek_in_buffered 
-
         }
     }
 
Index: player/app/gtk/superbufhscale.c
===================================================================
RCS file: /cvsroot/player/app/gtk/superbufhscale.c,v
retrieving revision 1.10
diff -u -w -r1.10 superbufhscale.c
--- player/app/gtk/superbufhscale.c	11 Oct 2007 20:36:43 -0000	1.10
+++ player/app/gtk/superbufhscale.c	26 Dec 2007 18:58:14 -0000
@@ -136,10 +136,18 @@
     layout = &superbuf_hscale->layout;
     widget = GTK_WIDGET(superbuf_hscale);
 
+    x = widget->allocation.x + layout->trough_rect.x;
+
+    if ( (superbuf_hscale->adjustment->upper - superbuf_hscale->adjustment->lower) \
<= 0) +    {
+        // Return x window coordinate of slider zero.
+        return x;
+    }
+
     value_ratio = (value - superbuf_hscale->adjustment->lower) / 
         (superbuf_hscale->adjustment->upper - superbuf_hscale->adjustment->lower);
 
-    x = widget->allocation.x + layout->trough_rect.x + layout->trough_rect.width * \
value_ratio; +    x += layout->trough_rect.width * value_ratio;
 
     return x;
 }
@@ -1698,8 +1706,7 @@
     HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
     guint grab_button = superbuf_hscale->grab_button;
 
-
-    if (event->keyval == GDK_Escape && superbuf_hscale->grab_button)
+    if (event->keyval == GDK_Escape && grab_button)
     {
         hx_superbuf_hscale_grab_remove(superbuf_hscale);
 
@@ -1708,7 +1715,7 @@
         return TRUE;
     }
 
-    if (superbuf_hscale->grab_button)
+    if (grab_button)
     {
         return FALSE;
     }



_______________________________________________
Player-dev mailing list
Player-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/player-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic