changeset 2980:d58560be5a4c trunk

draw directly instead using embeded GtkImage
author Tomasz Mon <desowin@gmail.com>
date Wed, 04 Jul 2007 16:35:27 +0200
parents 2d91fa378e45
children 3bd337a93c9d df71b1cef70a
files src/audacious/ui_main.c src/audacious/ui_playlist.c src/audacious/ui_skinned_textbox.c src/audacious/ui_skinned_textbox.h
diffstat 4 files changed, 396 insertions(+), 481 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/ui_main.c	Tue Jul 03 21:20:09 2007 -0500
+++ b/src/audacious/ui_main.c	Wed Jul 04 16:35:27 2007 +0200
@@ -2833,25 +2833,23 @@
     g_signal_connect(mainwin_pl, "clicked", mainwin_playlist_pushed_cb, NULL);
     UI_SKINNED_BUTTON(mainwin_pl)->inside = cfg.playlist_visible;
 
-    mainwin_info = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_info, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 112, 27,
+    mainwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 112, 27,
                              153, 1, SKIN_TEXT);
+    gtk_fixed_put(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_info, 112, 27);
     ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
     ui_skinned_textbox_set_xfont(mainwin_info, cfg.mainwin_use_xfont, cfg.mainwin_font);
     g_signal_connect(mainwin_info, "double-clicked", mainwin_info_double_clicked_cb, NULL);
     g_signal_connect(mainwin_info, "right-clicked", mainwin_info_right_clicked_cb, NULL);
 
-    mainwin_othertext = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_othertext, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 112, 43,
+    mainwin_othertext = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 112, 43,
                              153, 1, SKIN_TEXT);
-
-    mainwin_rate_text = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_rate_text, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 111, 43, 15,
+    gtk_fixed_put(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_othertext, 112, 43);
+    mainwin_rate_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 111, 43, 15,
                              0, SKIN_TEXT);
-
-    mainwin_freq_text = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_freq_text, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 156, 43, 10,
+    gtk_fixed_put(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_rate_text, 111, 43);
+    mainwin_freq_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 156, 43, 10,
                             0, SKIN_TEXT);
+    gtk_fixed_put(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_freq_text, 156, 43);
 
     mainwin_menurow =
         create_menurow(&mainwin_wlist, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 10, 22, 304,
@@ -2927,13 +2925,11 @@
                        mainwin_spos_release_cb, SKIN_TITLEBAR);
     widget_hide(WIDGET(mainwin_sposition));
 
-    mainwin_stime_min = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_stime_min, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 130, 4, 15,
+    mainwin_stime_min = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 130, 4, 15,
                        FALSE, SKIN_TEXT);
     g_signal_connect(mainwin_stime_min, "clicked", change_timer_mode, NULL);
 
-    mainwin_stime_sec = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(mainwin_stime_sec, SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 147, 4, 10,
+    mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, mainwin_bg, SKINNED_WINDOW(mainwin)->gc, 147, 4, 10,
                        FALSE, SKIN_TEXT);
     g_signal_connect(mainwin_stime_sec, "clicked", change_timer_mode, NULL);
 
--- a/src/audacious/ui_playlist.c	Tue Jul 03 21:20:09 2007 -0500
+++ b/src/audacious/ui_playlist.c	Wed Jul 04 16:35:27 2007 +0200
@@ -1558,8 +1558,7 @@
     /* This function creates the custom widgets used by the playlist editor */
 
     /* text box for displaying song title in shaded mode */
-    playlistwin_sinfo = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(playlistwin_sinfo, SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
+    playlistwin_sinfo = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
                              4, 4, playlistwin_get_width() - 35, TRUE, SKIN_TEXT);
 
     playlistwin_set_sinfo_font(cfg.playlist_font);
@@ -1604,20 +1603,17 @@
     ui_skinned_window_widgetlist_associate(playlistwin, WIDGET(playlistwin_slider));
 
     /* track time (minute) */
-    playlistwin_time_min = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(playlistwin_time_min, SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
+    playlistwin_time_min = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
                        playlistwin_get_width() - 82,
                        cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT);
 
     /* track time (second) */
-    playlistwin_time_sec = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(playlistwin_time_sec, SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
+    playlistwin_time_sec = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
                        playlistwin_get_width() - 64,
                        cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT);
 
     /* playlist information (current track length / total track length) */
-    playlistwin_info = ui_skinned_textbox_new();
-    ui_skinned_textbox_setup(playlistwin_info, SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
+    playlistwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_bg, SKINNED_WINDOW(playlistwin)->gc,
                        playlistwin_get_width() - 143,
                        cfg.playlist_height - 28, 90, FALSE, SKIN_TEXT);
 
--- a/src/audacious/ui_skinned_textbox.c	Tue Jul 03 21:20:09 2007 -0500
+++ b/src/audacious/ui_skinned_textbox.c	Wed Jul 04 16:35:27 2007 +0200
@@ -33,10 +33,10 @@
 #include <gtk/gtkmarshal.h>
 #include <gtk/gtkimage.h>
 
-#define UI_SKINNED_TEXTBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UI_TYPE_SKINNED_TEXTBOX, UiSkinnedTextboxPrivate))
-typedef struct _UiSkinnedTextboxPrivate UiSkinnedTextboxPrivate;
+static GMutex *mutex = NULL;
 
-static GMutex *mutex = NULL;
+#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT  30
+#define TEXTBOX_SCROLL_WAIT            80
 
 enum {
     CLICKED,
@@ -47,107 +47,65 @@
     LAST_SIGNAL
 };
 
-struct _UiSkinnedTextboxPrivate {
-    GtkWidget        *image;
-    GdkGC            *gc;
-    SkinPixmapId     skin_index;
-    GtkWidget        *fixed;
-    gboolean         double_size;
-    gboolean         scroll_back;
-    gint             nominal_y, nominal_height;
-    gint             scroll_timeout;
-    gint             font_ascent, font_descent;
-    PangoFontDescription *font;
-    gchar            *fontname;
-    gchar            *pixmap_text;
-    gint             skin_id;
-    gint             drag_x, drag_off, offset;
-    gboolean         is_scrollable, is_dragging;
-    gint             pixmap_width;
-    GdkPixmap        *pixmap;
-    gboolean         scroll_allowed, scroll_enabled;
-    gint             scroll_dummy;
-    gint             resize_width, resize_height;
-    gint             move_x, move_y;
-};
-
+static void ui_skinned_textbox_class_init         (UiSkinnedTextboxClass *klass);
+static void ui_skinned_textbox_init               (UiSkinnedTextbox *textbox);
+static void ui_skinned_textbox_destroy            (GtkObject *object);
+static void ui_skinned_textbox_realize            (GtkWidget *widget);
+static void ui_skinned_textbox_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_textbox_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_textbox_expose         (GtkWidget *widget, GdkEventExpose *event);
+static gboolean ui_skinned_textbox_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_textbox_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_textbox_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static void ui_skinned_textbox_toggle_doublesize  (UiSkinnedTextbox *textbox);
+static void ui_skinned_textbox_redraw             (UiSkinnedTextbox *textbox);
+static gboolean ui_skinned_textbox_should_scroll  (UiSkinnedTextbox *textbox);
+static void textbox_generate_xfont_pixmap         (UiSkinnedTextbox *textbox, const gchar *pixmaptext);
+static gboolean textbox_scroll                    (gpointer data);
+static void textbox_generate_pixmap               (UiSkinnedTextbox *textbox);
+static void textbox_handle_special_char           (gchar c, gint * x, gint * y);
 
-static GtkBinClass *parent_class = NULL;
-static void ui_skinned_textbox_class_init(UiSkinnedTextboxClass *klass);
-static void ui_skinned_textbox_init(UiSkinnedTextbox *textbox);
-static GObject* ui_skinned_textbox_constructor(GType type, guint n_construct_properties, GObjectConstructParam *construct_params);
-static void ui_skinned_textbox_destroy(GtkObject *object);
-static void ui_skinned_textbox_realize(GtkWidget *widget);
-static void ui_skinned_textbox_unrealize(GtkWidget *widget);
-static void ui_skinned_textbox_map(GtkWidget *widget);
-static void ui_skinned_textbox_unmap(GtkWidget *widget);
-static gint ui_skinned_textbox_expose(GtkWidget *widget,GdkEventExpose *event);
-
-static void ui_skinned_textbox_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
-
+static GtkWidgetClass *parent_class = NULL;
 static guint textbox_signals[LAST_SIGNAL] = { 0 };
-static gint ui_skinned_textbox_textbox_press(GtkWidget *widget, GdkEventButton *event);
-static gint ui_skinned_textbox_textbox_release(GtkWidget *widget, GdkEventButton *event);
 
-static void ui_skinned_textbox_add(GtkContainer *container, GtkWidget *widget);
-static void ui_skinned_textbox_toggle_doublesize(UiSkinnedTextbox *textbox);
-
-static gint ui_skinned_textbox_motion_notify(GtkWidget *widget, GdkEventMotion *event);
-static void ui_skinned_textbox_paint(UiSkinnedTextbox *textbox);
-static void ui_skinned_textbox_redraw(UiSkinnedTextbox *textbox);
-static gboolean ui_skinned_textbox_should_scroll(UiSkinnedTextbox *textbox);
-static void textbox_generate_xfont_pixmap(UiSkinnedTextbox *textbox, const gchar *pixmaptext);
-static void textbox_generate_pixmap(UiSkinnedTextbox *textbox);
-static void textbox_handle_special_char(gchar c, gint * x, gint * y);
-
-GType ui_skinned_textbox_get_type (void) {
+GType ui_skinned_textbox_get_type() {
     static GType textbox_type = 0;
-
     if (!textbox_type) {
         static const GTypeInfo textbox_info = {
             sizeof (UiSkinnedTextboxClass),
-            NULL,                /* base_init */
-            NULL,                /* base_finalize */
+            NULL,
+            NULL,
             (GClassInitFunc) ui_skinned_textbox_class_init,
-            NULL,                /* class_finalize */
-            NULL,                /* class_data */
+            NULL,
+            NULL,
             sizeof (UiSkinnedTextbox),
-            16,                /* n_preallocs */
+            0,
             (GInstanceInitFunc) ui_skinned_textbox_init,
         };
+        textbox_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedTextbox", &textbox_info, 0);
+    }
 
-        textbox_type = g_type_register_static (GTK_TYPE_BIN, "UiSkinnedTextbox", &textbox_info, 0);
-    }
     return textbox_type;
 }
 
-static void ui_skinned_textbox_class_init (UiSkinnedTextboxClass *klass) {
-    GObjectClass *gobject_class;
+static void ui_skinned_textbox_class_init(UiSkinnedTextboxClass *klass) {
     GtkObjectClass *object_class;
     GtkWidgetClass *widget_class;
-    GtkContainerClass *container_class;
 
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*)klass;
-    widget_class = (GtkWidgetClass*)klass;
-    container_class = (GtkContainerClass*)klass;
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
 
-    parent_class = g_type_class_peek_parent(klass);
-    gobject_class->constructor = ui_skinned_textbox_constructor;
     object_class->destroy = ui_skinned_textbox_destroy;
 
     widget_class->realize = ui_skinned_textbox_realize;
-    widget_class->unrealize = ui_skinned_textbox_unrealize;
-    widget_class->map = ui_skinned_textbox_map;
-    widget_class->unmap = ui_skinned_textbox_unmap;
+    widget_class->expose_event = ui_skinned_textbox_expose;
+    widget_class->size_request = ui_skinned_textbox_size_request;
     widget_class->size_allocate = ui_skinned_textbox_size_allocate;
-    widget_class->expose_event = ui_skinned_textbox_expose;
-    widget_class->button_press_event = ui_skinned_textbox_textbox_press;
-    widget_class->button_release_event = ui_skinned_textbox_textbox_release;
+    widget_class->button_press_event = ui_skinned_textbox_button_press;
+    widget_class->button_release_event = ui_skinned_textbox_button_release;
     widget_class->motion_notify_event = ui_skinned_textbox_motion_notify;
 
-    container_class->add = ui_skinned_textbox_add;
-
     klass->clicked = NULL;
     klass->double_clicked = NULL;
     klass->right_clicked = NULL;
@@ -178,177 +136,204 @@
         g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
                       G_STRUCT_OFFSET (UiSkinnedTextboxClass, redraw), NULL, NULL,
                       gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedTextboxPrivate));
-}
-
-static void ui_skinned_textbox_init (UiSkinnedTextbox *textbox) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-    mutex = g_mutex_new();
-    priv->image = gtk_image_new();
-    priv->resize_width = 0;
-    priv->resize_height = 0;
-    priv->move_x = 0;
-    priv->move_y = 0;
-    textbox->redraw = TRUE;
-
-    g_object_set (priv->image, "visible", TRUE, NULL);
-    gtk_container_add(GTK_CONTAINER(GTK_WIDGET(textbox)), priv->image);
-
-    GTK_WIDGET_SET_FLAGS (textbox, GTK_NO_WINDOW);
-}
-
-static void ui_skinned_textbox_destroy (GtkObject *object) {
-    (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static GObject* ui_skinned_textbox_constructor(GType type, guint n_construct_properties, GObjectConstructParam *construct_params) {
-    GObject *object = (*G_OBJECT_CLASS (parent_class)->constructor)(type, n_construct_properties, construct_params);
-
-    return object;
 }
 
-static void ui_skinned_textbox_realize (GtkWidget *widget) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    GdkWindowAttr attrib;
-
-    GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-
-    attrib.window_type = GDK_WINDOW_CHILD;
-    attrib.x = widget->allocation.x;
-    attrib.y = widget->allocation.y;
-    attrib.width = widget->allocation.width;
-    attrib.height = widget->allocation.height;
-    attrib.wclass = GDK_INPUT_ONLY;
-    attrib.event_mask = gtk_widget_get_events (widget);
-    attrib.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK);
-
-    widget->window = gtk_widget_get_parent_window(widget);
-    g_object_ref(widget->window);
-
-    textbox->event_window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrib, GDK_WA_X | GDK_WA_Y);
-    gdk_window_set_user_data (textbox->event_window, textbox);
-}
-
-static void ui_skinned_textbox_unrealize(GtkWidget *widget) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-
-    if (textbox->event_window) {
-        gdk_window_set_user_data (textbox->event_window, NULL);
-        gdk_window_destroy (textbox->event_window);
-        textbox->event_window = NULL;
-    }
-
-    GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+static void ui_skinned_textbox_init(UiSkinnedTextbox *textbox) {
+    mutex = g_mutex_new();
+    textbox->resize_width = 0;
+    textbox->resize_height = 0;
+    textbox->move_x = 0;
+    textbox->move_y = 0;
+    textbox->img = NULL;
 }
 
-static void ui_skinned_textbox_map(GtkWidget *widget) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    g_return_if_fail (UI_IS_SKINNED_TEXTBOX (widget));
-    GTK_WIDGET_CLASS (parent_class)->map(widget);
-    gdk_window_show (textbox->event_window);
-}
-
-static void ui_skinned_textbox_unmap (GtkWidget *widget) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    g_return_if_fail (UI_IS_SKINNED_TEXTBOX(widget));
-
-    if (textbox->event_window)
-        gdk_window_hide (textbox->event_window);
-
-    GTK_WIDGET_CLASS (parent_class)->unmap (widget);
-}
+GtkWidget* ui_skinned_textbox_new(GtkWidget *fixed, GdkPixmap * parent, GdkGC * gc, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) {
+    UiSkinnedTextbox *textbox = g_object_new (ui_skinned_textbox_get_type (), NULL);
 
-static gboolean ui_skinned_textbox_expose(GtkWidget *widget, GdkEventExpose *event) {
-    if (GTK_WIDGET_DRAWABLE (widget)) {
-        ui_skinned_textbox_paint(UI_SKINNED_TEXTBOX(widget));
-        (*GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
-    }
-
-    return FALSE;
-}
-
-GtkWidget* ui_skinned_textbox_new () {
-    return g_object_new (UI_TYPE_SKINNED_TEXTBOX, NULL);
-}
-
-void ui_skinned_textbox_setup(GtkWidget *widget, GtkWidget *fixed,GdkPixmap * parent, GdkGC * gc, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) {
-
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
     textbox->height = bmp_active_skin->properties.textbox_bitmap_font_height;
     textbox->x = x;
     textbox->y = y;
     textbox->text = g_strdup("");
-    priv->gc = gc;
+    textbox->gc = gc;
     textbox->width = w;
-    priv->scroll_allowed = allow_scroll;
-    priv->scroll_enabled = TRUE;
-    priv->skin_index = si;
-    priv->nominal_y = y;
-    priv->nominal_height = textbox->height;
-    priv->scroll_timeout = 0;
-    priv->scroll_dummy = 0;
+    textbox->scroll_allowed = allow_scroll;
+    textbox->scroll_enabled = TRUE;
+    textbox->skin_index = si;
+    textbox->nominal_y = y;
+    textbox->nominal_height = textbox->height;
+    textbox->scroll_timeout = 0;
+    textbox->scroll_dummy = 0;
+
+    textbox->fixed = fixed;
+    textbox->double_size = FALSE;
+
+    return GTK_WIDGET(textbox);
+}
+
+static void ui_skinned_textbox_destroy(GtkObject *object) {
+    UiSkinnedTextbox *textbox;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_TEXTBOX (object));
+
+    textbox = UI_SKINNED_TEXTBOX (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_textbox_realize(GtkWidget *widget) {
+    UiSkinnedTextbox *textbox;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
 
-    priv->fixed = fixed;
-    priv->double_size = FALSE;
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_TEXTBOX(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    textbox = UI_SKINNED_TEXTBOX(widget);
 
-    gtk_widget_set_size_request(widget, textbox->width, textbox->height);
-    gtk_fixed_put(GTK_FIXED(priv->fixed), widget, textbox->x, textbox->y);
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+                             GDK_POINTER_MOTION_HINT_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_textbox_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    requisition->width = UI_SKINNED_TEXTBOX(widget)->width*(1+textbox->double_size);
+    requisition->height = UI_SKINNED_TEXTBOX(widget)->height*(1+textbox->double_size);
 }
 
 static void ui_skinned_textbox_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
     g_mutex_lock(mutex);
     UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-    GtkAllocation child_alloc;
-
     widget->allocation = *allocation;
-    if (GTK_BIN (textbox)->child) {                //image should fill whole widget
-        child_alloc.x = widget->allocation.x;
-        child_alloc.y = widget->allocation.y;
-        child_alloc.width = MAX (1, widget->allocation.width);
-        child_alloc.height = MAX (1, widget->allocation.height);
-
-        gtk_widget_size_allocate (GTK_BIN (textbox)->child, &child_alloc);
-    }
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
 
-    if (GDK_IS_WINDOW(textbox->event_window))
-        gdk_window_move_resize (textbox->event_window, widget->allocation.x, widget->allocation.y,
-                                widget->allocation.width, widget->allocation.height);
-
-    textbox->x = widget->allocation.x/(priv->double_size ? 2 : 1);
-    textbox->y = widget->allocation.y/(priv->double_size ? 2 : 1);
-    priv->move_x = 0;
-    priv->move_y = 0;
+    textbox->x = widget->allocation.x/(textbox->double_size ? 2 : 1);
+    textbox->y = widget->allocation.y/(textbox->double_size ? 2 : 1);
+    textbox->move_x = 0;
+    textbox->move_y = 0;
 
-    if (textbox->width != widget->allocation.width/(priv->double_size ? 2 : 1)) {
-        textbox->width = widget->allocation.width/(priv->double_size ? 2 : 1);
-        priv->resize_width = 0;
-        priv->resize_height = 0;
-        if (priv->pixmap_text) g_free(priv->pixmap_text);
-        priv->pixmap_text = NULL;
-        priv->offset = 0;
-        textbox->redraw = TRUE;
+    if (textbox->width != widget->allocation.width/(textbox->double_size ? 2 : 1)) {
+        textbox->width = widget->allocation.width/(textbox->double_size ? 2 : 1);
+        textbox->resize_width = 0;
+        textbox->resize_height = 0;
+        if (textbox->pixmap_text) g_free(textbox->pixmap_text);
+        textbox->pixmap_text = NULL;
+        textbox->offset = 0;
         gtk_widget_queue_draw(GTK_WIDGET(textbox));
     }
     g_mutex_unlock(mutex);
 }
 
-static gboolean ui_skinned_textbox_textbox_press(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
+static gboolean ui_skinned_textbox_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    if(textbox->redraw) {
+        textbox->redraw = FALSE;
+        GdkPixmap *obj = NULL;
+        gint cw;
+
+        if (textbox->text && (!textbox->pixmap_text || strcmp(textbox->text, textbox->pixmap_text)))
+            textbox_generate_pixmap(textbox);
+
+        if (textbox->pixmap) {
+            if (skin_get_id() != textbox->skin_id) {
+                textbox->skin_id = skin_get_id();
+                textbox_generate_pixmap(textbox);
+            }
+            obj = gdk_pixmap_new(NULL, textbox->width, textbox->height, gdk_rgb_get_visual()->depth);
+
+            if(cfg.twoway_scroll) { // twoway scroll
+                cw = textbox->pixmap_width - textbox->offset;
+                if (cw > textbox->width)
+                    cw = textbox->width;
+                gdk_draw_drawable(obj, textbox->gc, textbox->pixmap, textbox->offset, 0, 0, 0, cw, textbox->height);
+                if (cw < textbox->width)
+                    gdk_draw_drawable(obj, textbox->gc, textbox->pixmap, 0, 0,
+                                      textbox->x + cw, textbox->y,
+                                      textbox->width - cw, textbox->height);
+            }
+            else { // oneway scroll
+                int cw1, cw2;
+
+                if(textbox->offset >= textbox->pixmap_width)
+                    textbox->offset = 0;
 
+                if(textbox->pixmap_width - textbox->offset > textbox->width){ // case1
+                    cw1 = textbox->width;
+                    gdk_draw_drawable(textbox->img, textbox->gc, textbox->pixmap, textbox->offset, 0,
+                                      0, 0, cw1, textbox->height);
+                }
+                else { // case 2
+                    cw1 = textbox->pixmap_width - textbox->offset;
+                    gdk_draw_drawable(textbox->img, textbox->gc, textbox->pixmap, textbox->offset, 0,
+                                      0, 0, cw1, textbox->height);
+                    cw2 = textbox->width - cw1;
+                    gdk_draw_drawable(textbox->img, textbox->gc, textbox->pixmap, 0, 0, cw1, 0, cw2, textbox->height);
+                }
+
+            }
+        if (textbox->img)
+                g_object_unref(textbox->img);
+        textbox->img = gdk_pixmap_new(NULL, textbox->width*(1+textbox->double_size),
+                                            textbox->height*(1+textbox->double_size),
+                                            gdk_rgb_get_visual()->depth);
+
+        if (textbox->double_size) {
+            GdkImage *img, *img2x;
+            img = gdk_drawable_get_image(obj, 0, 0, textbox->width, textbox->height);
+            img2x = create_dblsize_image(img);
+            gdk_draw_image (textbox->img, textbox->gc, img2x, 0, 0, 0, 0, textbox->width*2, textbox->height*2);
+            g_object_unref(img2x);
+            g_object_unref(img);
+        } else
+            gdk_draw_drawable (textbox->img, textbox->gc, obj, 0, 0, 0, 0, textbox->width, textbox->height);
+            g_object_unref(obj);
+            gtk_widget_queue_resize(widget);
+        }
+    }
+
+    gdk_draw_drawable (widget->window, textbox->gc, textbox->img, 0, 0, 0, 0,
+                       textbox->width*(1+textbox->double_size), textbox->height*(1+textbox->double_size));
+  return FALSE;
+}
+
+static gboolean ui_skinned_textbox_button_press(GtkWidget *widget, GdkEventButton *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
     if (event->type == GDK_BUTTON_PRESS) {
         textbox = UI_SKINNED_TEXTBOX(widget);
-
         if (event->button == 1) {
-            if (priv->scroll_allowed) {
-                if ((priv->pixmap_width > textbox->width) && priv->is_scrollable) {
-                    priv->is_dragging = TRUE;
-                    textbox->redraw = TRUE;
-                    priv->drag_off = priv->offset;
-                    priv->drag_x = event->x;
+            if (textbox->scroll_allowed) {
+                if ((textbox->pixmap_width > textbox->width) && textbox->is_scrollable) {
+                    textbox->is_dragging = TRUE;
+                    textbox->drag_off = textbox->offset;
+                    textbox->drag_x = event->x;
                 }
             } else
                 g_signal_emit(widget, textbox_signals[CLICKED], 0);
@@ -361,144 +346,65 @@
             g_signal_emit(widget, textbox_signals[DOUBLE_CLICKED], 0);
         }
     }
-    return TRUE;
+
+    return FALSE;
 }
 
-static gboolean ui_skinned_textbox_textbox_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
+static gboolean ui_skinned_textbox_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedTextbox *textbox;
+
+    textbox = UI_SKINNED_TEXTBOX (widget);
     if (event->button == 1) {
-        priv->is_dragging = FALSE;
-        textbox->redraw = TRUE;
+        textbox->is_dragging = FALSE;
     }
 
-    return TRUE;
+    return FALSE;
 }
 
 static gboolean ui_skinned_textbox_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
 
-    if (priv->is_dragging) {
-        if (priv->scroll_allowed &&
-            priv->pixmap_width > textbox->width) {
-            priv->offset = priv->drag_off - (event->x - priv->drag_x);
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    if (textbox->is_dragging) {
+        if (textbox->scroll_allowed &&
+            textbox->pixmap_width > textbox->width) {
+            textbox->offset = textbox->drag_off - (event->x - textbox->drag_x);
 
-            while (priv->offset < 0)
-                priv->offset = 0;
+            while (textbox->offset < 0)
+                textbox->offset = 0;
 
-            while (priv->offset > (priv->pixmap_width - textbox->width))
-                priv->offset = (priv->pixmap_width - textbox->width);
+            while (textbox->offset > (textbox->pixmap_width - textbox->width))
+                textbox->offset = (textbox->pixmap_width - textbox->width);
 
             textbox->redraw = TRUE;
             gtk_widget_queue_draw(widget);
         }
     }
 
-    return FALSE;
-}
-
-static void ui_skinned_textbox_add(GtkContainer *container, GtkWidget *widget) {
-    GTK_CONTAINER_CLASS (parent_class)->add(container, widget);
+  return FALSE;
 }
 
 static void ui_skinned_textbox_toggle_doublesize(UiSkinnedTextbox *textbox) {
     GtkWidget *widget = GTK_WIDGET (textbox);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-    priv->double_size = !priv->double_size;
+    textbox->double_size = !textbox->double_size;
 
-    gtk_widget_set_size_request(widget, textbox->width*(1+priv->double_size), textbox->height*(1+priv->double_size));
-    gtk_widget_set_uposition(widget, textbox->x*(1+priv->double_size), textbox->y*(1+priv->double_size));
+    gtk_widget_set_size_request(widget, textbox->width*(1+textbox->double_size), textbox->height*(1+textbox->double_size));
+    gtk_widget_set_uposition(widget, textbox->x*(1+textbox->double_size), textbox->y*(1+textbox->double_size));
 
     textbox->redraw = TRUE;
     gtk_widget_queue_draw(GTK_WIDGET(textbox));
 }
 
-static void ui_skinned_textbox_paint(UiSkinnedTextbox *textbox) {
-    GtkWidget *widget = GTK_WIDGET (textbox);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-
-    if (textbox->redraw == TRUE) {
-        textbox->redraw = FALSE;
-        gint cw;
-        GdkPixmap *obj;
-
-        if (textbox->text && (!priv->pixmap_text || strcmp(textbox->text, priv->pixmap_text)))
-            textbox_generate_pixmap(textbox);
-
-        if (priv->pixmap) {
-            if (skin_get_id() != priv->skin_id) {
-                priv->skin_id = skin_get_id();
-                textbox_generate_pixmap(textbox);
-            }
-            obj = gdk_pixmap_new(NULL, textbox->width, textbox->height, gdk_rgb_get_visual()->depth);
-
-            if(cfg.twoway_scroll) { // twoway scroll
-                cw = priv->pixmap_width - priv->offset;
-                if (cw > textbox->width)
-                    cw = textbox->width;
-                gdk_draw_drawable(obj, priv->gc, priv->pixmap, priv->offset, 0, 0, 0, cw, textbox->height);
-                if (cw < textbox->width)
-                    gdk_draw_drawable(obj, priv->gc, priv->pixmap, 0, 0,
-                                      textbox->x + cw, textbox->y,
-                                      textbox->width - cw, textbox->height);
-
-                if (priv->double_size) {
-                    GdkImage *img, *img2x;
-                    img = gdk_drawable_get_image(obj, 0, 0, textbox->width, textbox->height);
-                    img2x = create_dblsize_image(img);
-                    gtk_image_set(GTK_IMAGE(priv->image), img2x, NULL);
-                    g_object_unref(img2x);
-                    g_object_unref(img);
-                } else
-                    gtk_image_set_from_pixmap(GTK_IMAGE(priv->image), obj, NULL);
-            }
-            else { // oneway scroll
-                int cw1, cw2;
-
-                if(priv->offset >= priv->pixmap_width)
-                    priv->offset = 0;
-
-                if(priv->pixmap_width - priv->offset > textbox->width){ // case1
-                    cw1 = textbox->width;
-                    gdk_draw_drawable(obj, priv->gc, priv->pixmap, priv->offset, 0,
-                                      0, 0, cw1, textbox->height);
-                }
-                else { // case 2
-                    cw1 = priv->pixmap_width - priv->offset;
-                    gdk_draw_drawable(obj, priv->gc, priv->pixmap, priv->offset, 0,
-                                      0, 0, cw1, textbox->height);
-                    cw2 = textbox->width - cw1;
-                    gdk_draw_drawable(obj, priv->gc, priv->pixmap, 0, 0, cw1, 0, cw2, textbox->height);
-                }
-
-                if (priv->double_size) {
-                    GdkImage *img, *img2x;
-                    img = gdk_drawable_get_image(obj, 0, 0, textbox->width, textbox->height);
-                    img2x = create_dblsize_image(img);
-                    gtk_image_set(GTK_IMAGE(priv->image), img2x, NULL);
-                    g_object_unref(img2x);
-                    g_object_unref(img);
-                } else {
-                    gtk_image_set_from_pixmap(GTK_IMAGE(priv->image), obj, NULL);
-                }
-            }
-
-            g_object_unref(obj);
-            gtk_widget_queue_resize(widget);
-        }
-    }
-}
-
 static void ui_skinned_textbox_redraw(UiSkinnedTextbox *textbox) {
     g_mutex_lock(mutex);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-    if (priv->resize_width || priv->resize_height)
+    if (textbox->resize_width || textbox->resize_height)
         gtk_widget_set_size_request(GTK_WIDGET(textbox),
-                                   (textbox->width+priv->resize_width)*(1+priv->double_size),
-                                   (textbox->height+priv->resize_height)*(1+priv->double_size));
-    if (priv->move_x || priv->move_y)
-        gtk_fixed_move(GTK_FIXED(priv->fixed), GTK_WIDGET(textbox), textbox->x+priv->move_x, textbox->y+priv->move_y);
+                                   (textbox->width+textbox->resize_width)*(1+textbox->double_size),
+                                   (textbox->height+textbox->resize_height)*(1+textbox->double_size));
+    if (textbox->move_x || textbox->move_y)
+        gtk_fixed_move(GTK_FIXED(textbox->fixed), GTK_WIDGET(textbox), textbox->x+textbox->move_x, textbox->y+textbox->move_y);
 
     textbox->redraw = TRUE;
     gtk_widget_queue_draw(GTK_WIDGET(textbox));
@@ -506,13 +412,12 @@
 }
 
 static gboolean ui_skinned_textbox_should_scroll(UiSkinnedTextbox *textbox) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
-    if (!priv->scroll_allowed)
+    if (!textbox->scroll_allowed)
         return FALSE;
 
-    if (priv->font) {
+    if (textbox->font) {
         gint width;
-        text_get_extents(priv->fontname, textbox->text, &width, NULL, NULL, NULL);
+        text_get_extents(textbox->fontname, textbox->text, &width, NULL, NULL, NULL);
 
         if (width <= textbox->width)
             return FALSE;
@@ -528,62 +433,60 @@
 
 void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname) {
     UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
     gint ascent, descent;
 
     g_return_if_fail(textbox != NULL);
 
-    if (priv->font) {
-        pango_font_description_free(priv->font);
-        priv->font = NULL;
+    if (textbox->font) {
+        pango_font_description_free(textbox->font);
+        textbox->font = NULL;
     }
 
-    textbox->y = priv->nominal_y;
-    textbox->height = priv->nominal_height;
+    textbox->y = textbox->nominal_y;
+    textbox->height = textbox->nominal_height;
 
     /* Make sure the pixmap is regenerated */
-    if (priv->pixmap_text) {
-        g_free(priv->pixmap_text);
-        priv->pixmap_text = NULL;
+    if (textbox->pixmap_text) {
+        g_free(textbox->pixmap_text);
+        textbox->pixmap_text = NULL;
     }
 
     if (!use_xfont || strlen(fontname) == 0)
         return;
 
-    priv->font = pango_font_description_from_string(fontname);
-    priv->fontname = g_strdup(fontname);
+    textbox->font = pango_font_description_from_string(fontname);
+    textbox->fontname = g_strdup(fontname);
 
     text_get_extents(fontname,
                      "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ",
                      NULL, NULL, &ascent, &descent);
-    priv->font_ascent = ascent;
-    priv->font_descent = descent;
+    textbox->font_ascent = ascent;
+    textbox->font_descent = descent;
 
 
-    if (priv->font == NULL)
+    if (textbox->font == NULL)
         return;
 
-    textbox->height = priv->font_ascent;
-    if (textbox->height > priv->nominal_height)
-        textbox->y -= (textbox->height - priv->nominal_height) / 2;
+    textbox->height = textbox->font_ascent;
+    if (textbox->height > textbox->nominal_height)
+        textbox->y -= (textbox->height - textbox->nominal_height) / 2;
     else
-        textbox->height = priv->nominal_height;
+        textbox->height = textbox->nominal_height;
 }
 
 void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text) {
     g_return_if_fail(text != NULL);
     UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
 
     if (!strcmp(textbox->text, text))
          return;
     if (textbox->text)
         g_free(textbox->text);
 
+    textbox->redraw = TRUE;
     textbox->text = str_to_utf8(text);
-    priv->scroll_back = FALSE;
-    textbox->redraw = TRUE;
-    gtk_widget_queue_draw(GTK_WIDGET(textbox));
+    textbox->scroll_back = FALSE;
+    //gtk_widget_queue_draw(GTK_WIDGET(textbox));
 }
 
 static void textbox_generate_xfont_pixmap(UiSkinnedTextbox *textbox, const gchar *pixmaptext) {
@@ -593,41 +496,40 @@
     GdkBitmap *mask;
     PangoLayout *layout;
     gint width;
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
 
     g_return_if_fail(textbox != NULL);
     g_return_if_fail(pixmaptext != NULL);
 
     length = g_utf8_strlen(pixmaptext, -1);
 
-    text_get_extents(priv->fontname, pixmaptext, &width, NULL, NULL, NULL);
+    text_get_extents(textbox->fontname, pixmaptext, &width, NULL, NULL, NULL);
 
-    priv->pixmap_width = MAX(width, textbox->width);
-    priv->pixmap = gdk_pixmap_new(mainwin->window, priv->pixmap_width,
+    textbox->pixmap_width = MAX(width, textbox->width);
+    textbox->pixmap = gdk_pixmap_new(mainwin->window, textbox->pixmap_width,
                                    textbox->height,
                                    gdk_rgb_get_visual()->depth);
-    gc = priv->gc;
+    gc = textbox->gc;
     c = skin_get_color(bmp_active_skin, SKIN_TEXTBG);
     for (i = 0; i < textbox->height; i++) {
         gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
-        gdk_draw_line(priv->pixmap, gc, 0, i, priv->pixmap_width, i);
+        gdk_draw_line(textbox->pixmap, gc, 0, i, textbox->pixmap_width, i);
     }
 
-    mask = gdk_pixmap_new(mainwin->window, priv->pixmap_width, textbox->height, 1);
+    mask = gdk_pixmap_new(mainwin->window, textbox->pixmap_width, textbox->height, 1);
     maskgc = gdk_gc_new(mask);
     pattern.pixel = 0;
     gdk_gc_set_foreground(maskgc, &pattern);
 
-    gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, priv->pixmap_width, textbox->height);
+    gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, textbox->pixmap_width, textbox->height);
     pattern.pixel = 1;
     gdk_gc_set_foreground(maskgc, &pattern);
 
     gdk_gc_set_foreground(gc, skin_get_color(bmp_active_skin, SKIN_TEXTFG));
 
     layout = gtk_widget_create_pango_layout(mainwin, pixmaptext);
-    pango_layout_set_font_description(layout, priv->font);
+    pango_layout_set_font_description(layout, textbox->font);
 
-    gdk_draw_layout(priv->pixmap, gc, 0, (priv->font_descent / 2), layout);
+    gdk_draw_layout(textbox->pixmap, gc, 0, (textbox->font_descent / 2), layout);
     g_object_unref(layout);
 
     g_object_unref(maskgc);
@@ -636,7 +538,7 @@
     c = skin_get_color(bmp_active_skin, SKIN_TEXTFG);
     for (i = 0; i < textbox->height; i++) {
         gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
-        gdk_draw_line(priv->pixmap, gc, 0, i, priv->pixmap_width, i);
+        gdk_draw_line(textbox->pixmap, gc, 0, i, textbox->pixmap_width, i);
     }
     g_object_unref(mask);
     gdk_gc_set_clip_mask(gc, NULL);
@@ -644,33 +546,31 @@
 
 static gboolean textbox_scroll(gpointer data) {
     UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(data);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (data);
 
-    if (!priv->is_dragging) {
-        if (priv->scroll_dummy < TEXTBOX_SCROLL_WAIT)
-            priv->scroll_dummy++;
+    if (!textbox->is_dragging) {
+        if (textbox->scroll_dummy < TEXTBOX_SCROLL_WAIT)
+            textbox->scroll_dummy++;
         else {
             if(cfg.twoway_scroll) {
-                if (priv->scroll_back)
-                    priv->offset -= 1;
+                if (textbox->scroll_back)
+                    textbox->offset -= 1;
                 else
-                    priv->offset += 1;
+                    textbox->offset += 1;
 
-                if (priv->offset >= (priv->pixmap_width - textbox->width)) {
-                    priv->scroll_back = TRUE;
-                    priv->scroll_dummy = 0;
+                if (textbox->offset >= (textbox->pixmap_width - textbox->width)) {
+                    textbox->scroll_back = TRUE;
+                    textbox->scroll_dummy = 0;
                 }
-                if (priv->offset <= 0) {
-                    priv->scroll_back = FALSE;
-                    priv->scroll_dummy = 0;
+                if (textbox->offset <= 0) {
+                    textbox->scroll_back = FALSE;
+                    textbox->scroll_dummy = 0;
                 }
             }
             else { // oneway scroll
-                priv->scroll_back = FALSE;
-                priv->offset += 1;
+                textbox->scroll_back = FALSE;
+                textbox->offset += 1;
             }
-
-            textbox->redraw = TRUE;
+            textbox->redraw=TRUE;
             gtk_widget_queue_draw(GTK_WIDGET(textbox));
         }
     }
@@ -682,12 +582,12 @@
     gchar *pixmaptext;
     gchar *tmp, *stxt;
     GdkGC *gc;
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
+
     g_return_if_fail(textbox != NULL);
 
-    if (priv->pixmap) {
-        g_object_unref(priv->pixmap);
-        priv->pixmap = NULL;
+    if (textbox->pixmap) {
+        g_object_unref(textbox->pixmap);
+        textbox->pixmap = NULL;
     }
 
     /*
@@ -695,13 +595,13 @@
      * changed.  This is a hack to avoid visual noice on vbr files
      * where we guess the length.
      */
-    if (!(priv->pixmap_text && strrchr(textbox->text, '(') &&
-          !strncmp(priv->pixmap_text, textbox->text,
+    if (!(textbox->pixmap_text && strrchr(textbox->text, '(') &&
+          !strncmp(textbox->pixmap_text, textbox->text,
                    strrchr(textbox->text, '(') - textbox->text)))
-        priv->offset = 0;
+        textbox->offset = 0;
 
-    g_free(priv->pixmap_text);
-    priv->pixmap_text = g_strdup(textbox->text);
+    g_free(textbox->pixmap_text);
+    textbox->pixmap_text = g_strdup(textbox->text);
 
     /*
      * wl is the number of (partial) letters visible. Only makes
@@ -713,52 +613,52 @@
 
     length = g_utf8_strlen(textbox->text, -1);
 
-    priv->is_scrollable = FALSE;
+    textbox->is_scrollable = FALSE;
 
-    priv->is_scrollable = ui_skinned_textbox_should_scroll(textbox);
+    textbox->is_scrollable = ui_skinned_textbox_should_scroll(textbox);
 
-    if (priv->is_scrollable) {
+    if (textbox->is_scrollable) {
         if(!cfg.twoway_scroll) {
-            pixmaptext = g_strdup_printf("%s *** ", priv->pixmap_text);
+            pixmaptext = g_strdup_printf("%s *** ", textbox->pixmap_text);
             length += 5;
         } else
-            pixmaptext = g_strdup(priv->pixmap_text);
+            pixmaptext = g_strdup(textbox->pixmap_text);
     } else
-    if (!priv->font && length <= wl) {
+    if (!textbox->font && length <= wl) {
         gint pad = wl - length;
         gchar *padchars = g_strnfill(pad, ' ');
 
-        pixmaptext = g_strconcat(priv->pixmap_text, padchars, NULL);
+        pixmaptext = g_strconcat(textbox->pixmap_text, padchars, NULL);
         g_free(padchars);
         length += pad;
     } else
-        pixmaptext = g_strdup(priv->pixmap_text);
+        pixmaptext = g_strdup(textbox->pixmap_text);
 
-    if (priv->is_scrollable) {
-        if (priv->scroll_enabled && !priv->scroll_timeout) {
+    if (textbox->is_scrollable) {
+        if (textbox->scroll_enabled && !textbox->scroll_timeout) {
             gint tag;
             tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
-            priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
+            textbox->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
         }
     } else {
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
+        if (textbox->scroll_timeout) {
+            g_source_remove(textbox->scroll_timeout);
+            textbox->scroll_timeout = 0;
         }
-        priv->offset = 0;
+        textbox->offset = 0;
     }
 
-    if (priv->font) {
+    if (textbox->font) {
         textbox_generate_xfont_pixmap(textbox, pixmaptext);
         g_free(pixmaptext);
         return;
     }
 
-    priv->pixmap_width = length * bmp_active_skin->properties.textbox_bitmap_font_width;
-    priv->pixmap = gdk_pixmap_new(NULL,
-                                     priv->pixmap_width, bmp_active_skin->properties.textbox_bitmap_font_height,
+    textbox->pixmap_width = length * bmp_active_skin->properties.textbox_bitmap_font_width;
+    textbox->pixmap = gdk_pixmap_new(NULL,
+                                     textbox->pixmap_width, bmp_active_skin->properties.textbox_bitmap_font_height,
                                      gdk_rgb_get_visual()->depth);
-    gc = priv->gc;
+    gc = textbox->gc;
 
     for (tmp = stxt = g_utf8_strup(pixmaptext, -1), i = 0;
          tmp != NULL && i < length; i++, tmp = g_utf8_next_char(tmp)) {
@@ -776,7 +676,7 @@
             textbox_handle_special_char(c, &x, &y);
 
         skin_draw_pixmap(bmp_active_skin,
-                         priv->pixmap, gc, priv->skin_index,
+                         textbox->pixmap, gc, textbox->skin_index,
                          x, y, i * bmp_active_skin->properties.textbox_bitmap_font_width, 0,
                          bmp_active_skin->properties.textbox_bitmap_font_width, 
                          bmp_active_skin->properties.textbox_bitmap_font_height);
@@ -787,35 +687,31 @@
 
 void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll) {
     g_return_if_fail(widget != NULL);
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (textbox);
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
 
-    priv->scroll_enabled = scroll;
-    if (priv->scroll_enabled && priv->is_scrollable && priv->scroll_allowed) {
+    textbox->scroll_enabled = scroll;
+    if (textbox->scroll_enabled && textbox->is_scrollable && textbox->scroll_allowed) {
         gint tag;
         tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
+        if (textbox->scroll_timeout) {
+            g_source_remove(textbox->scroll_timeout);
+            textbox->scroll_timeout = 0;
         }
-        priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
+        textbox->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
 
     } else {
 
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
+        if (textbox->scroll_timeout) {
+            g_source_remove(textbox->scroll_timeout);
+            textbox->scroll_timeout = 0;
         }
 
-        priv->offset = 0;
-        textbox->redraw = TRUE;
-        gtk_widget_queue_draw(GTK_WIDGET(textbox));
+        textbox->offset = 0;
+        //gtk_widget_queue_draw(GTK_WIDGET(textbox));
     }
 }
 
-static void
-textbox_handle_special_char(gchar c, gint * x, gint * y)
-{
+static void textbox_handle_special_char(gchar c, gint * x, gint * y) {
     gint tx, ty;
 
     switch (c) {
@@ -926,16 +822,16 @@
 
 void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y) {
     g_mutex_lock(mutex);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (widget);
-    priv->move_x += x;
-    priv->move_y += y;
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    textbox->move_x += x;
+    textbox->move_y += y;
     g_mutex_unlock(mutex);
 }
 
 void ui_skinned_textbox_resize_relative(GtkWidget *widget, gint w, gint h) {
     g_mutex_lock(mutex);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE (widget);
-    priv->resize_width += w;
-    priv->resize_height += h;
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    textbox->resize_width += w;
+    textbox->resize_height += h;
     g_mutex_unlock(mutex);
 }
--- a/src/audacious/ui_skinned_textbox.h	Tue Jul 03 21:20:09 2007 -0500
+++ b/src/audacious/ui_skinned_textbox.h	Wed Jul 04 16:35:27 2007 +0200
@@ -2,6 +2,12 @@
  * Audacious - a cross-platform multimedia player
  * Copyright (c) 2007  Audacious development team.
  *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; under version 2 of the License.
@@ -20,33 +26,51 @@
 #define UISKINNEDTEXTBOX_H
 
 #include <gdk/gdk.h>
-#include <gtk/gtkbin.h>
-#include <gtk/gtkenums.h>
-#include "widgets/skin.h"
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
 
-#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT  30
-#define TEXTBOX_SCROLL_WAIT            80
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
 
-#define UI_TYPE_SKINNED_TEXTBOX            (ui_skinned_textbox_get_type())
-#define UI_SKINNED_TEXTBOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), UI_TYPE_SKINNED_TEXTBOX, UiSkinnedTextbox))
-#define UI_SKINNED_TEXTBOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), UI_TYPE_SKINNED_TEXTBOX, UiSkinnedTextboxClass))
-#define UI_IS_SKINNED_TEXTBOX(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UI_TYPE_SKINNED_TEXTBOX))
-#define UI_IS_SKINNED_TEXTBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UI_TYPE_SKINNED_TEXTBOX))
-#define UI_SKINNED_TEXTBOX_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), UI_TYPE_SKINNED_TEXTBOX, GtkFlatTextboxClass))
+#define UI_SKINNED_TEXTBOX(obj)          GTK_CHECK_CAST (obj, ui_skinned_textbox_get_type (), UiSkinnedTextbox)
+#define UI_SKINNED_TEXTBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_textbox_get_type (), UiSkinnedTextboxClass)
+#define UI_SKINNED_IS_TEXTBOX(obj)       GTK_CHECK_TYPE (obj, ui_skinned_textbox_get_type ())
 
-typedef struct _UiSkinnedTextbox	UiSkinnedTextbox;
-typedef struct _UiSkinnedTextboxClass	UiSkinnedTextboxClass;
+typedef struct _UiSkinnedTextbox        UiSkinnedTextbox;
+typedef struct _UiSkinnedTextboxClass   UiSkinnedTextboxClass;
 
 struct _UiSkinnedTextbox {
-    GtkBin bin;
-    GdkWindow *event_window;
-    gint x, y, width, height;
-    gboolean redraw;
-    gchar *text;
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gchar            *text;
+    gboolean         redraw;
+    GdkPixmap        *img;
+    GdkGC            *gc;
+    SkinPixmapId     skin_index;
+    GtkWidget        *fixed;
+    gboolean         double_size;
+    gboolean         scroll_back;
+    gint             nominal_y, nominal_height;
+    gint             scroll_timeout;
+    gint             font_ascent, font_descent;
+    PangoFontDescription *font;
+    gchar            *fontname;
+    gchar            *pixmap_text;
+    gint             skin_id;
+    gint             drag_x, drag_off, offset;
+    gboolean         is_scrollable, is_dragging;
+    gint             pixmap_width;
+    GdkPixmap        *pixmap;
+    gboolean         scroll_allowed, scroll_enabled;
+    gint             scroll_dummy;
+    gint             resize_width, resize_height;
+    gint             move_x, move_y;
 };
 
 struct _UiSkinnedTextboxClass {
-    GtkBinClass parent_class;
+    GtkWidgetClass          parent_class;
     void (* clicked)        (UiSkinnedTextbox *textbox);
     void (* double_clicked) (UiSkinnedTextbox *textbox);
     void (* right_clicked)  (UiSkinnedTextbox *textbox);
@@ -54,13 +78,16 @@
     void (* redraw)         (UiSkinnedTextbox *textbox);
 };
 
-GType ui_skinned_textbox_get_type(void) G_GNUC_CONST;
-GtkWidget* ui_skinned_textbox_new();
-void ui_skinned_textbox_setup(GtkWidget *widget, GtkWidget *fixed, GdkPixmap *parent, GdkGC *gc, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si);
+GtkWidget* ui_skinned_textbox_new (GtkWidget *fixed, GdkPixmap * parent, GdkGC * gc, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si);
+GtkType ui_skinned_textbox_get_type(void);
+void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname);
 void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text);
-void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar *fontname);
 void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll);
 void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y);
 void ui_skinned_textbox_resize_relative(GtkWidget *widget, gint w, gint h);
 
+#ifdef __cplusplus
+}
 #endif
+
+#endif