[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.orgUpdate 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);