[Player-cvs] app/gtk commonapp.cpp, 1.97.2.1.2.1, 1.97.2.1.2.2 guids.cpp, 1.16, 1.16.6.1 hxstatuspositionslider.cpp, 1.25.2.1, 1.25.2.1.2.1 prefsdialog.cpp, 1.41, 1.41.6.1 superbufhscale.cpp, 1.3.2.1, 1.3.2.1.2.1 superbufhscale.h, 1.4.10.1, 1.4.10.1.2.1

[Player-cvs] app/gtk commonapp.cpp, 1.97.2.1.2.1, 1.97.2.1.2.2 guids.cpp, 1.16, 1.16.6.1 hxstatuspositionslider.cpp, 1.25.2.1, 1.25.2.1.2.1 prefsdialog.cpp, 1.41, 1.41.6.1 superbufhscale.cpp, 1.3.2.1, 1.3.2.1.2.1 superbufhscale.h, 1.4.10.1, 1.4.10.1.2.1

idefix at helixcommunity.org idefix at helixcommunity.org
Fri Oct 10 01:09:25 PDT 2008


Update of /cvsroot/player/app/gtk
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv13756/app/gtk

Modified Files:
      Tag: balto_sun
	commonapp.cpp guids.cpp hxstatuspositionslider.cpp 
	prefsdialog.cpp superbufhscale.cpp superbufhscale.h 
Log Message:
Modified by: chris.wang at sun.com
Date: 10/09/2008
Project: Porting to Solaris
Synopsis: Merge cumulative changes from 150Cay to 205Cay. on Sun balto branch

Overview:
Merge cumulative changes from 150Cay to 205Cay. on Sun balto branch

Files Modified:

player/installer/postinst/platform/unix/postinst.cpp
  Tar handling changes.

player/app/gtk/prefsdialog.cpp
  Overlay/XVideo and ALSA device changes.

player/app/gtk/superbufhscale.cpp
player/app/gtk/superbufhscale.h
player/app/gtk/hxstatuspositionslider.cpp
  Xorg XID Reuse Extension fix.
  Left edge, widget coords fix.

player/app/gtk/guids.cpp

player/app/gtk/commonapp.cpp
  http://lists.helixcommunity.org/pipermail/player-dev/2008-June/003694.html
  Player gives HXR_ALREADY_OPEN error on second & subsequent trials
player/installer/archive/make_tempdir
player/installer/archive/make_archive
player/installer/archive/make_symbols
player/installer/app/Umakefil
player/installer/common/common.py
player/installer/common/postinst/postuninst.sh
player/installer/common/postinst/setup_path.sh
player/installer/common/postinst/install_fedora_selinux_workaround.sh 
player/app/gtk/unix.pcf
player/common/gtk/unix.pcf 

Platforms and Profiles Affected:
Solaris/Linux

Distribution Libraries Affected:
libhxclient.so

Distribution library impact and planned action:
no

Platforms and Profiles Build Verified:
Have verified on solaris 11 x86 , with
SYSTEM_ID=sunos-5.10-i386-studio11, profile as player-all


BIF : reaplayer_gtk_balto_sun
Profile: helix_client_all_defines
Branch :  hxclient_2_0_5_cayenne
Copyright assignment:
1. My company (sun.com) submits this code under the terms
of a commercial contribution agreement with RealNetworks,
and I am authorized to contribute this code under said agreement.



Index: prefsdialog.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/prefsdialog.cpp,v
retrieving revision 1.41
retrieving revision 1.41.6.1
diff -u -d -r1.41 -r1.41.6.1
--- prefsdialog.cpp	26 Dec 2007 10:09:58 -0000	1.41
+++ prefsdialog.cpp	10 Oct 2008 08:04:19 -0000	1.41.6.1
@@ -1452,8 +1452,8 @@
     { "HTTPProxyHost",      "",                "hpd_http_proxy_host",          prefs_entry_read,                    prefs_entry_write                    },
     { "HTTPProxyPort",      "80",              "hpd_http_proxy_port",          prefs_entry_read,                    prefs_entry_write                    },
     { "Quality",            "4",               "hpd_quality",                  prefs_scale_read,                    prefs_scale_write                    },
-    { "UseOverlay",         "1",               "hpd_use_overlay",              prefs_checkbutton_read,              prefs_checkbutton_write              },
-    { "OverlayMode",        "1",               "hpd_use_overlay",              prefs_checkbutton_read,              prefs_checkbutton_write              },
+    { "UseOverlay",         "0",               "hpd_use_overlay",              prefs_checkbutton_read,              prefs_checkbutton_write              },
+    { "OverlayMode",        "0",               "hpd_use_overlay",              prefs_checkbutton_read,              prefs_checkbutton_write              },
     { "SoundDriver",        "3"/* ALSA */,     "hpd_sound_driver",             prefs_sound_driver_option_menu_read, prefs_sound_driver_option_menu_write },
     { "UseUDPPort",         "0",               "hpd_use_udp_port",             prefs_checkbutton_read,              prefs_checkbutton_write              },
     { "UDPPort",            "7070",            "hpd_udp_port",                 prefs_entry_read,                    prefs_entry_write                    },
@@ -1475,7 +1475,7 @@
     { "EnableSuperbuffer",    "1",     "hpd_playback_perfectplay_checkbutton", prefs_checkbutton_read,              prefs_checkbutton_write,             (gpointer)prefs_enable_superbuffer_write_value_notify  },
     { "SuperBufferLength",  "300000",       "hpd_playback_livepause_combobox", prefs_combobox_read,                 prefs_combobox_write,                (gpointer)&livepause_combobox_mapping },
 
-    { "AlsaPCMDeviceName",  "default",         "hpd_alsa_pcm_device",          prefs_entry_read,                    prefs_entry_write                    },
+    { "AlsaPCMDeviceName",  "cards.pcm.default", "hpd_alsa_pcm_device",        prefs_entry_read,                    prefs_entry_write                    },
     { "Alsa51PCMDeviceName","plug:surround51", "hpd_alsa_51_pcm_device_entry", prefs_entry_read,                    prefs_entry_write                    },
     { "OSSPCMElementName",  "/dev/dsp",        "hpd_oss_pcm_device",           prefs_entry_read,                    prefs_entry_write                    },
     { "OSSMixerElementName","/dev/mixer",      "hpd_oss_mixer_device",         prefs_entry_read,                    prefs_entry_write                    },

Index: superbufhscale.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/superbufhscale.cpp,v
retrieving revision 1.3.2.1
retrieving revision 1.3.2.1.2.1
diff -u -d -r1.3.2.1 -r1.3.2.1.2.1
--- superbufhscale.cpp	25 Feb 2008 01:27:23 -0000	1.3.2.1
+++ superbufhscale.cpp	10 Oct 2008 08:04:19 -0000	1.3.2.1.2.1
@@ -78,6 +78,7 @@
 static gboolean hx_superbuf_hscale_motion_notify_event(GtkWidget *widget, GdkEventMotion *event);
 static gboolean hx_superbuf_hscale_scroll_event(GtkWidget *widget, GdkEventScroll *event);
 static gboolean hx_superbuf_hscale_key_press_event(GtkWidget *widget, GdkEventKey *event);
+static void hx_superbuf_hscale_common_free_resources(HXSuperbufHScale *superbuf_hscale);
 
 #if GTK_CHECK_VERSION(2, 8, 0)
 static gboolean hx_superbuf_hscale_grab_broken_event(GtkWidget *widget, GdkEventGrabBroken *event);
@@ -175,12 +176,20 @@
     return value;
 }
 
+void
+hx_superbuf_hscale_set_mode(HXSuperbufHScale *superbuf_hscale, HX_SUPERB superbuffer_mode)
+{
+    superbuf_hscale->buffer_mode = superbuffer_mode;
+
+    return;
+}
 
 // Layout slider (thumb) and slider label.
 void 
 hx_superbuf_hscale_layout_slider(HXSuperbufHScale *superbuf_hscale)
 {
     gchar *label_text = NULL, *temp = NULL;
+    GtkWidget *widget = GTK_WIDGET(superbuf_hscale);
     PangoRectangle logical_pango_rect_label = {0, 0, 0, 0};
     HXSuperbufHScaleLayout *layout = &superbuf_hscale->layout;
     gint min, max;
@@ -192,7 +201,7 @@
 
     // Layout slider (thumb)
     slider_width = superbuf_hscale->slider_graphics.subgraphic_width[superbuf_hscale->buffer_mode];
-    layout->slider_rect.x = x - slider_width/2;
+    layout->slider_rect.x = x - widget->allocation.x - slider_width/2;  // layout coords are widget coord, not window coords.
 
     layout->slider_rect.y = layout->trough_rect.y - 
         (superbuf_hscale->slider_height - layout->trough_rect.height) / 2;
@@ -246,14 +255,11 @@
                                    GtkAllocation          *allocation)
 {
     gint border_left = 0, border_right = 0, border_top = 0, border_bottom = 0;
-    gint buffer_min_x, buffer_max_x;
 
     gint hscale_height = 0;          // Not including borders.
 
-    GtkStateType state_type;
     PangoRectangle logical_pango_rect_label = {0, 0, 0, 0};
     gchar *label_text = NULL;
-    GtkWidget *widget = GTK_WIDGET(superbuf_hscale);
 
     gint slider_width;
     gint trough_border; // The actual border + the part of slider that overhangs the trough.
@@ -333,67 +339,81 @@
         return;
     }
 
-    buffer_min_x = hx_superbuf_hscale_adjustment_value_to_slider_x(superbuf_hscale, superbuf_hscale->buffer_min);
+    layout->buffer_min_x = hx_superbuf_hscale_adjustment_value_to_slider_x(superbuf_hscale, superbuf_hscale->buffer_min);
 
     // Buffer width corresponding to x coordinate.
-    buffer_max_x = hx_superbuf_hscale_adjustment_value_to_slider_x(superbuf_hscale, superbuf_hscale->buffer_max);
+    layout->buffer_max_x = hx_superbuf_hscale_adjustment_value_to_slider_x(superbuf_hscale, superbuf_hscale->buffer_max);
 
-    HXLOGL4(HXLOG_TLCX, "hx_superbuf_hscale_calc_allocation() buffer_min_x=%d, buffer_max_x=%d", buffer_min_x, buffer_max_x);
+    HXLOGL4(HXLOG_TLCX, "hx_superbuf_hscale_calc_allocation() buffer_min_x=%d, buffer_max_x=%d", layout->buffer_min_x, layout->buffer_max_x);
 
     // Layout Tile Graphics
     switch (superbuf_hscale->buffer_mode)
     {
-    case HX_SUPERB_MODE_BG:
-        layout->fg_tile = HX_SUPERB_MODE_NIL;
-        layout->fg_tile_rect.x = 0;
-        layout->fg_tile_rect.y = 0;
-        layout->fg_tile_rect.width = 0;
-        layout->fg_tile_rect.height = 0;
+    case HX_SUPERB_BG:
+        layout->fg_graphic = HX_SUPERB_NIL;
+        layout->fg_graphic_rect.x = 0;
+        layout->fg_graphic_rect.y = 0;
+        layout->fg_graphic_rect.width = 0;
+        layout->fg_graphic_rect.height = 0;
+
+        layout->draw_buffer_track = FALSE;
+        layout->draw_live_track = FALSE;
         break;
-    case HX_SUPERB_MODE_NON_SUPERB:
-        layout->fg_tile = HX_SUPERB_MODE_NON_SUPERB;
-        layout->fg_tile_rect.x      = layout->trough_rect.x;
-        layout->fg_tile_rect.y      = layout->trough_rect.y;
-        layout->fg_tile_rect.width  = layout->trough_rect.width;
-        layout->fg_tile_rect.height = layout->trough_rect.height;
+
+    case HX_SUPERB_NON_SUPERBUFFERED:
+        layout->fg_graphic = HX_SUPERB_NON_SUPERBUFFERED;
+        layout->fg_graphic_rect.x      = layout->trough_rect.x;
+        layout->fg_graphic_rect.y      = layout->trough_rect.y;
+        layout->fg_graphic_rect.width  = layout->trough_rect.width;
+        layout->fg_graphic_rect.height = layout->trough_rect.height;
+
+        layout->draw_buffer_track = TRUE;
+        layout->draw_live_track = FALSE;
         break;
-    case HX_SUPERB_MODE_ONDEMAND:
-        layout->fg_tile = HX_SUPERB_MODE_ONDEMAND;
-        layout->fg_tile_rect.x      = buffer_min_x;
-        layout->fg_tile_rect.y      = layout->trough_rect.y;
-        layout->fg_tile_rect.width  = buffer_max_x - buffer_min_x + 1;
-        layout->fg_tile_rect.height = layout->trough_rect.height;
 
-        HXLOGL4(HXLOG_TLCX, "hx_superbuf_hscale_calc_allocation() OnDemand: fg_tile_rect.x=%d, fg_tile_rect.width=%d", 
-            layout->fg_tile_rect.x, layout->fg_tile_rect.width);
+    case HX_SUPERB_ONDEMAND:
+        layout->fg_graphic = HX_SUPERB_ONDEMAND;
+        layout->fg_graphic_rect.x      = layout->buffer_min_x;
+        layout->fg_graphic_rect.y      = layout->trough_rect.y;
+        layout->fg_graphic_rect.width  = layout->buffer_max_x - layout->buffer_min_x + 1;
+        layout->fg_graphic_rect.height = layout->trough_rect.height;
+
+        layout->draw_buffer_track = TRUE;
+        layout->draw_live_track = FALSE;
+
+        HXLOGL4(HXLOG_TLCX, "hx_superbuf_hscale_calc_allocation() OnDemand: fg_graphic_rect.x=%d, fg_graphic_rect.width=%d", 
+            layout->fg_graphic_rect.x, layout->fg_graphic_rect.width);
         break;
-    case HX_SUPERB_MODE_LIVE:
-        layout->fg_tile = HX_SUPERB_MODE_ONDEMAND;
-        layout->fg_tile_rect.x      = buffer_min_x;
-        layout->fg_tile_rect.y      = layout->trough_rect.y;
-        layout->fg_tile_rect.width  = buffer_max_x - buffer_min_x + 1;
-        layout->fg_tile_rect.height = layout->trough_rect.height;
 
-        layout->live_tile_rect.x      = buffer_min_x;
+    case HX_SUPERB_LIVE:
+        layout->fg_graphic = HX_SUPERB_ONDEMAND;
+        layout->fg_graphic_rect.x      = layout->buffer_min_x;
+        layout->fg_graphic_rect.y      = layout->trough_rect.y;
+        layout->fg_graphic_rect.width  = layout->buffer_max_x - layout->buffer_min_x + 1;
+        layout->fg_graphic_rect.height = layout->trough_rect.height;
+
+        layout->live_tile_rect.x      = layout->buffer_min_x;
         layout->live_tile_rect.y      = layout->trough_rect.y;
-        layout->live_tile_rect.width  = buffer_max_x - buffer_min_x + 1;
+        layout->live_tile_rect.width  = layout->buffer_max_x - layout->buffer_min_x + 1;
         layout->live_tile_rect.height = layout->trough_rect.height;
 
+        layout->draw_buffer_track = TRUE;
+        layout->draw_live_track = TRUE;
+
         HXLOGL4(HXLOG_TLCX, "hx_superbuf_hscale_calc_allocation() Live: live_tile_rect.x=%d, live_tile_rect.width=%d", 
             layout->live_tile_rect.x, layout->live_tile_rect.width);
 
         break;
+
     default:
         g_assert(!"Unknown superbuffer mode!");
         break;
     }
 
-    state_type = (GtkStateType)GTK_WIDGET_STATE(widget);
-    if (state_type == GTK_STATE_PRELIGHT)
-    {
+    // state_type == GTK_STATE_PRELIGHT or not, calculate the the layout as if it is has PRELIGHT.
         // Middle of tile_leading_pixels is a more realistic start visually. 
         layout->buffer_start_arrow.x = layout->trough_rect.x
-            + (superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].tile_leading_pixels + 1)  / 2
+        + (superbuf_hscale->tile_graphics[HX_SUPERB_BG].tile_leading_pixels + 1)  / 2
             - superbuf_hscale->arrow_size / 2;
         layout->buffer_start_arrow.y = layout->trough_rect.y + layout->trough_rect.height;
         layout->buffer_start_arrow.width  = superbuf_hscale->arrow_size;
@@ -418,7 +438,7 @@
 
         // Layout *end* arrow
         layout->buffer_end_arrow.x = layout->trough_rect.x + layout->trough_rect.width
-            - (superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].tile_trailing_pixels + 1)  / 2
+        - (superbuf_hscale->tile_graphics[HX_SUPERB_BG].tile_trailing_pixels + 1)  / 2
             - superbuf_hscale->arrow_size / 2;
         layout->buffer_end_arrow.y = layout->trough_rect.y + layout->trough_rect.height;
         layout->buffer_end_arrow.width  = superbuf_hscale->arrow_size;
@@ -452,14 +472,13 @@
 
         layout->buffer_start_label.x = layout->buffer_start_label.x;
         layout->buffer_start_label.y = layout->buffer_start_label.y;
-        // Clear "border_preferred" pixels beyond beginning of end label too.
+    // Clear "border_preferred" pixels beyond beginning of end label too
+    // to make it more readable.
         layout->buffer_start_label.width = 
             layout->buffer_end_label.x - layout->buffer_start_label.x 
             - border_preferred;
         layout->buffer_start_label.height = layout->buffer_start_label.height;
 
-    }
-
     hx_superbuf_hscale_layout_slider(superbuf_hscale);
 
     return;
@@ -480,39 +499,39 @@
 
     superbuf_hscale->user_control_notify_delay = 1000;  // ms
 
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].pixbuf 
+    superbuf_hscale->tile_graphics[HX_SUPERB_BG].pixbuf 
         = create_pixbuf("track.png");   
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_NON_SUPERB].pixbuf 
+    superbuf_hscale->tile_graphics[HX_SUPERB_NON_SUPERBUFFERED].pixbuf 
         = create_pixbuf("nonsuperb.png");           // Corresponds to postrack.png
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND].pixbuf
+    superbuf_hscale->tile_graphics[HX_SUPERB_ONDEMAND].pixbuf
         = create_pixbuf("superbuffer.png");         // Corresponds to trackmask.png
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE].pixbuf
+    superbuf_hscale->tile_graphics[HX_SUPERB_LIVE].pixbuf
         = create_pixbuf("superbufferlive.png");     // Corresponds to superbuffertile.png
 
 
-    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].pixbuf);
-    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_MODE_NON_SUPERB].pixbuf);
-    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND].pixbuf);
-    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE].pixbuf);
+    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_BG].pixbuf);
+    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_NON_SUPERBUFFERED].pixbuf);
+    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_ONDEMAND].pixbuf);
+    g_return_if_fail(superbuf_hscale->tile_graphics[HX_SUPERB_LIVE].pixbuf);
 
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].tile_leading_pixels = 5;
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG].tile_trailing_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_BG].tile_leading_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_BG].tile_trailing_pixels = 5;
 
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_NON_SUPERB].tile_leading_pixels = 5;
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_NON_SUPERB].tile_trailing_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_NON_SUPERBUFFERED].tile_leading_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_NON_SUPERBUFFERED].tile_trailing_pixels = 5;
 
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND].tile_leading_pixels = 5;
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND].tile_trailing_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_ONDEMAND].tile_leading_pixels = 5;
+    superbuf_hscale->tile_graphics[HX_SUPERB_ONDEMAND].tile_trailing_pixels = 5;
 
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE].right_align = TRUE;
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE].tile_leading_pixels = 0;  
-    superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE].tile_trailing_pixels = 0; 
+    superbuf_hscale->tile_graphics[HX_SUPERB_LIVE].right_align = TRUE;
+    superbuf_hscale->tile_graphics[HX_SUPERB_LIVE].tile_leading_pixels = 0;  
+    superbuf_hscale->tile_graphics[HX_SUPERB_LIVE].tile_trailing_pixels = 0; 
 
-    superbuf_hscale->animate_delta = 0;
+    superbuf_hscale->animate_delta = 0.0;
 
     superbuf_hscale->trough_height = 0;
     superbuf_hscale->trough_min_width = 0;
-    for (i = 0; i < HX_SUPERB_MODE_LAST; ++i)
+    for (i = 0; i < HX_SUPERB_LAST; ++i)
     {
         height = gdk_pixbuf_get_height(superbuf_hscale->tile_graphics[i].pixbuf);
         min_width = superbuf_hscale->tile_graphics[i].tile_leading_pixels + 
@@ -536,21 +555,18 @@
         = create_pixbuf("sliders.png");             // Corresponds to posthumb.png
     g_return_if_fail(superbuf_hscale->slider_graphics.pixbuf);
 
-    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_MODE_BG]         = 0;
-    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_MODE_NON_SUPERB] = 9;
-    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_MODE_ONDEMAND]   = 18;
-    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_MODE_LIVE]       = 27;
+    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_BG]         = 0;
+    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_NON_SUPERBUFFERED] = 9;
+    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_ONDEMAND]   = 18;
+    superbuf_hscale->slider_graphics.subgraphic_x[HX_SUPERB_LIVE]       = 27;
 
-    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_MODE_BG]         = 9;
-    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_MODE_NON_SUPERB] = 9;
-    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_MODE_ONDEMAND]   = 9;
-    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_MODE_LIVE]       = 9;
+    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_BG]         = 9;
+    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_NON_SUPERBUFFERED] = 9;
+    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_ONDEMAND]   = 9;
+    superbuf_hscale->slider_graphics.subgraphic_width[HX_SUPERB_LIVE]       = 9;
 
     superbuf_hscale->slider_height = gdk_pixbuf_get_height(superbuf_hscale->slider_graphics.pixbuf);
 
-
-
-
     superbuf_hscale->arrow_size = 10;
 
     // PangoLayout
@@ -721,15 +737,15 @@
 {
     HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(object);
 
-    hx_superbuf_stop_animation(superbuf_hscale);
+    hx_superbuf_hscale_common_free_resources(superbuf_hscale);
 
+    // _dispose() can be called multiple times; don't free up multiple times!
     if (superbuf_hscale->adjustment) 
     {
         g_object_unref(superbuf_hscale->adjustment);
         superbuf_hscale->adjustment = NULL;
     }
 
-    // _dispose() can be called multiple times; don't free up multiple times!
     if (superbuf_hscale->pango_layout_start)
     {
         g_object_unref(superbuf_hscale->pango_layout_start);
@@ -746,11 +762,19 @@
         superbuf_hscale->pango_layout_slider = NULL;
     }
 
+    if (superbuf_hscale->slider_graphics.pixbuf)
+    {
+        g_object_unref(superbuf_hscale->slider_graphics.pixbuf);
+        superbuf_hscale->slider_graphics.pixbuf = NULL;
+    }
+
     // Chain up
     if ( G_OBJECT_CLASS(hx_superbuf_hscale_parent_class)->dispose)
     {
         G_OBJECT_CLASS(hx_superbuf_hscale_parent_class)->dispose(object);
     }
+
+    return;
 }
 
 
@@ -860,6 +884,68 @@
     return;
 }
 
+static void
+hx_superbuf_handle_size_dependent_xresources(GtkWidget *widget)
+{
+    // When this function is called from size_allocate() before realize(), 
+    // there is no widget->window needed to allocate X server resources.
+    g_return_if_fail(GTK_WIDGET_REALIZED(widget));
+
+    HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
+
+    const GdkColor white_color = {1, 0, 0, 0};
+    gint tile_mask_width = superbuf_hscale->tile_mask_width;
+    GtkAllocation *allocation = &widget->allocation;
+
+    // Move event_window
+    gdk_window_move_resize(superbuf_hscale->event_window, 
+                           allocation->x,
+                           allocation->y,
+                           allocation->width,
+                           allocation->height);
+
+    // Allocate X server resources.
+    // Create the mask used for tiling.
+    if (superbuf_hscale->tile_mask && 
+        allocation->width > 0 && 
+        allocation->height > 0 && 
+        allocation->width != tile_mask_width) // height is the constant trough_height.
+    {
+        // Deallocate only if sizes changed.
+        g_object_unref(superbuf_hscale->tile_mask);
+        superbuf_hscale->tile_mask = NULL;
+    }
+
+    if (!superbuf_hscale->tile_mask)
+    {
+        tile_mask_width = allocation->width;
+        g_assert(tile_mask_width > 0);
+
+        superbuf_hscale->tile_mask = gdk_pixmap_new(widget->window, 
+                                                    tile_mask_width, 
+                                                    superbuf_hscale->trough_height, // Fixed max. image height computed from graphics.
+                                                    1);             // depth
+
+        superbuf_hscale->tile_mask_width = tile_mask_width;     // Remember the current tile_mask's width.
+
+        HXLOGL4(HXLOG_TLCX, "hx_superbuf_alloc_xserver_resources() Allocated tile_mask_width=%d trough_height=%d", tile_mask_width, superbuf_hscale->trough_height);
+    }
+    g_assert(superbuf_hscale->tile_mask);
+
+    // Create the GC.
+    if (superbuf_hscale->tile_mask_gc)
+    {
+        g_object_unref(superbuf_hscale->tile_mask_gc);
+        superbuf_hscale->tile_mask_gc = NULL;
+    }
+    superbuf_hscale->tile_mask_gc = gdk_gc_new(superbuf_hscale->tile_mask); 
+    g_assert(superbuf_hscale->tile_mask_gc);
+
+    gdk_gc_set_fill(superbuf_hscale->tile_mask_gc, GDK_TILED);
+    gdk_gc_set_foreground(superbuf_hscale->tile_mask_gc, &white_color);
+
+    return;
+}
 
 
 static void
@@ -868,6 +954,11 @@
     GdkWindowAttr attributes = {};
     gint attributes_mask = 0;
     HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
+    gint image_height = 0;
+    gint image_width = 0;
+    gint tile_height = 0;
+    gint tile_width = 0;
+    guint u;
 
     GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
     widget->window = gtk_widget_get_parent_window(widget);
@@ -898,20 +989,146 @@
     gdk_window_set_user_data (superbuf_hscale->event_window, superbuf_hscale);
     widget->style = gtk_style_attach (widget->style, widget->window);
 
+    g_assert(!superbuf_hscale->gc);  // Forgot to unref() in unrealize()?
+    superbuf_hscale->gc = gdk_gc_new(widget->window);
+    g_assert(superbuf_hscale->gc);
+    gdk_gc_copy(superbuf_hscale->gc, widget->style->white_gc); 
+
+    g_assert(!superbuf_hscale->tile_mid_section_gc);    // Forgot to unref() in unrealize()?
+    superbuf_hscale->tile_mid_section_gc = gdk_gc_new(widget->window);
+    g_assert(superbuf_hscale->tile_mid_section_gc);
+    gdk_gc_copy(superbuf_hscale->tile_mid_section_gc, widget->style->white_gc); 
+    gdk_gc_set_fill(superbuf_hscale->tile_mid_section_gc, GDK_TILED);
+
+    for (u = 0; u < sizeof(superbuf_hscale->tile_graphics)/sizeof(superbuf_hscale->tile_graphics[0]); ++u)
+    {
+        TileGraphic *graphic = &superbuf_hscale->tile_graphics[u];
+        HXTileGraphicPrivate *tile_graphics_private = &superbuf_hscale->tile_graphics_private[u];
+
+        // right_align mode doesn't support leading and trailing non-tileable pixels 
+        // in this implementation.
+        g_return_if_fail(!graphic->right_align || 
+            (!graphic->tile_leading_pixels && !graphic->tile_trailing_pixels) );
+
+        image_width = gdk_pixbuf_get_width(graphic->pixbuf);
+        tile_width = image_width - graphic->tile_leading_pixels - graphic->tile_trailing_pixels;
+
+        g_return_if_fail(tile_width >= 0);
+
+        image_height = tile_height = gdk_pixbuf_get_height(graphic->pixbuf);
+
+        tile_graphics_private->image_width = image_width;
+        tile_graphics_private->image_height = image_height;
+        tile_graphics_private->tile_width = tile_width;
+
+        HXLOGL4(HXLOG_TLCX, "image_width=%d, tile_width=%d, image_height=%d", tile_graphics_private->image_width, tile_graphics_private->tile_width, tile_graphics_private->image_height);
+
+        // Generate tile (middle section) pixmap itself.
+        g_assert(!tile_graphics_private->tile_pixmap);     // Forgot to unref() in unrealize()?
+        tile_graphics_private->tile_pixmap = gdk_pixmap_new(widget->window, 
+                                                            tile_width,
+                                                            tile_height,
+                                                            -1);            // depth
+        g_assert(tile_graphics_private->tile_pixmap);
+
+        gdk_draw_pixbuf(tile_graphics_private->tile_pixmap, 
+                        superbuf_hscale->gc, 
+                        graphic->pixbuf, 
+                        graphic->tile_leading_pixels,            // src_x
+                        0,                                       // src_y
+                        0, 0,                                    // dest_x, dest_y,
+                        tile_width, tile_height,
+                        GDK_RGB_DITHER_NONE,
+                        0, 0);                                   // x_dither, y_dither.
+
+        // These don't need changing their sizes when widget sizes changed.
+
+        // Create the bitmap for transparent pixels.
+        g_assert(!tile_graphics_private->tile_bitmap);     // Forgot to unref() in unrealize()?
+        tile_graphics_private->tile_bitmap = gdk_pixmap_new(widget->window, 
+                                                            tile_width, 
+                                                            tile_height, 
+                                                            1);             // depth
+        g_assert(tile_graphics_private->tile_bitmap);
+
+        gdk_pixbuf_render_threshold_alpha(graphic->pixbuf,
+                                          tile_graphics_private->tile_bitmap,
+                                          graphic->tile_leading_pixels, 0,   // src_x, src_y
+                                          0, 0,                              // dest_x, dest_y
+                                          tile_width, tile_height,
+                                          127);                              // alpha_threshold
+    }
+
+    // Allocate size-dependent X server resources ahead of expose().
+    hx_superbuf_handle_size_dependent_xresources(widget);
+
     return;
 }
 
 static void
-hx_superbuf_hscale_unrealize(GtkWidget *widget)
+hx_superbuf_hscale_common_free_resources(HXSuperbufHScale *superbuf_hscale)
 {
-    HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
+    guint u;
 
+    if (superbuf_hscale->event_window)
+    {
     gdk_window_set_user_data (superbuf_hscale->event_window, NULL);
     gdk_window_destroy(superbuf_hscale->event_window);
     superbuf_hscale->event_window = NULL;
+    }
 
     hx_superbuf_stop_animation(superbuf_hscale);
 
+    for (u = 0; u < sizeof(superbuf_hscale->tile_graphics_private)/sizeof(superbuf_hscale->tile_graphics_private[0]); ++u)
+    {
+        HXTileGraphicPrivate *tile_graphics_private = &superbuf_hscale->tile_graphics_private[u];
+        if (tile_graphics_private->tile_pixmap)
+        {
+            g_object_unref(tile_graphics_private->tile_pixmap); 
+            tile_graphics_private->tile_pixmap = NULL;
+        }
+
+        if (tile_graphics_private->tile_bitmap)
+        {
+            g_object_unref(tile_graphics_private->tile_bitmap); 
+            tile_graphics_private->tile_bitmap = NULL;
+        }
+    }
+
+    if (superbuf_hscale->gc)
+    {
+        g_object_unref(superbuf_hscale->gc); 
+        superbuf_hscale->gc = NULL;
+    }
+
+    if (superbuf_hscale->tile_mask_gc)
+    {
+        g_object_unref(superbuf_hscale->tile_mask_gc); 
+        superbuf_hscale->tile_mask_gc = NULL;
+    }
+
+    if (superbuf_hscale->tile_mid_section_gc)
+    {
+        g_object_unref(superbuf_hscale->tile_mid_section_gc); 
+        superbuf_hscale->tile_mid_section_gc = NULL;
+    }
+
+    if (superbuf_hscale->tile_mask)
+    {
+        g_object_unref(superbuf_hscale->tile_mask); 
+        superbuf_hscale->tile_mask = NULL;
+    }
+
+    return;
+}
+
+static void
+hx_superbuf_hscale_unrealize(GtkWidget *widget)
+{
+    HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
+
+    hx_superbuf_hscale_common_free_resources(superbuf_hscale);
+
     // Chain up
     if ( GTK_WIDGET_CLASS(hx_superbuf_hscale_parent_class)->unrealize)
     {
@@ -978,15 +1195,15 @@
     // Force widget to fit into the actual allocated dimension.
     hx_superbuf_hscale_calc_allocation(superbuf_hscale, &superbuf_hscale->layout, allocation);
 
-    // Move event_window
+    // When size_allocate() is called first, before realize(), there is no widget->window needed 
+    // to allocate X server resources.
+    // After realize() and map(), we need to reallocate X server resources here 
+    // whenever allocation size changes. 
     if (GTK_WIDGET_REALIZED(widget))
     {
-        gdk_window_move_resize(superbuf_hscale->event_window, 
-                               allocation->x,
-                               allocation->y,
-                               allocation->width,
-                               allocation->height);
+        hx_superbuf_handle_size_dependent_xresources(widget);
     }
+
     gtk_widget_queue_draw(widget);
 
     return;
@@ -1026,83 +1243,70 @@
 
 
 
+// Draw one set of leading graphic, mid-section tiled graphic, and trailing graphic.
 void
-draw_tile_graphic(GtkWidget    *widget, 
-                  GdkGC        *gc_in,          // Can be NULL
-                  TileGraphic  *graphic, 
-                  GdkRectangle *dest_rect, 
-                  gint         animate_delta)   // Shift graphic to the left for animation.
+hx_superbuf_hscale_draw_tile_graphic(GtkWidget *widget, 
+                                     HX_SUPERB superbuffer_graphic)
 {
-    gint image_height = 0;
-    gint image_width = 0;
-    gint tile_height = 0;
-    gint tile_width = 0;
+    HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
+    TileGraphic *graphic = &superbuf_hscale->tile_graphics[superbuffer_graphic]; 
+    HXTileGraphicPrivate *tile_graphics_private = &superbuf_hscale->tile_graphics_private[superbuffer_graphic];
+    HXSuperbufHScaleLayout *layout = &superbuf_hscale->layout;
+    GdkRectangle clip_rect = {};
+    GdkRectangle *layout_rect = NULL;
     gint center_delta = 0;  // Number of pixels to add to y to center the graphic.
-    gint align_delta = 0;   // Number of pixels to move to the left to align the tile (to the right edge).
-
-    GdkPixmap *tile_pixmap = NULL;
-    GdkBitmap *tile_bitmap = NULL;
-    GdkBitmap *tile_mask = NULL;
-    GdkGC *gc = NULL;
-    GdkGC *tile_mask_gc = NULL;
-    GdkRectangle clip_rect;
+    gdouble align_delta = 0;   // Number of pixels to move to the left to align the tile (to the right edge).
+    gdouble animate_delta = superbuf_hscale->animate_delta;
+    gint delta = 0;
+    gint image_width = tile_graphics_private->image_width;
+    gint image_height = tile_graphics_private->image_height;
+    gint tile_width = tile_graphics_private->tile_width;
+    GdkGC *gc = superbuf_hscale->gc;
+    GdkBitmap *tile_mask = superbuf_hscale->tile_mask;
+    GdkGC *tile_mask_gc = superbuf_hscale->tile_mask_gc;
+    gint tile_mask_width = superbuf_hscale->tile_mask_width;
+    gint tile_mask_height = superbuf_hscale->trough_height;
+    GdkGC *tile_mid_section_gc = superbuf_hscale->tile_mid_section_gc;
 
     g_return_if_fail(GTK_IS_WIDGET(widget));
-    g_return_if_fail(graphic);
-    g_return_if_fail(GDK_IS_PIXBUF(graphic->pixbuf));
-    // right_align mode doesn't support leading and trailing non-tileable pixels 
-    // in this implementation.
-    g_return_if_fail(!graphic->right_align || 
-        (!graphic->tile_leading_pixels && !graphic->tile_trailing_pixels) );
 
+    switch(superbuffer_graphic)
+    {
+    case HX_SUPERB_BG:
+        layout_rect = &layout->trough_rect;
+        break;
 
-    image_width = gdk_pixbuf_get_width(graphic->pixbuf);
-    tile_width = image_width - graphic->tile_leading_pixels - graphic->tile_trailing_pixels;
-    g_return_if_fail(tile_width >= 0);
+    case HX_SUPERB_NON_SUPERBUFFERED:
+    case HX_SUPERB_ONDEMAND:
+        layout_rect = &layout->fg_graphic_rect;
+        break;
 
-    image_height = tile_height = gdk_pixbuf_get_height(graphic->pixbuf);
+    case HX_SUPERB_LIVE:
+        layout_rect = &layout->live_tile_rect;
+        break;
 
-    center_delta = MAX((dest_rect->height - image_height)/2, 0);  // Clamp to positive values.
+    default:
+        g_assert(!"Bad HX_SUPERB superbuffer_graphic value!");
+        break;
+    }
 
-    // Compute delta to align image on the right of the rectangle.
-    if (graphic->right_align)
+    if (layout_rect->width <= 0 || layout_rect->height <= 0)
     {
-        align_delta = tile_width - dest_rect->width % tile_width;
+        return;
     }
 
-    gc = gc_in ? gc_in : gdk_gc_new(widget->window); 
-    g_assert(gc);
-    gdk_gc_copy(gc, widget->style->black_gc); 
-
-    // Generate tile pixmap before changing gc.
-    tile_pixmap = gdk_pixmap_new(widget->window, 
-        tile_width,
-        tile_height,
-        -1);            // depth
-
-    g_assert(tile_pixmap);
-
-    gdk_draw_pixbuf(tile_pixmap, 
-                    gc, 
-                    graphic->pixbuf, 
-                    graphic->tile_leading_pixels,            // src_x
-                    0,                                       // src_y
-                    0, 0,                                    // dest_x, dest_y,
-                    tile_width, tile_height,
-                    GDK_RGB_DITHER_NONE,
-                    0, 0);                                   // x_dither, y_dither.
+    center_delta = MAX((layout_rect->height - image_height)/2, 0);  // Clamp to positive values.
 
+    // Draw leading graphic to window.
     if (graphic->tile_leading_pixels)
     {
-        // Draw leading graphic.
-        clip_rect.x = dest_rect->x;
-        clip_rect.y = dest_rect->y + center_delta; 
-        clip_rect.width = MIN(graphic->tile_leading_pixels, dest_rect->width);  // Clip to within dest_rect!
+        clip_rect.x = widget->allocation.x + layout_rect->x;
+        clip_rect.y = widget->allocation.y + layout_rect->y + center_delta; 
+        clip_rect.width = MIN(graphic->tile_leading_pixels, layout_rect->width);  // Clip to within layout_rect!
         clip_rect.height = image_height;
-        gdk_gc_set_fill(gc, GDK_SOLID);
         gdk_gc_set_clip_rectangle(gc, &clip_rect);
 
-        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() leading graphic clip_rect.x=%d, clip_rect.width=%d", clip_rect.x, clip_rect.width);
+        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() leading graphic clip_rect={%d, %d, %d, %d}", clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
         gdk_draw_pixbuf(widget->window, 
                         gc,
                         graphic->pixbuf, 
@@ -1117,102 +1321,93 @@
 
 
     // Mid section to be tiled.
-    clip_rect.x = dest_rect->x + graphic->tile_leading_pixels;
-    clip_rect.y = dest_rect->y + center_delta; 
-    clip_rect.width = dest_rect->width - graphic->tile_leading_pixels - graphic->tile_trailing_pixels;
+    clip_rect.x = widget->allocation.x + layout_rect->x + graphic->tile_leading_pixels;
+    clip_rect.y = widget->allocation.y + layout_rect->y + center_delta; 
+    clip_rect.width = layout_rect->width - graphic->tile_leading_pixels - graphic->tile_trailing_pixels;
     clip_rect.height = image_height;
 
+    HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() Mid section clip_rect={%d, %d, %d, %d}", 
+            clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
+
+    // Compute delta to align image on the right of the rectangle.
+    if (graphic->right_align)
+    {
+        align_delta = tile_width - layout_rect->width % tile_width;
+        delta = (gint) (-align_delta - animate_delta);
+
+        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() align_delta = %d, delta=%d", align_delta, delta);
+    }
+
+
     // Generate tile mask bitmap - by tiling tile bitmap
     if (clip_rect.width > 0)
     {
         // Generate tile bitmap - from pixbuf
-        tile_bitmap = gdk_pixmap_new(widget->window, 
-                                     tile_width,
-                                     tile_height,
-                                     1);            // depth
-        g_assert(tile_bitmap);
-        gdk_pixbuf_render_threshold_alpha(graphic->pixbuf,
-                                          tile_bitmap,
-                                          graphic->tile_leading_pixels, 0,   // src_x, src_y
-                                          0, 0,                              // dest_x, dest_y
-                                          tile_width, tile_height,
-                                          127);                              // alpha_threshold
 
-        tile_mask = gdk_pixmap_new (widget->window, clip_rect.width, clip_rect.height, 1);
-        g_assert(tile_mask);
-        tile_mask_gc = gdk_gc_new(tile_mask); 
-        g_assert(tile_mask_gc);
+        // There is only one shared tile_mask_gc among all graphics, but tile_bitmap isn't shared. 
+        gdk_gc_set_tile(tile_mask_gc, tile_graphics_private->tile_bitmap);
+        gdk_gc_set_clip_rectangle(tile_mask_gc, NULL);
 
-        gdk_gc_set_fill(tile_mask_gc, GDK_TILED);
-        gdk_gc_set_tile(tile_mask_gc, tile_bitmap);
-        gdk_gc_set_ts_origin(tile_mask_gc, -align_delta - animate_delta, 0);  // Align tile_mask.
+        // gdk_gc_set_fill(tile_mask_gc, GDK_TILED) was set in size_allocate().
 
-        // Generate tile mask
-        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() tile mask dest_rect->width=%d", dest_rect->width);
+        // Align x coord. of tile_mask. 
+        gdk_gc_set_ts_origin(tile_mask_gc, delta, 0);
+
+        // Generate the (tile) mask (using ts origin information in tile_mask_gc.)
+        // To be optimized, keep this drawing operation in expose(), and only when mapped.
+        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() tile mask layout_rect={0, 0, %d, %d} animate_delta=%d", layout_rect->width, layout_rect->height, animate_delta);
+        // Generate tile mask.
         gdk_draw_rectangle(tile_mask, 
                            tile_mask_gc,
                            TRUE,            // Filled?
                            0, 0, 
-                           dest_rect->width, dest_rect->height);
-        g_object_unref(tile_mask_gc);
-        tile_mask_gc = NULL;
-        g_object_unref(tile_bitmap);
-        tile_bitmap = NULL;
+                           tile_mask_width, tile_mask_height);
 
-        gdk_gc_set_fill(gc, GDK_TILED);
-        gdk_gc_set_tile(gc, tile_pixmap);
-        gdk_gc_set_ts_origin(gc, clip_rect.x - align_delta - animate_delta, clip_rect.y);  // Align tile.
+        //gdk_gc_set_fill(tile_mid_section_gc, GDK_TILED) was set in realize().
+        gdk_gc_set_tile(tile_mid_section_gc, tile_graphics_private->tile_pixmap);
+        gdk_gc_set_ts_origin(tile_mid_section_gc,                                   // Align tile.
+                             clip_rect.x + delta, 
+                             clip_rect.y);
 
-        gdk_gc_set_clip_rectangle(gc, &clip_rect);
-        gdk_gc_set_clip_mask(gc, tile_mask);
-        gdk_gc_set_clip_origin(gc, clip_rect.x, clip_rect.y);  // tile_mask has already been adjusted to align.
+        gdk_gc_set_clip_rectangle(tile_mid_section_gc, NULL);
+        gdk_gc_set_clip_mask(tile_mid_section_gc, tile_mask);
+        gdk_gc_set_clip_origin(tile_mid_section_gc, 
+                               clip_rect.x,   // tile_mask x-coord has already been adjusted to align.
+                               clip_rect.y);
 
         // Draw tile
-        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() draw tile clip_rect.x=%d, clip_rect.width=%d", clip_rect.x, clip_rect.width);
+        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() draw mid section tile clip_rect={%d, %d, %d, %d}", clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
         gdk_draw_rectangle(widget->window,
-                           gc,
+                           tile_mid_section_gc,
                            TRUE,           // Filled?
                            clip_rect.x, 
                            clip_rect.y,
                            clip_rect.width, 
                            clip_rect.height);
-        g_object_unref(tile_mask); 
-        tile_mask = NULL;
-
-        // free tile pixmap.
-        g_object_unref(tile_pixmap); 
-        tile_pixmap = NULL;
     }
 
     if (graphic->tile_trailing_pixels)
     {
-        // Draw trailing graphic.
-        clip_rect.width = MIN(graphic->tile_trailing_pixels, dest_rect->width); // Clip to within dest_rect!
-        clip_rect.x = dest_rect->x + dest_rect->width - clip_rect.width;        // Clip to within dest_rect!
-        clip_rect.y = dest_rect->y + center_delta; 
+        // Draw trailing graphic to window.
+        clip_rect.width = MIN(graphic->tile_trailing_pixels, layout_rect->width); // Clip to within layout_rect!
+        clip_rect.x = widget->allocation.x + layout_rect->x + layout_rect->width - clip_rect.width;        // Clip to within layout_rect!
+        clip_rect.y = widget->allocation.y + layout_rect->y + center_delta; 
         clip_rect.height = image_height;
-        gdk_gc_set_fill(gc, GDK_SOLID);
         gdk_gc_set_clip_rectangle(gc, &clip_rect);
-        gdk_gc_set_clip_mask(gc, NULL);
 
-        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() trailing graphic clip_rect.x=%d, clip_rect.width=%d", clip_rect.x, clip_rect.width);
+        HXLOGL4(HXLOG_TLCX, "draw_tile_graphic() trailing graphic clip_rect={%d, %d, %d, %d}", clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
         gdk_draw_pixbuf(widget->window, 
                         gc,
                         graphic->pixbuf, 
-                        image_width - clip_rect.width,                  // src_x; clip to within dest_rect!
+                        image_width - clip_rect.width,                  // src_x; clip to within layout_rect!
                         0,                                              // src_y
                         clip_rect.x, clip_rect.y,                       // dest_x, dest_y,
                         clip_rect.width, clip_rect.height,
                         GDK_RGB_DITHER_NONE,
                         0, 0);                                          // x_dither, y_dither.
     }    
-    gdk_gc_set_clip_rectangle(gc, NULL);
 
-    if (!gc_in) // Don't unref passed-in gc.
-    {
-        g_object_unref(gc);
-    }
-    gc = NULL;
+    return;
 }
 
 
@@ -1222,85 +1417,36 @@
 {
     HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
     HXSuperbufHScaleLayout *layout = &superbuf_hscale->layout;
+    GdkGC *gc = superbuf_hscale->gc;
     GtkStateType state_type;
 
     GdkRectangle clip_rect;
-    TileGraphic *buffer_graphic = NULL;
-    gboolean draw_background_track = TRUE;
-    gboolean draw_buffer_track = FALSE;
-    gboolean draw_live_track = FALSE;
-    GdkGC *gc = NULL;
-
-    switch (superbuf_hscale->buffer_mode)
-    {
-    case HX_SUPERB_MODE_BG:
-        draw_background_track = TRUE;
-        draw_buffer_track = FALSE;
-        draw_live_track = FALSE;
-        break;
-    case HX_SUPERB_MODE_NON_SUPERB:
-        draw_background_track = FALSE;
-        draw_buffer_track = TRUE;
-        draw_live_track = FALSE;
-        buffer_graphic = &superbuf_hscale->tile_graphics[HX_SUPERB_MODE_NON_SUPERB];
-        break;
-    case HX_SUPERB_MODE_ONDEMAND:
-        draw_background_track = TRUE;
-        draw_buffer_track = TRUE;
-        draw_live_track = FALSE;
-        buffer_graphic = &superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND];
-        break;
-    case HX_SUPERB_MODE_LIVE:
-        draw_background_track = TRUE;
-        draw_buffer_track = TRUE;
-        draw_live_track = TRUE;
-        buffer_graphic = &superbuf_hscale->tile_graphics[HX_SUPERB_MODE_ONDEMAND]; // ondemand is drawn in live too.
-        break;
-    default:
-        g_assert(!"Unknown superbuffer mode!");
-    }
 
-    if (layout->trough_rect.width == 0 || layout->trough_rect.height == 0)
-    {
-        // Not drawing trough.
-        return FALSE;
-    }
-
-    gc = gdk_gc_new(widget->window);    // Create for slider (thumb.)
-    g_assert(gc);
+    g_assert(GTK_WIDGET_MAPPED(widget));
 
     // Draw background track if it is not entirely covered.
-    if (layout->fg_tile_rect.x > layout->trough_rect.x || 
-        layout->fg_tile_rect.width < layout->trough_rect.width )
+    if (layout->fg_graphic_rect.x > layout->trough_rect.x || 
+        layout->fg_graphic_rect.width < layout->trough_rect.width )
     {
-        clip_rect.x = widget->allocation.x + layout->trough_rect.x;
-        clip_rect.y = widget->allocation.y + layout->trough_rect.y;
-        clip_rect.width = layout->trough_rect.width;
-        clip_rect.height = layout->trough_rect.height;
-        draw_tile_graphic(widget, gc, &superbuf_hscale->tile_graphics[HX_SUPERB_MODE_BG], &clip_rect, 0); 
+        hx_superbuf_hscale_draw_tile_graphic(widget, 
+                                             HX_SUPERB_BG);         // Draw background graphic.
     }
 
     // Draw buffered track.
-    if (draw_buffer_track && layout->fg_tile_rect.width)
+    if (layout->draw_buffer_track)
     {
-        clip_rect.x = widget->allocation.x + layout->fg_tile_rect.x;
-        clip_rect.y = widget->allocation.y + layout->fg_tile_rect.y;
-        clip_rect.width = layout->fg_tile_rect.width;
-        clip_rect.height = layout->fg_tile_rect.height;
-        draw_tile_graphic(widget, gc, &superbuf_hscale->tile_graphics[layout->fg_tile], &clip_rect, 0); 
+        hx_superbuf_hscale_draw_tile_graphic(widget, 
+                                             layout->fg_graphic);   // Draw foreground graphic.
     }
 
     // Draw live track.
-    if (draw_live_track && layout->live_tile_rect.width)
+    if (layout->draw_live_track && layout->live_tile_rect.width)
     {
-        clip_rect.x = widget->allocation.x + layout->live_tile_rect.x;
-        clip_rect.y = widget->allocation.y + layout->live_tile_rect.y;
-        clip_rect.width = layout->live_tile_rect.width;
-        clip_rect.height = layout->live_tile_rect.height;
-        draw_tile_graphic(widget, gc, &superbuf_hscale->tile_graphics[HX_SUPERB_MODE_LIVE], &clip_rect, 
-            (gint)superbuf_hscale->animate_delta); 
+        hx_superbuf_hscale_draw_tile_graphic(widget, 
+                                             HX_SUPERB_LIVE);       // Draw live graphic.
     }
 
+    gdk_gc_set_clip_rectangle(gc, NULL);
 
     // Draw slider (thumb)
     clip_rect.x = widget->allocation.x + layout->slider_rect.x; 
@@ -1497,12 +1643,8 @@
 hx_superbuf_hscale_enter_notify_event(GtkWidget *widget, GdkEventCrossing *event)
 {
     g_return_val_if_fail(GTK_IS_WIDGET(widget), TRUE);
-    HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(widget);
 
     gtk_widget_set_state(widget, GTK_STATE_PRELIGHT);
-    hx_superbuf_hscale_calc_allocation(superbuf_hscale, 
-                                       &superbuf_hscale->layout, 
-                                       &widget->allocation);
 
     return FALSE; 
 }
@@ -1892,7 +2034,6 @@
     hx_superbuf_hscale_calc_allocation(superbuf_hscale, 
                                        &superbuf_hscale->layout, 
                                        &widget->allocation);
-    hx_superbuf_hscale_layout_slider(superbuf_hscale);
 }
 
 void

Index: guids.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/guids.cpp,v
retrieving revision 1.16
retrieving revision 1.16.6.1
diff -u -d -r1.16 -r1.16.6.1
--- guids.cpp	17 Dec 2007 23:15:36 -0000	1.16
+++ guids.cpp	10 Oct 2008 08:04:19 -0000	1.16.6.1
@@ -73,6 +73,7 @@
 #include "ihxlist.h"
 #include "hxdtdr.h"
 #include "hxtbuf.h"
+#include "hxwintyp.h"
 
 // From common/include/hxsrcin.h (which includes ihxpckts.h, and thus cannot be included here directly)
 DEFINE_GUID(IID_IHXSourceInput, 0xebf8d220, 0x40f7, 0x11d6, 0xab, 0x3f, 0x0, 0x1, 0x2, 0x51, 0xb3, 0x40);

Index: hxstatuspositionslider.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/hxstatuspositionslider.cpp,v
retrieving revision 1.25.2.1
retrieving revision 1.25.2.1.2.1
diff -u -d -r1.25.2.1 -r1.25.2.1.2.1
--- hxstatuspositionslider.cpp	25 Feb 2008 01:27:23 -0000	1.25.2.1
+++ hxstatuspositionslider.cpp	10 Oct 2008 08:04:19 -0000	1.25.2.1.2.1
@@ -263,7 +263,7 @@
                                                                       &maxPosition);
             if (is_live_or_infinite)
             {
-                superbuf_hscale->buffer_mode = HX_SUPERB_MODE_LIVE;
+                hx_superbuf_hscale_set_mode(superbuf_hscale, HX_SUPERB_LIVE);
                 superbuf_hscale->restrict_seek_in_buffered = TRUE;
                 if (maxBuffered == maxPosition)
                 {
@@ -276,7 +276,7 @@
             else
             {
                 // Superbuffer enabled and not live == OnDemand.
-                superbuf_hscale->buffer_mode = HX_SUPERB_MODE_ONDEMAND;
+                hx_superbuf_hscale_set_mode(superbuf_hscale, HX_SUPERB_ONDEMAND);
                 superbuf_hscale->restrict_seek_in_buffered = FALSE;
                 superbuf_hscale->live_background_moved = 0;
                 hx_superbuf_stop_animation(superbuf_hscale);
@@ -295,7 +295,7 @@
         else if (is_live_or_infinite)
         {
             // Superbuffer disabled and live.
-            superbuf_hscale->buffer_mode = HX_SUPERB_MODE_NON_SUPERB;
+            hx_superbuf_hscale_set_mode(superbuf_hscale, HX_SUPERB_NON_SUPERBUFFERED);
             superbuf_hscale->live_background_moved = 0;
             hx_superbuf_stop_animation(superbuf_hscale);
         }
@@ -304,7 +304,7 @@
             // Also non-superbuffer case.
             len = hx_basic_playback_get_length(status->player);
 
-            superbuf_hscale->buffer_mode = HX_SUPERB_MODE_NON_SUPERB;
+            hx_superbuf_hscale_set_mode(superbuf_hscale, HX_SUPERB_NON_SUPERBUFFERED);
             superbuf_hscale->live_background_moved = 0;
             hx_superbuf_stop_animation(superbuf_hscale);
 
@@ -570,7 +570,7 @@
     HXSuperbufHScale *superbuf_hscale = HX_SUPERBUF_HSCALE(position_status->position_scale);
     g_return_if_fail(superbuf_hscale); 
     hx_superbuf_stop_animation(superbuf_hscale);
-    superbuf_hscale->buffer_mode = HX_SUPERB_MODE_BG;
+    hx_superbuf_hscale_set_mode(superbuf_hscale, HX_SUPERB_BG);
 
     hx_superbuf_hscale_set(superbuf_hscale, 
                            0.0,         // value

Index: commonapp.cpp
===================================================================
RCS file: /cvsroot/player/app/gtk/commonapp.cpp,v
retrieving revision 1.97.2.1.2.1
retrieving revision 1.97.2.1.2.2
diff -u -d -r1.97.2.1.2.1 -r1.97.2.1.2.2
--- commonapp.cpp	24 Apr 2008 10:13:48 -0000	1.97.2.1.2.1
+++ commonapp.cpp	10 Oct 2008 08:04:19 -0000	1.97.2.1.2.2
@@ -1000,7 +1000,7 @@
         else
         {
             int c = ' ';
-            sscanf(src_pos, "%02x", &c);
+            sscanf(src_pos+1, "%02x", &c);
             *dest_pos++ = (gchar)c;
             src_pos += 3;
         }

Index: superbufhscale.h
===================================================================
RCS file: /cvsroot/player/app/gtk/superbufhscale.h,v
retrieving revision 1.4.10.1
retrieving revision 1.4.10.1.2.1
diff -u -d -r1.4.10.1 -r1.4.10.1.2.1
--- superbufhscale.h	25 Feb 2008 01:27:23 -0000	1.4.10.1
+++ superbufhscale.h	10 Oct 2008 08:04:19 -0000	1.4.10.1.2.1
@@ -52,16 +52,19 @@
 
 G_BEGIN_DECLS
 
+#include <gdk/gdkpixmap.h>
+
 
+// HX_SUPERB is used for both Superbuffer mode and Superbuffer graphics.
 typedef enum 
 {
-    HX_SUPERB_MODE_NIL = -1,        // Not a Buffer Mode.
-    HX_SUPERB_MODE_BG,              // Corresponds to original track.png
-    HX_SUPERB_MODE_NON_SUPERB,      // Corresponds to original postrack.png
-    HX_SUPERB_MODE_ONDEMAND,        // Corresponds to original trackmask.png
-    HX_SUPERB_MODE_LIVE,            // Corresponds to original superbuffertile.png
-    HX_SUPERB_MODE_LAST             // Number of Buffer Modes.
-} HX_SUPERB_MODE;
+    HX_SUPERB_NIL = -1,             // Not a Buffer Mode.
+    HX_SUPERB_BG,                   // Corresponds to original track.png
+    HX_SUPERB_NON_SUPERBUFFERED,    // Corresponds to original postrack.png
+    HX_SUPERB_ONDEMAND,             // Corresponds to original trackmask.png
+    HX_SUPERB_LIVE,                 // Corresponds to original superbuffertile.png
+    HX_SUPERB_LAST                  // Number of Buffer Modes.
+} HX_SUPERB; 
 
 
 
@@ -76,6 +79,17 @@
     gboolean right_align;           // Align to the right edge of the display rectangle. Default to FALSE (left alignment.)
 } TileGraphic;
 
+typedef struct _HXTileGraphicPrivate
+{
+    // These resources are not shared among graphics.
+    GdkPixmap *tile_pixmap;
+    GdkBitmap *tile_bitmap;
+
+    gint image_width;
+    gint image_height;
+    gint tile_width;
+} HXTileGraphicPrivate;
+
 typedef struct _SliderGraphics
 {
     GdkPixbuf *pixbuf;
@@ -95,18 +109,21 @@
 {
     GdkRectangle scale_rect;    // HScale region excluding borders.
 
-    // Also used as tile_graphics[HX_SUPERB_MODE_BG] layout.
+    // Layout information for tile_graphics[HX_SUPERB_BG].
     GdkRectangle trough_rect;   
 
-    // Used for tile_graphics[one of HX_SUPERB_MODE_ONDEMAND or HX_SUPERB_MODE_ONDEMAND] layout.
-    GdkRectangle fg_tile_rect;  
-    HX_SUPERB_MODE fg_tile;     // Points to either HX_SUPERB_MODE_ONDEMAND or HX_SUPERB_MODE_ONDEMAND.
+    // Layout information for tile_graphics[fg_graphic].
+    GdkRectangle fg_graphic_rect;  
+    HX_SUPERB    fg_graphic;    // Points to either HX_SUPERB_NON_SUPERBUFFERED or HX_SUPERB_ONDEMAND.
 
-    // Used for tile_graphics[HX_SUPERB_MODE_LIVE] layout.
+    // Used for tile_graphics[HX_SUPERB_LIVE] layout.
     GdkRectangle live_tile_rect; 
 
     GdkRectangle slider_rect;   // Slider (thumb.)
 
+    gint buffer_min_x; 
+    gint buffer_max_x;
+
     GdkRectangle buffer_start_arrow;            // (x, y) are arrow tip.
     GdkRectangle buffer_start_arrow_clip_rect;  // end_arrow/label might shadow start_arrow.
     // Typically, only (x, y) are used. If width is smaller than actual label width,
@@ -118,6 +135,9 @@
 
     GdkRectangle slider_label;
 
+    gboolean draw_buffer_track;
+    gboolean draw_live_track;
+
 } HXSuperbufHScaleLayout;
 
 
@@ -152,11 +172,12 @@
 
     guint arrow_size;
 
-    HX_SUPERB_MODE buffer_mode;
+    HX_SUPERB buffer_mode;
     gdouble live_background_moved;  // Shift of adjustment->lower in scale (timeline) unit.
 
-    TileGraphic tile_graphics[HX_SUPERB_MODE_LAST];
-    guint trough_height;                    // Fixed max. height computed from graphics.
+    TileGraphic          tile_graphics[HX_SUPERB_LAST];
+    HXTileGraphicPrivate tile_graphics_private[HX_SUPERB_LAST];
+    guint trough_height;                    // Fixed max. image height computed from graphics.
     guint trough_min_width;                 // Min. width; Width not fixed.
 
     SliderGraphics slider_graphics;         // Corresponds to posthumb.png
@@ -167,6 +188,23 @@
     guint timeoutid;
     HXSuperbufHScaleLayout layout;
 
+    // These resources are shared by all graphics.
+    // GC cache used in *draw_tile_graphic() for all leading, mid-section and trailing graphics.
+    GdkGC *gc;
+
+    // GC cache used in *draw_tile_graphic() for mid-section tile only.
+    GdkGC *tile_mask_gc;        // For tile mask.
+    GdkGC *tile_mid_section_gc; // For tile itself.
+
+    // Tile mask itself doesn't tile, so (tile) mask needs to be allocated for the whole allocated width.
+    // Because tile mask doesn't tile, it doesn't need to be the exact size, but just need to be
+    // large enough for the graphic's mid section.
+    // Unlike tile_pixmap, etc., there is only one tile_mask (of the max width needed for mask) 
+    // shared by all TileGraphics.
+    GdkBitmap *tile_mask;
+    // Current width of tile_mask = max width suitable for use with all tile operations 
+    // shared with all Superbuffer graphics.
+    gint tile_mask_width;
 } HXSuperbufHScale;
 
 typedef struct _HXSuperbufHScaleClass
@@ -206,6 +244,7 @@
 
 GType      hx_superbuf_hscale_get_type (void) G_GNUC_CONST;
 
+void hx_superbuf_hscale_set_mode(HXSuperbufHScale *superbuf_hscale, HX_SUPERB superbuffer_mode);
 GtkWidget* hx_superbuf_hscale_new_with_range (gdouble min, gdouble max, gdouble step);
 void hx_superbuf_start_animation(HXSuperbufHScale *superbuf_hscale);
 void hx_superbuf_stop_animation(HXSuperbufHScale *superbuf_hscale);




More information about the Player-cvs mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.