# HG changeset patch # User nenolod # Date 1155116842 25200 # Node ID 06329cbf186a73d0c2d913bb86f1d31a86b6cf44 # Parent 237bb7c977598f53e2b64e7875bb4ea6c7db7af0 [svn] this massive commit does the following: - seriously cleans up dependencies on the WA2-like gui code - moves all of the WA2 stuff into a seperate library (libwidgets.a) - makes things less icky in the player tree diff -r 237bb7c97759 -r 06329cbf186a ChangeLog --- a/ChangeLog Wed Aug 09 02:11:01 2006 -0700 +++ b/ChangeLog Wed Aug 09 02:47:22 2006 -0700 @@ -1,3 +1,12 @@ +2006-08-09 09:11:01 +0000 William Pitcock + revision [1994] + - use posix_memalign() instead of memalign(). + + + Changes: Modified: + +7 -4 trunk/Plugins/Input/wma/libffwma/mem.c + + 2006-08-09 09:04:02 +0000 William Pitcock revision [1992] - switch to stdlib/unistd.h for malloc (all C89/C99 systems have these). fixes bug #539. diff -r 237bb7c97759 -r 06329cbf186a audacious/Makefile --- a/audacious/Makefile Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/Makefile Wed Aug 09 02:47:22 2006 -0700 @@ -1,7 +1,7 @@ include ../mk/rules.mk include ../mk/objective.mk -SUBDIRS = glade images +SUBDIRS = widgets glade images beepincludedir = $(includedir)/audacious @@ -14,7 +14,8 @@ ../sqlite/libsqlite.a \ $(CHARDET_LIBS) \ $(GTK_LIBS) \ - $(LIBGLADE_LIBS) + $(LIBGLADE_LIBS) \ + ./widgets/libwidgets.a CFLAGS += \ $(GTK_CFLAGS) \ @@ -33,7 +34,6 @@ SOURCES = \ build_stamp.c \ genevent.c \ - skin.c \ util.c \ output.c \ fft.c \ @@ -45,23 +45,7 @@ playlist.c \ controlsocket.c \ dock.c \ - widget.c \ - sbutton.c \ - pbutton.c \ - tbutton.c \ - textbox.c \ - menurow.c \ - hslider.c \ - monostereo.c \ - vis.c \ - svis.c \ - number.c \ playback.c \ - playstatus.c \ - playlist_list.c \ - playlist_slider.c \ - eq_graph.c \ - eq_slider.c \ main.c \ logger.c \ mainwin.c \ diff -r 237bb7c97759 -r 06329cbf186a audacious/controlsocket.c --- a/audacious/controlsocket.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/controlsocket.c Wed Aug 09 02:47:22 2006 -0700 @@ -42,7 +42,6 @@ #include "playlist.h" #include "ui_playlist.h" #include "prefswin.h" -#include "skin.h" #include "libaudacious/beepctrl.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/eq_graph.c --- a/audacious/eq_graph.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "eq_graph.h" - -#include - -#include "main.h" -#include "skin.h" - -void -init_spline(gfloat * x, gfloat * y, gint n, gfloat * y2) -{ - gint i, k; - gfloat p, qn, sig, un, *u; - - u = (gfloat *) g_malloc(n * sizeof(gfloat)); - - y2[0] = u[0] = 0.0; - - for (i = 1; i < n - 1; i++) { - sig = ((gfloat) x[i] - x[i - 1]) / ((gfloat) x[i + 1] - x[i - 1]); - p = sig * y2[i - 1] + 2.0; - y2[i] = (sig - 1.0) / p; - u[i] = - (((gfloat) y[i + 1] - y[i]) / (x[i + 1] - x[i])) - - (((gfloat) y[i] - y[i - 1]) / (x[i] - x[i - 1])); - u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p; - } - qn = un = 0.0; - - y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0); - for (k = n - 2; k >= 0; k--) - y2[k] = y2[k] * y2[k + 1] + u[k]; - g_free(u); -} - -gfloat -eval_spline(gfloat xa[], gfloat ya[], gfloat y2a[], gint n, gfloat x) -{ - gint klo, khi, k; - gfloat h, b, a; - - klo = 0; - khi = n - 1; - while (khi - klo > 1) { - k = (khi + klo) >> 1; - if (xa[k] > x) - khi = k; - else - klo = k; - } - h = xa[khi] - xa[klo]; - a = (xa[khi] - x) / h; - b = (x - xa[klo]) / h; - return (a * ya[klo] + b * ya[khi] + - ((a * a * a - a) * y2a[klo] + - (b * b * b - b) * y2a[khi]) * (h * h) / 6.0); -} - -void -eqgraph_draw(Widget * w) -{ - EqGraph *eg = (EqGraph *) w; - GdkPixmap *obj; - GdkColor col; - guint32 cols[19]; - gint i, y, ymin, ymax, py = 0; - gfloat x[] = { 0, 11, 23, 35, 47, 59, 71, 83, 97, 109 }, yf[10]; - - /* - * This avoids the init_spline() function to be inlined. - * Inlining the function caused troubles when compiling with - * `-O' (at least on FreeBSD). - */ - void (*__init_spline) (gfloat *, gfloat *, gint, gfloat *) = init_spline; - - obj = eg->eg_widget.parent; - skin_draw_pixmap(bmp_active_skin, obj, eg->eg_widget.gc, SKIN_EQMAIN, - 0, 294, eg->eg_widget.x, eg->eg_widget.y, - eg->eg_widget.width, eg->eg_widget.height); - skin_draw_pixmap(bmp_active_skin, obj, eg->eg_widget.gc, SKIN_EQMAIN, - 0, 314, eg->eg_widget.x, - eg->eg_widget.y + 9 + - ((cfg.equalizer_preamp * 9) / 20), - eg->eg_widget.width, 1); - - skin_get_eq_spline_colors(bmp_active_skin, cols); - - __init_spline(x, cfg.equalizer_bands, 10, yf); - for (i = 0; i < 109; i++) { - y = 9 - - (gint) ((eval_spline(x, cfg.equalizer_bands, yf, 10, i) * - 9.0) / 20.0); - if (y < 0) - y = 0; - if (y > 18) - y = 18; - if (!i) - py = y; - if (y < py) { - ymin = y; - ymax = py; - } - else { - ymin = py; - ymax = y; - } - py = y; - for (y = ymin; y <= ymax; y++) { - col.pixel = cols[y]; - gdk_gc_set_foreground(eg->eg_widget.gc, &col); - gdk_draw_point(obj, eg->eg_widget.gc, eg->eg_widget.x + i + 2, - eg->eg_widget.y + y); - } - } -} - -EqGraph * -create_eqgraph(GList ** wlist, GdkPixmap * parent, GdkGC * gc, gint x, gint y) -{ - EqGraph *eg; - - eg = g_new0(EqGraph, 1); - widget_init(&eg->eg_widget, parent, gc, x, y, 113, 19, TRUE); - eg->eg_widget.draw = eqgraph_draw; - - widget_list_add(wlist, WIDGET(eg)); - - return eg; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/eq_graph.h --- a/audacious/eq_graph.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef EQ_GRAPH_H -#define EQ_GRAPH_H - -#include -#include - -#include "widget.h" - -#define EQ_GRAPH(x) ((EqGraph *)(x)) -struct _EqGraph { - Widget eg_widget; -}; - -typedef struct _EqGraph EqGraph; - -EqGraph *create_eqgraph(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/eq_slider.c --- a/audacious/eq_slider.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "eq_slider.h" - -#include -#include -#include -#include - -#include "equalizer.h" -#include "mainwin.h" -#include "skin.h" - -void -eqslider_set_position(EqSlider * es, - gfloat pos) -{ - es->es_position = 25 - (gint) ((pos * 25.0) / 20.0); - - if (es->es_position < 0) - es->es_position = 0; - - if (es->es_position > 50) - es->es_position = 50; - - if (es->es_position >= 24 && es->es_position <= 26) - es->es_position = 25; - - widget_draw(WIDGET(es)); -} - -gfloat -eqslider_get_position(EqSlider * es) -{ - return 20.0 - (((gfloat) es->es_position * 20.0) / 25.0); -} - -void -eqslider_draw(Widget * w) -{ - EqSlider *es = (EqSlider *) w; - GdkPixmap *obj; - SkinPixmapId src; - gint frame; - - src = SKIN_EQMAIN; - obj = es->es_widget.parent; - - frame = 27 - ((es->es_position * 27) / 50); - if (frame < 14) - skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, - (frame * 15) + 13, 164, es->es_widget.x, - es->es_widget.y, es->es_widget.width, - es->es_widget.height); - else - skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, - ((frame - 14) * 15) + 13, 229, es->es_widget.x, - es->es_widget.y, es->es_widget.width, - es->es_widget.height); - if (es->es_isdragging) - skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, 0, - 176, es->es_widget.x + 1, - es->es_widget.y + es->es_position, 11, 11); - else - skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, 0, - 164, es->es_widget.x + 1, - es->es_widget.y + es->es_position, 11, 11); -} - -void -eqslider_set_mainwin_text(EqSlider * es) -{ - gint band = 0; - const gchar *bandname[11] = { N_("PREAMP"), N_("60HZ"), N_("170HZ"), - N_("310HZ"), N_("600HZ"), N_("1KHZ"), - N_("3KHZ"), N_("6KHZ"), N_("12KHZ"), - N_("14KHZ"), N_("16KHZ") - }; - gchar *tmp; - - if (es->es_widget.x > 21) - band = ((es->es_widget.x - 78) / 18) + 1; - - tmp = - g_strdup_printf("EQ: %s: %+.1f DB", _(bandname[band]), - eqslider_get_position(es)); - mainwin_lock_info_text(tmp); - g_free(tmp); -} - -void -eqslider_button_press_cb(GtkWidget * w, - GdkEventButton * event, - gpointer data) -{ - EqSlider *es = EQ_SLIDER(data); - gint y; - - if (widget_contains(&es->es_widget, event->x, event->y)) { - if (event->button == 1) { - y = event->y - es->es_widget.y; - es->es_isdragging = TRUE; - if (y >= es->es_position && y < es->es_position + 11) - es->es_drag_y = y - es->es_position; - else { - es->es_position = y - 5; - es->es_drag_y = 5; - if (es->es_position < 0) - es->es_position = 0; - if (es->es_position > 50) - es->es_position = 50; - if (es->es_position >= 24 && es->es_position <= 26) - es->es_position = 25; - equalizerwin_eq_changed(); - } - - eqslider_set_mainwin_text(es); - widget_draw(WIDGET(es)); - } - if (event->button == 4) { - es->es_position -= 2; - if (es->es_position < 0) - es->es_position = 0; - equalizerwin_eq_changed(); - widget_draw(WIDGET(es)); - } - } -} - -void -eqslider_mouse_scroll_cb(GtkWidget * w, - GdkEventScroll * event, - gpointer data) -{ - EqSlider *es = EQ_SLIDER(data); - - if (!widget_contains(&es->es_widget, event->x, event->y)) - return; - - if (event->direction == GDK_SCROLL_UP) { - es->es_position -= 2; - - if (es->es_position < 0) - es->es_position = 0; - - equalizerwin_eq_changed(); - widget_draw(WIDGET(es)); - } - else { - es->es_position += 2; - - if (es->es_position > 50) - es->es_position = 50; - - equalizerwin_eq_changed(); - widget_draw(WIDGET(es)); - } -} - -void -eqslider_motion_cb(GtkWidget * w, - GdkEventMotion * event, - gpointer data) -{ - EqSlider *es = EQ_SLIDER(data); - gint y; - - y = event->y - es->es_widget.y; - if (es->es_isdragging) { - es->es_position = y - es->es_drag_y; - if (es->es_position < 0) - es->es_position = 0; - if (es->es_position > 50) - es->es_position = 50; - if (es->es_position >= 24 && es->es_position <= 26) - es->es_position = 25; - equalizerwin_eq_changed(); - eqslider_set_mainwin_text(es); - widget_draw(WIDGET(es)); - } -} - -void -eqslider_button_release_cb(GtkWidget * w, - GdkEventButton * event, - gpointer data) -{ - EqSlider *es = EQ_SLIDER(data); - - if (es->es_isdragging) { - es->es_isdragging = FALSE; - mainwin_release_info_text(); - widget_draw(WIDGET(es)); - } -} - -EqSlider * -create_eqslider(GList ** wlist, - GdkPixmap * parent, - GdkGC * gc, - gint x, gint y) -{ - EqSlider *es; - - es = g_new0(EqSlider, 1); - widget_init(&es->es_widget, parent, gc, x, y, 14, 63, TRUE); - es->es_widget.button_press_cb = eqslider_button_press_cb; - es->es_widget.button_release_cb = eqslider_button_release_cb; - es->es_widget.motion_cb = eqslider_motion_cb; - es->es_widget.draw = eqslider_draw; - es->es_widget.mouse_scroll_cb = eqslider_mouse_scroll_cb; - - widget_list_add(wlist, WIDGET(es)); - - return es; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/eq_slider.h --- a/audacious/eq_slider.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef EQ_SLIDER_H -#define EQ_SLIDER_H - -#include -#include - -#include "widget.h" - -#define EQ_SLIDER(x) ((EqSlider *)(x)) -struct _EqSlider { - Widget es_widget; - gint es_position; - gboolean es_isdragging; - gint es_drag_y; -}; - -typedef struct _EqSlider EqSlider; - -EqSlider *create_eqslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y); -void eqslider_set_position(EqSlider * es, gfloat pos); -gfloat eqslider_get_position(EqSlider * es); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/equalizer.c --- a/audacious/equalizer.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/equalizer.c Wed Aug 09 02:47:22 2006 -0700 @@ -41,17 +41,17 @@ #include #include "dock.h" -#include "eq_graph.h" -#include "eq_slider.h" +#include "widgets/eq_graph.h" +#include "widgets/eq_slider.h" #include "hints.h" -#include "hslider.h" +#include "widgets/hslider.h" #include "input.h" #include "main.h" -#include "pbutton.h" +#include "widgets/pbutton.h" #include "playlist.h" #include "ui_playlist.h" -#include "skin.h" -#include "tbutton.h" +#include "widgets/skin.h" +#include "widgets/tbutton.h" #include "util.h" #include "output.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/equalizer.h --- a/audacious/equalizer.h Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/equalizer.h Wed Aug 09 02:47:22 2006 -0700 @@ -25,7 +25,7 @@ #include #include -#include "pbutton.h" +#include "widgets/pbutton.h" #define EQUALIZER_HEIGHT (gint)(cfg.equalizer_shaded ? 14 : 116) #define EQUALIZER_WIDTH (gint)275 diff -r 237bb7c97759 -r 06329cbf186a audacious/genevent.c --- a/audacious/genevent.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/genevent.c Wed Aug 09 02:47:22 2006 -0700 @@ -67,7 +67,6 @@ #include "ui_playlist.h" #include "pluginenum.h" #include "prefswin.h" -#include "skin.h" #include "skinwin.h" #include "util.h" #include "visualization.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/genevent.h --- a/audacious/genevent.h Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/genevent.h Wed Aug 09 02:47:22 2006 -0700 @@ -26,8 +26,6 @@ #define GENEVENT_H #include "mainwin.h" -#include "textbox.h" -#include "vis.h" extern gboolean ev_waiting; diff -r 237bb7c97759 -r 06329cbf186a audacious/hslider.c --- a/audacious/hslider.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -/* XMMS - Cross-platform multimedia player - * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "hslider.h" - -#include -#include -#include - -#include "skin.h" - -void -hslider_set_position(HSlider * hs, - gint pos) -{ - if (pos == hs->hs_position || hs->hs_pressed) - return; - - hs->hs_position = pos; - - if (hs->hs_frame_cb) - hs->hs_frame = hs->hs_frame_cb(hs->hs_position); - - widget_draw(WIDGET(hs)); -} - -gint -hslider_get_position(HSlider * hs) -{ - return hs->hs_position; -} - -void -hslider_draw(Widget * w) -{ - HSlider *hs = (HSlider *) w; - GdkPixmap *obj; - - obj = hs->hs_widget.parent; - - skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, - hs->hs_skin_index, hs->hs_frame_offset, - hs->hs_frame * hs->hs_frame_height, hs->hs_widget.x, - hs->hs_widget.y, hs->hs_widget.width, - hs->hs_widget.height); - if (hs->hs_pressed) - skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, - hs->hs_skin_index, hs->hs_knob_px, - hs->hs_knob_py, hs->hs_widget.x + hs->hs_position, - hs->hs_widget.y + - ((hs->hs_widget.height - hs->hs_knob_height) / 2), - hs->hs_knob_width, hs->hs_knob_height); - else - skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, - hs->hs_skin_index, hs->hs_knob_nx, hs->hs_knob_ny, - hs->hs_widget.x + hs->hs_position, - hs->hs_widget.y + - ((hs->hs_widget.height - hs->hs_knob_height) / 2), - hs->hs_knob_width, hs->hs_knob_height); -} - -void -hslider_button_press_cb(GtkWidget * w, - GdkEventButton * event, - gpointer data) -{ - HSlider *hs = HSLIDER(data); - gint x; - - if (event->button != 1) - return; - - if (widget_contains(&hs->hs_widget, event->x, event->y)) { - x = event->x - hs->hs_widget.x; - hs->hs_pressed = TRUE; - - if (x >= hs->hs_position && x < hs->hs_position + hs->hs_knob_width) - hs->hs_pressed_x = x - hs->hs_position; - else { - hs->hs_position = x - (hs->hs_knob_width / 2); - hs->hs_pressed_x = hs->hs_knob_width / 2; - if (hs->hs_position < hs->hs_min) - hs->hs_position = hs->hs_min; - if (hs->hs_position > hs->hs_max) - hs->hs_position = hs->hs_max; - if (hs->hs_frame_cb) - hs->hs_frame = hs->hs_frame_cb(hs->hs_position); - - } - - if (hs->hs_motion_cb) - hs->hs_motion_cb(hs->hs_position); - - widget_draw(WIDGET(hs)); - } -} - -void -hslider_motion_cb(GtkWidget * w, GdkEventMotion * event, gpointer data) -{ - HSlider *hs = (HSlider *) data; - gint x; - - if (hs->hs_pressed) { - if (!hs->hs_widget.visible) { - hs->hs_pressed = FALSE; - return; - } - - x = event->x - hs->hs_widget.x; - hs->hs_position = x - hs->hs_pressed_x; - - if (hs->hs_position < hs->hs_min) - hs->hs_position = hs->hs_min; - - if (hs->hs_position > hs->hs_max) - hs->hs_position = hs->hs_max; - - if (hs->hs_frame_cb) - hs->hs_frame = hs->hs_frame_cb(hs->hs_position); - - if (hs->hs_motion_cb) - hs->hs_motion_cb(hs->hs_position); - - widget_draw(WIDGET(hs)); - } -} - -void -hslider_button_release_cb(GtkWidget * w, - GdkEventButton * event, - gpointer data) -{ - HSlider *hs = HSLIDER(data); - - if (hs->hs_pressed) { - hs->hs_pressed = FALSE; - - if (hs->hs_release_cb) - hs->hs_release_cb(hs->hs_position); - - widget_draw(WIDGET(hs)); - } -} - -HSlider * -create_hslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint knx, gint kny, - gint kpx, gint kpy, gint kw, gint kh, gint fh, - gint fo, gint min, gint max, gint(*fcb) (gint), - void (*mcb) (gint), void (*rcb) (gint), SkinPixmapId si) -{ - HSlider *hs; - - hs = g_new0(HSlider, 1); - widget_init(&hs->hs_widget, parent, gc, x, y, w, h, 1); - hs->hs_widget.button_press_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - hslider_button_press_cb; - hs->hs_widget.button_release_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - hslider_button_release_cb; - hs->hs_widget.motion_cb = - (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) - hslider_motion_cb; - hs->hs_widget.draw = hslider_draw; - hs->hs_knob_nx = knx; - hs->hs_knob_ny = kny; - hs->hs_knob_px = kpx; - hs->hs_knob_py = kpy; - hs->hs_knob_width = kw; - hs->hs_knob_height = kh; - hs->hs_frame_height = fh; - hs->hs_frame_offset = fo; - hs->hs_min = min; - hs->hs_position = min; - hs->hs_max = max; - hs->hs_frame_cb = fcb; - hs->hs_motion_cb = mcb; - hs->hs_release_cb = rcb; - if (hs->hs_frame_cb) - hs->hs_frame = hs->hs_frame_cb(0); - hs->hs_skin_index = si; - - widget_list_add(wlist, WIDGET(hs)); - - return hs; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/hslider.h --- a/audacious/hslider.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* XMMS - Cross-platform multimedia player - * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef HSLIDER_H -#define HSLIDER_H - -#include -#include - -#include "skin.h" -#include "widget.h" - -#define HSLIDER(x) ((HSlider *)(x)) -struct _HSlider { - Widget hs_widget; - gint hs_frame, hs_frame_offset, hs_frame_height, hs_min, hs_max; - gint hs_knob_nx, hs_knob_ny, hs_knob_px, hs_knob_py; - gint hs_knob_width, hs_knob_height; - gint hs_position; - gboolean hs_pressed; - gint hs_pressed_x, hs_pressed_y; - gint(*hs_frame_cb) (gint); - void (*hs_motion_cb) (gint); - void (*hs_release_cb) (gint); - SkinPixmapId hs_skin_index; -}; - -typedef struct _HSlider HSlider; - -HSlider *create_hslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint knx, gint kny, - gint kpx, gint kpy, gint kw, gint kh, gint fh, - gint fo, gint min, gint max, gint(*fcb) (gint), - void (*mcb) (gint), void (*rcb) (gint), - SkinPixmapId si); - -void hslider_set_position(HSlider * hs, gint pos); -gint hslider_get_position(HSlider * hs); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/input.c --- a/audacious/input.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/input.c Wed Aug 09 02:47:22 2006 -0700 @@ -36,7 +36,7 @@ #include "util.h" #include "visualization.h" #include "playback.h" -#include "playstatus.h" +#include "widgets/playstatus.h" #include "pluginenum.h" #include "libaudacious/titlestring.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/main.c --- a/audacious/main.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/main.c Wed Aug 09 02:47:22 2006 -0700 @@ -68,7 +68,6 @@ #include "ui_playlist.h" #include "pluginenum.h" #include "prefswin.h" -#include "skin.h" #include "skinwin.h" #include "util.h" #include "visualization.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/main.h --- a/audacious/main.h Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/main.h Wed Aug 09 02:47:22 2006 -0700 @@ -23,8 +23,8 @@ #define MAIN_H #include "mainwin.h" -#include "textbox.h" -#include "vis.h" +#include "widgets/textbox.h" +#include "widgets/vis.h" #include #include diff -r 237bb7c97759 -r 06329cbf186a audacious/mainwin.c --- a/audacious/mainwin.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/mainwin.c Wed Aug 09 02:47:22 2006 -0700 @@ -41,7 +41,7 @@ #include -#include "textbox.h" +#include "widgets/textbox.h" #include "mainwin.h" #include "pixmaps.h" @@ -60,20 +60,20 @@ #include "prefswin.h" #include "skinwin.h" #include "genevent.h" -#include "hslider.h" -#include "menurow.h" -#include "monostereo.h" -#include "pbutton.h" +#include "widgets/hslider.h" +#include "widgets/menurow.h" +#include "widgets/monostereo.h" +#include "widgets/pbutton.h" #include "playback.h" #include "playlist.h" -#include "playlist_list.h" -#include "playstatus.h" -#include "sbutton.h" -#include "svis.h" -#include "textbox.h" +#include "widgets/playlist_list.h" +#include "widgets/playstatus.h" +#include "widgets/sbutton.h" +#include "widgets/svis.h" +#include "widgets/textbox.h" #include "urldecode.h" #include "util.h" -#include "vis.h" +#include "widgets/vis.h" #include "visualization.h" #include "libaudacious/configdb.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/mainwin.h --- a/audacious/mainwin.h Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/mainwin.h Wed Aug 09 02:47:22 2006 -0700 @@ -24,14 +24,14 @@ #include -#include "number.h" -#include "pbutton.h" -#include "playstatus.h" -#include "tbutton.h" -#include "textbox.h" -#include "svis.h" -#include "vis.h" -#include "hslider.h" +#include "widgets/number.h" +#include "widgets/pbutton.h" +#include "widgets/playstatus.h" +#include "widgets/tbutton.h" +#include "widgets/textbox.h" +#include "widgets/svis.h" +#include "widgets/vis.h" +#include "widgets/hslider.h" /* yes, main window size is fixed */ #define MAINWIN_WIDTH (gint)275 diff -r 237bb7c97759 -r 06329cbf186a audacious/menurow.c --- a/audacious/menurow.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "menurow.h" - -#include -#include - -#include "main.h" -#include "menurow.h" -#include "widget.h" - -void -menurow_draw(Widget * widget) -{ - MenuRow *mr = MENU_ROW(widget); - - GdkPixmap *obj = mr->mr_widget.parent; - - if (mr->mr_selected == MENUROW_NONE) { - if (cfg.always_show_cb || mr->mr_bpushed) - skin_draw_pixmap(bmp_active_skin, obj, - mr->mr_widget.gc, - mr->mr_skin_index, - mr->mr_nx, mr->mr_ny, - mr->mr_widget.x, mr->mr_widget.y, 8, 43); - else - skin_draw_pixmap(bmp_active_skin, obj, - mr->mr_widget.gc, - mr->mr_skin_index, - mr->mr_nx + 8, mr->mr_ny, - mr->mr_widget.x, mr->mr_widget.y, 8, 43); - } - else { - skin_draw_pixmap(bmp_active_skin, obj, - mr->mr_widget.gc, - mr->mr_skin_index, - mr->mr_sx + ((mr->mr_selected - 1) * 8), - mr->mr_sy, mr->mr_widget.x, mr->mr_widget.y, 8, 43); - } - if (cfg.always_show_cb || mr->mr_bpushed) { - if (mr->mr_always_selected) - skin_draw_pixmap(bmp_active_skin, obj, - mr->mr_widget.gc, - mr->mr_skin_index, - mr->mr_sx + 8, mr->mr_sy + 10, - mr->mr_widget.x, mr->mr_widget.y + 10, 8, 8); - if (mr->mr_doublesize_selected) - skin_draw_pixmap(bmp_active_skin, obj, - mr->mr_widget.gc, - mr->mr_skin_index, - mr->mr_sx + 24, mr->mr_sy + 26, - mr->mr_widget.x, mr->mr_widget.y + 26, 8, 8); - } - -} - -MenuRowItem -menurow_find_selected(MenuRow * mr, gint x, gint y) -{ - MenuRowItem ret = MENUROW_NONE; - - x -= mr->mr_widget.x; - y -= mr->mr_widget.y; - if (x > 0 && x < 8) { - if (y >= 0 && y <= 10) - ret = MENUROW_OPTIONS; - if (y >= 10 && y <= 17) - ret = MENUROW_ALWAYS; - if (y >= 18 && y <= 25) - ret = MENUROW_FILEINFOBOX; - if (y >= 26 && y <= 33) - ret = MENUROW_DOUBLESIZE; - if (y >= 34 && y <= 42) - ret = MENUROW_VISUALIZATION; - } - return ret; -} - -void -menurow_button_press(GtkWidget * widget, - GdkEventButton * event, - gpointer data) -{ - MenuRow *mr = MENU_ROW(data); - - if (event->button != 1) - return; - - if (widget_contains(&mr->mr_widget, event->x, event->y)) { - mr->mr_bpushed = TRUE; - mr->mr_selected = menurow_find_selected(mr, event->x, event->y); - - widget_draw(WIDGET(mr)); - - if (mr->mr_change_callback) - mr->mr_change_callback(mr->mr_selected); - } -} - -void -menurow_motion(GtkWidget * widget, - GdkEventMotion * event, - gpointer data) -{ - MenuRow *mr = MENU_ROW(data); - - if (mr->mr_bpushed) { - mr->mr_selected = menurow_find_selected(mr, event->x, event->y); - - widget_draw(WIDGET(mr)); - - if (mr->mr_change_callback) - mr->mr_change_callback(mr->mr_selected); - } -} - -void -menurow_button_release(GtkWidget * widget, - GdkEventButton * event, - gpointer data) -{ - MenuRow *mr = MENU_ROW(data); - - if (mr->mr_bpushed) { - mr->mr_bpushed = FALSE; - - if (mr->mr_selected == MENUROW_ALWAYS) - mr->mr_always_selected = !mr->mr_always_selected; - - if (mr->mr_selected == MENUROW_DOUBLESIZE) - mr->mr_doublesize_selected = !mr->mr_doublesize_selected; - - if ((int)(mr->mr_selected) != -1 && mr->mr_release_callback) - mr->mr_release_callback(mr->mr_selected); - - mr->mr_selected = MENUROW_NONE; - - widget_draw(WIDGET(mr)); - } -} - -MenuRow * -create_menurow(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint nx, gint ny, gint sx, gint sy, - void (*ccb) (MenuRowItem), - void (*rcb) (MenuRowItem), SkinPixmapId si) -{ - MenuRow *mr; - - mr = g_new0(MenuRow, 1); - widget_init(&mr->mr_widget, parent, gc, x, y, 8, 43, 1); - mr->mr_widget.draw = menurow_draw; - mr->mr_widget.button_press_cb = menurow_button_press; - mr->mr_widget.motion_cb = menurow_motion; - mr->mr_widget.button_release_cb = menurow_button_release; - mr->mr_nx = nx; - mr->mr_ny = ny; - mr->mr_sx = sx; - mr->mr_sy = sy; - mr->mr_selected = MENUROW_NONE; - mr->mr_change_callback = ccb; - mr->mr_release_callback = rcb; - mr->mr_skin_index = si; - - widget_list_add(wlist, WIDGET(mr)); - return mr; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/menurow.h --- a/audacious/menurow.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef MENUROW_H -#define MENUROW_H - -#include -#include - -#include "skin.h" -#include "widget.h" - -typedef enum { - MENUROW_NONE, MENUROW_OPTIONS, MENUROW_ALWAYS, MENUROW_FILEINFOBOX, - MENUROW_DOUBLESIZE, MENUROW_VISUALIZATION -} MenuRowItem; - -#define MENU_ROW(x) ((MenuRow *)(x)) -struct _MenuRow { - Widget mr_widget; - gint mr_nx, mr_ny; - gint mr_sx, mr_sy; - MenuRowItem mr_selected; - gboolean mr_bpushed; - gboolean mr_always_selected; - gboolean mr_doublesize_selected; - void (*mr_change_callback) (MenuRowItem); - void (*mr_release_callback) (MenuRowItem); - SkinPixmapId mr_skin_index; -}; - -typedef struct _MenuRow MenuRow; - -MenuRow *create_menurow(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint nx, gint ny, gint sx, gint sy, - void (*ccb) (MenuRowItem), - void (*rcb) (MenuRowItem), SkinPixmapId si); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/monostereo.c --- a/audacious/monostereo.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "monostereo.h" - -#include -#include - -#include "skin.h" -#include "widget.h" - -void -monostereo_draw(Widget * widget) -{ - MonoStereo *ms = (MonoStereo *) widget; - GdkPixmap *obj; - - obj = ms->ms_widget.parent; - - switch (ms->ms_num_channels) { - case 0: - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 29, 12, - ms->ms_widget.x, ms->ms_widget.y, 27, 12); - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 0, 12, - ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); - break; - case 1: - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 29, 0, - ms->ms_widget.x, ms->ms_widget.y, 27, 12); - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 0, 12, - ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); - break; - case 2: - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 29, 12, - ms->ms_widget.x, ms->ms_widget.y, 27, 12); - skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, - ms->ms_skin_index, 0, 0, - ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); - break; - } -} - -void -monostereo_set_num_channels(MonoStereo * ms, - gint nch) -{ - if (!ms) - return; - - ms->ms_num_channels = nch; - widget_draw(WIDGET(ms)); -} - -MonoStereo * -create_monostereo(GList ** wlist, - GdkPixmap * parent, - GdkGC * gc, - gint x, gint y, - SkinPixmapId si) -{ - MonoStereo *ms; - - ms = g_new0(MonoStereo, 1); - widget_init(&ms->ms_widget, parent, gc, x, y, 56, 12, 1); - ms->ms_widget.draw = monostereo_draw; - ms->ms_skin_index = si; - - widget_list_add(wlist, WIDGET(ms)); - return ms; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/monostereo.h --- a/audacious/monostereo.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef MONOSTEREO_H -#define MONOSTEREO_H - -#include -#include - -#include "skin.h" -#include "widget.h" - -#define MONO_STEREO(x) ((MonoStereo *)(x)) -struct _MonoStereo { - Widget ms_widget; - gint ms_num_channels; - SkinPixmapId ms_skin_index; -}; - -typedef struct _MonoStereo MonoStereo; - -MonoStereo *create_monostereo(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y, SkinPixmapId si); -void monostereo_set_num_channels(MonoStereo * ms, gint nch); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/number.c --- a/audacious/number.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "number.h" - -#include -#include - -#include "skin.h" - -void -number_set_number(Number * nu, - gint number) -{ - if (number == nu->nu_number) - return; - - nu->nu_number = number; - widget_draw(WIDGET(nu)); -} - -void -number_draw(Widget * w) -{ - Number *nu = NUMBER(w); - GdkPixmap *obj; - - obj = nu->nu_widget.parent; - - if (nu->nu_number <= 11) - skin_draw_pixmap(bmp_active_skin, obj, nu->nu_widget.gc, - nu->nu_skin_index, nu->nu_number * 9, 0, - nu->nu_widget.x, nu->nu_widget.y, 9, 13); - else - skin_draw_pixmap(bmp_active_skin, obj, nu->nu_widget.gc, - nu->nu_skin_index, 90, 0, nu->nu_widget.x, - nu->nu_widget.y, 9, 13); -} - -Number * -create_number(GList ** wlist, - GdkPixmap * parent, - GdkGC * gc, - gint x, gint y, - SkinPixmapId si) -{ - Number *nu; - - nu = g_new0(Number, 1); - widget_init(&nu->nu_widget, parent, gc, x, y, 9, 13, 1); - nu->nu_widget.draw = number_draw; - nu->nu_number = 10; - nu->nu_skin_index = si; - - widget_list_add(wlist, WIDGET(nu)); - return nu; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/number.h --- a/audacious/number.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef NUMBER_H -#define NUMBER_H - -#include -#include - -#include "widget.h" -#include "skin.h" - -#define NUMBER(x) ((Number *)(x)) -struct _Number { - Widget nu_widget; - gint nu_number; - SkinPixmapId nu_skin_index; -}; - -typedef struct _Number Number; - -void number_set_number(Number * nu, gint number); -Number *create_number(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, SkinPixmapId si); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/pbutton.c --- a/audacious/pbutton.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "pbutton.h" - -#include -#include -#include - -#include "skin.h" -#include "widget.h" - -void -pbutton_draw(PButton * button) -{ - GdkPixmap *obj; - - if (button->pb_allow_draw) { - obj = button->pb_widget.parent; - - if (button->pb_pressed && button->pb_inside) { - skin_draw_pixmap(bmp_active_skin, obj, - button->pb_widget.gc, - button->pb_skin_index2, button->pb_px, - button->pb_py, button->pb_widget.x, - button->pb_widget.y, - button->pb_widget.width, - button->pb_widget.height); - } - else { - skin_draw_pixmap(bmp_active_skin, obj, - button->pb_widget.gc, - button->pb_skin_index1, - button->pb_nx, button->pb_ny, - button->pb_widget.x, button->pb_widget.y, - button->pb_widget.width, - button->pb_widget.height); - } - } -} - -void -pbutton_button_press_cb(GtkWidget * widget, - GdkEventButton * event, - PButton * button) -{ - if (event->button != 1) - return; - - if (widget_contains(&button->pb_widget, event->x, event->y)) { - button->pb_pressed = 1; - button->pb_inside = 1; - widget_draw(WIDGET(button)); - if (button->pb_push_cb) - button->pb_push_cb(); - } -} - -void -pbutton_button_release_cb(GtkWidget * widget, - GdkEventButton * event, - PButton * button) -{ - if (event->button != 1) - return; - if (button->pb_inside && button->pb_pressed) { - button->pb_inside = 0; - widget_draw(WIDGET(button)); - if (button->pb_release_cb) - button->pb_release_cb(); - } - if (button->pb_pressed) - button->pb_pressed = 0; -} - -void -pbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, - PButton * button) -{ - gint inside; - - if (!button->pb_pressed) - return; - - inside = widget_contains(&button->pb_widget, event->x, event->y); - - if (inside != button->pb_inside) { - button->pb_inside = inside; - widget_draw(WIDGET(button)); - } -} - -void -pbutton_set_skin_index(PButton * b, SkinPixmapId si) -{ - b->pb_skin_index1 = b->pb_skin_index2 = si; -} - -void -pbutton_set_skin_index1(PButton * b, SkinPixmapId si) -{ - b->pb_skin_index1 = si; -} - -void -pbutton_set_skin_index2(PButton * b, SkinPixmapId si) -{ - b->pb_skin_index2 = si; -} - -void -pbutton_set_button_data(PButton * b, gint nx, gint ny, gint px, gint py) -{ - if (nx > -1) - b->pb_nx = nx; - if (ny > -1) - b->pb_ny = ny; - if (px > -1) - b->pb_px = px; - if (py > -1) - b->pb_py = py; -} - - -PButton * -create_pbutton_ex(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nx, - gint ny, gint px, gint py, void (*push_cb) (void), - void (*release_cb) (void), - SkinPixmapId si1, SkinPixmapId si2) -{ - PButton *b; - - b = g_new0(PButton, 1); - widget_init(&b->pb_widget, parent, gc, x, y, w, h, 1); - b->pb_widget.button_press_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - pbutton_button_press_cb; - b->pb_widget.button_release_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - pbutton_button_release_cb; - b->pb_widget.motion_cb = - (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) - pbutton_motion_cb; - - b->pb_widget.draw = (void (*)(Widget *)) pbutton_draw; - b->pb_nx = nx; - b->pb_ny = ny; - b->pb_px = px; - b->pb_py = py; - b->pb_push_cb = push_cb; - b->pb_release_cb = release_cb; - b->pb_skin_index1 = si1; - b->pb_skin_index2 = si2; - b->pb_allow_draw = TRUE; - b->pb_inside = 0; - b->pb_pressed = 0; - widget_list_add(wlist, WIDGET(b)); - - return b; -} - -PButton * -create_pbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nx, gint ny, - gint px, gint py, void (*cb) (void), SkinPixmapId si) -{ - return create_pbutton_ex(wlist, parent, gc, x, y, w, h, nx, ny, px, py, - NULL, cb, si, si); -} - -void -free_pbutton(PButton * b) -{ - g_free(b); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/pbutton.h --- a/audacious/pbutton.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef PBUTTON_H -#define PBUTTON_H - -#include -#include - -#include "widget.h" -#include "skin.h" - -#define PBUTTON(x) ((PButton *)(x)) -struct _PButton { - Widget pb_widget; - gint pb_nx, pb_ny; - gint pb_px, pb_py; - gboolean pb_pressed; - gboolean pb_inside; - gboolean pb_allow_draw; - void (*pb_push_cb) (void); - void (*pb_release_cb) (void); - SkinPixmapId pb_skin_index1, pb_skin_index2; -}; - -typedef struct _PButton PButton; - -PButton *create_pbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nx, gint ny, - gint px, gint py, void (*push_cb) (void), SkinPixmapId si); -PButton *create_pbutton_ex(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nx, - gint ny, gint px, gint py, void (*push_cb) (void), - void (*release_cb) (void), SkinPixmapId si1, - SkinPixmapId si2); -void free_pbutton(PButton * b); -void pbutton_set_skin_index(PButton * b, SkinPixmapId si); -void pbutton_set_skin_index1(PButton * b, SkinPixmapId si); -void pbutton_set_skin_index2(PButton * b, SkinPixmapId si); -void pbutton_set_button_data(PButton * b, gint nx, gint ny, gint px, gint py); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/playback.c --- a/audacious/playback.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/playback.c Wed Aug 09 02:47:22 2006 -0700 @@ -45,8 +45,6 @@ #include "output.h" #include "playlist.h" #include "ui_playlist.h" -#include "playlist_list.h" -#include "skin.h" #include "skinwin.h" #include "urldecode.h" #include "util.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/playlist.c --- a/audacious/playlist.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/playlist.c Wed Aug 09 02:47:22 2006 -0700 @@ -50,8 +50,6 @@ #include "playback.h" #include "playlist.h" #include "ui_playlist.h" -#include "playlist_list.h" -#include "skin.h" #include "urldecode.h" #include "util.h" #include "ui_fileinfo.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/playlist_list.c --- a/audacious/playlist_list.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,954 +0,0 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2006 Audacious development team. - * - * BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/* - * A note about Pango and some funky spacey fonts: Weirdly baselined - * fonts, or fonts with weird ascents or descents _will_ display a - * little bit weird in the playlist widget, but the display engine - * won't make it look too bad, just a little deranged. I honestly - * don't think it's worth fixing (around...), it doesn't have to be - * perfectly fitting, just the general look has to be ok, which it - * IMHO is. - * - * A second note: The numbers aren't perfectly aligned, but in the - * end it looks better when using a single Pango layout for each - * number. - */ - -#include "playlist_list.h" - -#include -#include - -#include "main.h" -#include "input.h" -#include "playback.h" -#include "playlist.h" -#include "ui_playlist.h" -#include "util.h" - -#include "debug.h" - -static PangoFontDescription *playlist_list_font = NULL; -static gint ascent, descent, width_delta_digit_one; -static gboolean has_slant; -static guint padding; - -/* FIXME: the following globals should not be needed. */ -static gint width_approx_letters; -static gint width_colon, width_colon_third; -static gint width_approx_digits, width_approx_digits_half; - -GdkPixmap *rootpix; - -void playlist_list_draw(Widget * w); - -/* Sort of stolen from XChat, but not really, as theres uses Xlib */ -static void -shade_gdkimage_generic (GdkVisual *visual, GdkImage *ximg, int bpl, int w, int h, int rm, int gm, int bm, int bg) -{ - int x, y; - int bgr = (256 - rm) * (bg & visual->red_mask); - int bgg = (256 - gm) * (bg & visual->green_mask); - int bgb = (256 - bm) * (bg & visual->blue_mask); - - for (x = 0; x < w; x++) - { - for (y = 0; y < h; y++) - { - unsigned long pixel = gdk_image_get_pixel (ximg, x, y); - int r, g, b; - - r = rm * (pixel & visual->red_mask) + bgr; - g = gm * (pixel & visual->green_mask) + bgg; - b = bm * (pixel & visual->blue_mask) + bgb; - - gdk_image_put_pixel (ximg, x, y, - ((r >> 8) & visual->red_mask) | - ((g >> 8) & visual->green_mask) | - ((b >> 8) & visual->blue_mask)); - } - } -} - -/* and this is definately mine... -nenolod */ -GdkPixmap * -shade_pixmap(GdkPixmap *in, gint x, gint y, gint x_offset, gint y_offset, gint w, gint h, GdkColor *shade_color) -{ - GdkImage *ximg; - GdkPixmap *p = gdk_pixmap_new(in, w, h, -1); - GdkGC *gc = gdk_gc_new(p); - - gdk_draw_pixmap(p, gc, in, x, y, 0, 0, w, h); - - gdk_error_trap_push(); - - ximg = gdk_drawable_copy_to_image(in, NULL, x, y, 0, 0, w, h); /* copy */ - - gdk_error_trap_pop(); - - shade_gdkimage_generic(gdk_drawable_get_visual(GDK_WINDOW(playlistwin->window)), - ximg, ximg->bpl, w, h, 60, 60, 60, shade_color->pixel); - - gdk_draw_image(p, gc, ximg, 0, 0, x, y, w, h); - - g_object_unref(gc); - - return p; -} - -#ifdef GDK_WINDOWING_X11 - -#include -#include -#include - -GdkDrawable *get_transparency_pixmap(void) -{ - GdkDrawable *root; - XID *pixmaps; - GdkAtom prop_type; - gint prop_size; - GdkPixmap *pixmap; - gboolean ret; - - root = gdk_get_default_root_window(); - - pixmap = NULL; - pixmaps = NULL; - - gdk_error_trap_push(); - - ret = gdk_property_get(root, gdk_atom_intern("_XROOTPMAP_ID", TRUE), - 0, 0, INT_MAX - 3, - FALSE, - &prop_type, NULL, &prop_size, - (guchar **) &pixmaps); - - gdk_error_trap_pop(); - - if ((ret == TRUE) && (prop_type == GDK_TARGET_PIXMAP) && (prop_size >= sizeof(XID)) && (pixmaps != NULL)) - { - pixmap = gdk_pixmap_foreign_new_for_display(gdk_drawable_get_display(root), - pixmaps[0]); - - if (pixmaps != NULL) - g_free(pixmaps); - } - - return GDK_DRAWABLE(pixmap); -} - -static GdkFilterReturn -root_event_cb (GdkXEvent *xev, GdkEventProperty *event, gpointer data) -{ - static Atom at = None; - XEvent *xevent = (XEvent *)xev; - - if (xevent->type == PropertyNotify) - { - if (at == None) - at = XInternAtom (xevent->xproperty.display, "_XROOTPMAP_ID", True); - - if (at == xevent->xproperty.atom) - { - rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), - skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); - - if (cfg.playlist_transparent) - { - playlistwin_update_list(); - draw_playlist_window(TRUE); - } - } - } - - return GDK_FILTER_CONTINUE; -} - -#else - -GdkPixmap *get_transparency_pixmap(void) -{ - return NULL; -} - -#endif - -static gboolean -playlist_list_auto_drag_down_func(gpointer data) -{ - PlayList_List *pl = data; - - if (pl->pl_auto_drag_down) { - playlist_list_move_down(pl); - pl->pl_first++; - playlistwin_update_list(); - return TRUE; - } - return FALSE; -} - -static gboolean -playlist_list_auto_drag_up_func(gpointer data) -{ - PlayList_List *pl = data; - - if (pl->pl_auto_drag_up) { - playlist_list_move_up(pl); - pl->pl_first--; - playlistwin_update_list(); - return TRUE; - - } - return FALSE; -} - -void -playlist_list_move_up(PlayList_List * pl) -{ - GList *list; - - PLAYLIST_LOCK(); - if ((list = playlist_get()) == NULL) { - PLAYLIST_UNLOCK(); - return; - } - if (PLAYLIST_ENTRY(list->data)->selected) { - /* We are at the top */ - PLAYLIST_UNLOCK(); - return; - } - while (list) { - if (PLAYLIST_ENTRY(list->data)->selected) - glist_moveup(list); - list = g_list_next(list); - } - PLAYLIST_UNLOCK(); - if (pl->pl_prev_selected != -1) - pl->pl_prev_selected--; - if (pl->pl_prev_min != -1) - pl->pl_prev_min--; - if (pl->pl_prev_max != -1) - pl->pl_prev_max--; -} - -void -playlist_list_move_down(PlayList_List * pl) -{ - GList *list; - - PLAYLIST_LOCK(); - - if (!(list = g_list_last(playlist_get()))) { - PLAYLIST_UNLOCK(); - return; - } - - if (PLAYLIST_ENTRY(list->data)->selected) { - /* We are at the bottom */ - PLAYLIST_UNLOCK(); - return; - } - - while (list) { - if (PLAYLIST_ENTRY(list->data)->selected) - glist_movedown(list); - list = g_list_previous(list); - } - - PLAYLIST_UNLOCK(); - - if (pl->pl_prev_selected != -1) - pl->pl_prev_selected++; - if (pl->pl_prev_min != -1) - pl->pl_prev_min++; - if (pl->pl_prev_max != -1) - pl->pl_prev_max++; -} - -static void -playlist_list_button_press_cb(GtkWidget * widget, - GdkEventButton * event, - PlayList_List * pl) -{ - gint nr, y; - - if (event->button == 1 && pl->pl_fheight && - widget_contains(&pl->pl_widget, event->x, event->y)) { - - y = event->y - pl->pl_widget.y; - nr = (y / pl->pl_fheight) + pl->pl_first; - - if (nr >= playlist_get_length()) - nr = playlist_get_length() - 1; - - if (!(event->state & GDK_CONTROL_MASK)) - playlist_select_all(FALSE); - - if (event->state & GDK_SHIFT_MASK && pl->pl_prev_selected != -1) { - playlist_select_range(pl->pl_prev_selected, nr, TRUE); - pl->pl_prev_min = pl->pl_prev_selected; - pl->pl_prev_max = nr; - pl->pl_drag_pos = nr - pl->pl_first; - } - else { - if (playlist_select_invert(nr)) { - if (event->state & GDK_CONTROL_MASK) { - if (pl->pl_prev_min == -1) { - pl->pl_prev_min = pl->pl_prev_selected; - pl->pl_prev_max = pl->pl_prev_selected; - } - if (nr < pl->pl_prev_min) - pl->pl_prev_min = nr; - else if (nr > pl->pl_prev_max) - pl->pl_prev_max = nr; - } - else - pl->pl_prev_min = -1; - pl->pl_prev_selected = nr; - pl->pl_drag_pos = nr - pl->pl_first; - } - } - if (event->type == GDK_2BUTTON_PRESS) { - /* - * Ungrab the pointer to prevent us from - * hanging on to it during the sometimes slow - * bmp_playback_initiate(). - */ - gdk_pointer_ungrab(GDK_CURRENT_TIME); - gdk_flush(); - playlist_set_position(nr); - if (!bmp_playback_get_playing()) - bmp_playback_initiate(); - } - - pl->pl_dragging = TRUE; - playlistwin_update_list(); - } -} - -gint -playlist_list_get_playlist_position(PlayList_List * pl, - gint x, - gint y) -{ - gint iy, length; - - if (!widget_contains(WIDGET(pl), x, y) || !pl->pl_fheight) - return -1; - - if ((length = playlist_get_length()) == 0) - return -1; - iy = y - pl->pl_widget.y; - - return (MIN((iy / pl->pl_fheight) + pl->pl_first, length - 1)); -} - -static void -playlist_list_motion_cb(GtkWidget * widget, - GdkEventMotion * event, - PlayList_List * pl) -{ - gint nr, y, off, i; - - if (pl->pl_dragging) { - y = event->y - pl->pl_widget.y; - nr = (y / pl->pl_fheight); - if (nr < 0) { - nr = 0; - if (!pl->pl_auto_drag_up) { - pl->pl_auto_drag_up = TRUE; - pl->pl_auto_drag_up_tag = - gtk_timeout_add(100, playlist_list_auto_drag_up_func, pl); - } - } - else if (pl->pl_auto_drag_up) - pl->pl_auto_drag_up = FALSE; - - if (nr >= pl->pl_num_visible) { - nr = pl->pl_num_visible - 1; - if (!pl->pl_auto_drag_down) { - pl->pl_auto_drag_down = TRUE; - pl->pl_auto_drag_down_tag = - gtk_timeout_add(100, playlist_list_auto_drag_down_func, - pl); - } - } - else if (pl->pl_auto_drag_down) - pl->pl_auto_drag_down = FALSE; - - off = nr - pl->pl_drag_pos; - if (off) { - for (i = 0; i < abs(off); i++) { - if (off < 0) - playlist_list_move_up(pl); - else - playlist_list_move_down(pl); - - } - playlistwin_update_list(); - } - pl->pl_drag_pos = nr; - } -} - -static void -playlist_list_button_release_cb(GtkWidget * widget, - GdkEventButton * event, - PlayList_List * pl) -{ - pl->pl_dragging = FALSE; - pl->pl_auto_drag_down = FALSE; - pl->pl_auto_drag_up = FALSE; -} - -static void -playlist_list_draw_string(PlayList_List * pl, - PangoFontDescription * font, - gint line, - gint width, - const gchar * text, - guint ppos) -{ - guint plist_length_int; - - PangoLayout *layout; - - REQUIRE_STATIC_LOCK(playlist); - - if (cfg.show_numbers_in_pl) { - gchar *pos_string = g_strdup_printf(cfg.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos); - plist_length_int = - gint_count_digits(playlist_get_length_nolock()) + !cfg.show_separator_in_pl + 1; /* cf.show_separator_in_pl will be 0 if false */ - - padding = plist_length_int; - padding = ((padding + 1) * width_approx_digits); - - layout = gtk_widget_create_pango_layout(playlistwin, pos_string); - pango_layout_set_font_description(layout, playlist_list_font); - pango_layout_set_width(layout, plist_length_int * 100); - - pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); - gdk_draw_layout(pl->pl_widget.parent, pl->pl_widget.gc, - pl->pl_widget.x + - (width_approx_digits * - (-1 + plist_length_int - strlen(pos_string))) + - (width_approx_digits / 4), - pl->pl_widget.y + (line - 1) * pl->pl_fheight + - ascent + abs(descent), layout); - g_free(pos_string); - g_object_unref(layout); - - if (!cfg.show_separator_in_pl) - padding -= (width_approx_digits * 1.5); - } - else { - padding = 3; - } - - width -= padding; - - layout = gtk_widget_create_pango_layout(playlistwin, text); - - pango_layout_set_font_description(layout, playlist_list_font); - pango_layout_set_width(layout, width * PANGO_SCALE); - pango_layout_set_single_paragraph_mode(layout, TRUE); - pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); - gdk_draw_layout(pl->pl_widget.parent, pl->pl_widget.gc, - pl->pl_widget.x + padding + (width_approx_letters / 4), - pl->pl_widget.y + (line - 1) * pl->pl_fheight + - ascent + abs(descent), layout); - - g_object_unref(layout); -} - -void -playlist_list_draw(Widget * w) -{ - PlayList_List *pl = PLAYLIST_LIST(w); - GList *list; - GdkGC *gc; - GdkPixmap *obj; - PangoLayout *layout; - gchar *title; - gint width, height; - gint i, max_first; - guint padding, padding_dwidth, padding_plength; - guint max_time_len = 0; - gfloat queue_tailpadding = 0; - gint tpadding; - gsize tpadding_dwidth = 0; - gint x, y; - guint tail_width; - guint tail_len; - - gchar tail[100]; - gchar queuepos[255]; - gchar length[40]; - - gchar **frags; - gchar *frag0; - - gint plw_w, plw_h; - - GdkRectangle *playlist_rect; - - gc = pl->pl_widget.gc; - - width = pl->pl_widget.width; - height = pl->pl_widget.height; - - obj = pl->pl_widget.parent; - - gtk_window_get_size(GTK_WINDOW(playlistwin), &plw_w, &plw_h); - - playlist_rect = g_new0(GdkRectangle, 1); - - playlist_rect->x = 0; - playlist_rect->y = 0; - playlist_rect->width = plw_w - 17; - playlist_rect->height = plw_h - 36; - - gdk_gc_set_clip_origin(gc, 31, 58); - gdk_gc_set_clip_rectangle(gc, playlist_rect); - - if (cfg.playlist_transparent == FALSE) - { - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_NORMALBG)); - gdk_draw_rectangle(obj, gc, TRUE, pl->pl_widget.x, pl->pl_widget.y, - width, height); - } - else - { - if (!rootpix) - rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), - skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); - gdk_draw_pixmap(obj, gc, rootpix, cfg.playlist_x + pl->pl_widget.x, - cfg.playlist_y + pl->pl_widget.y, pl->pl_widget.x, pl->pl_widget.y, - width, height); - } - - if (!playlist_list_font) { - g_critical("Couldn't open playlist font"); - return; - } - - pl->pl_fheight = (ascent + abs(descent)); - pl->pl_num_visible = height / pl->pl_fheight; - - max_first = playlist_get_length() - pl->pl_num_visible; - max_first = MAX(max_first, 0); - - pl->pl_first = CLAMP(pl->pl_first, 0, max_first); - - PLAYLIST_LOCK(); - list = playlist_get(); - list = g_list_nth(list, pl->pl_first); - - /* It sucks having to run the iteration twice but this is the only - way you can reliably get the maximum width so we can get our - playlist nice and aligned... -- plasmaroo */ - - for (i = pl->pl_first; - list && i < pl->pl_first + pl->pl_num_visible; - list = g_list_next(list), i++) { - PlaylistEntry *entry = list->data; - - if (entry->length != -1) - { - g_snprintf(length, sizeof(length), "%d:%-2.2d", - entry->length / 60000, (entry->length / 1000) % 60); - tpadding_dwidth = MAX(tpadding_dwidth, strlen(length)); - } - } - - /* Reset */ - list = playlist_get(); - list = g_list_nth(list, pl->pl_first); - - for (i = pl->pl_first; - list && i < pl->pl_first + pl->pl_num_visible; - list = g_list_next(list), i++) { - gint pos; - PlaylistEntry *entry = list->data; - - if (entry->selected) { - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_SELECTEDBG)); - gdk_draw_rectangle(obj, gc, TRUE, pl->pl_widget.x, - pl->pl_widget.y + - ((i - pl->pl_first) * pl->pl_fheight), - width, pl->pl_fheight); - } - - /* FIXME: entry->title should NEVER be NULL, and there should - NEVER be a need to do a UTF-8 conversion. Playlist title - strings should be kept properly. */ - - if (!entry->title) { - gchar *basename = g_path_get_basename(entry->filename); - title = filename_to_utf8(basename); - g_free(basename); - } - else - title = str_to_utf8(entry->title); - - pos = playlist_get_queue_position(entry); - - tail[0] = 0; - queuepos[0] = 0; - length[0] = 0; - - if (pos != -1) - g_snprintf(queuepos, sizeof(queuepos), "%d", pos + 1); - - if (entry->length != -1) - { - g_snprintf(length, sizeof(length), "%d:%-2.2d", - entry->length / 60000, (entry->length / 1000) % 60); - } - - strncat(tail, length, sizeof(tail)); - tail_len = strlen(tail); - - max_time_len = MAX(max_time_len, tail_len); - - if (pos != -1 && tpadding_dwidth <= 0) - tail_width = width - (width_approx_digits * (strlen(queuepos) + 2.25)); - else if (pos != -1) - tail_width = width - (width_approx_digits * (tpadding_dwidth + strlen(queuepos) + 4)); - else if (tpadding_dwidth > 0) - tail_width = width - (width_approx_digits * (tpadding_dwidth + 2.5)); - else - tail_width = width; - - if (i == playlist_get_position_nolock()) - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_CURRENT)); - else - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_NORMAL)); - playlist_list_draw_string(pl, playlist_list_font, - i - pl->pl_first, tail_width, title, - i + 1); - - x = pl->pl_widget.x + width - width_approx_digits * 2; - y = pl->pl_widget.y + ((i - pl->pl_first) - - 1) * pl->pl_fheight + ascent; - - frags = NULL; - frag0 = NULL; - - if ((strlen(tail) > 0) && (tail != NULL)) { - frags = g_strsplit(tail, ":", 0); - frag0 = g_strconcat(frags[0], ":", NULL); - - layout = gtk_widget_create_pango_layout(playlistwin, frags[1]); - pango_layout_set_font_description(layout, playlist_list_font); - pango_layout_set_width(layout, tail_len * 100); - pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); - gdk_draw_layout(obj, gc, x - (0.5 * width_approx_digits), - y + abs(descent), layout); - g_object_unref(layout); - - layout = gtk_widget_create_pango_layout(playlistwin, frag0); - pango_layout_set_font_description(layout, playlist_list_font); - pango_layout_set_width(layout, tail_len * 100); - pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); - gdk_draw_layout(obj, gc, x - (0.75 * width_approx_digits), - y + abs(descent), layout); - g_object_unref(layout); - - g_free(frag0); - g_strfreev(frags); - } - - if (pos != -1) { - - /* DON'T remove the commented code yet please -- Milosz */ - - if (tpadding_dwidth > 0) - queue_tailpadding = tpadding_dwidth + 1; - else - queue_tailpadding = -0.75; - - gdk_draw_rectangle(obj, gc, FALSE, - x - - (((queue_tailpadding + - strlen(queuepos)) * - width_approx_digits) + - (width_approx_digits / 4)), - y + abs(descent), - (strlen(queuepos)) * - width_approx_digits + - (width_approx_digits / 2), - pl->pl_fheight - 2); - - layout = - gtk_widget_create_pango_layout(playlistwin, queuepos); - pango_layout_set_font_description(layout, playlist_list_font); - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - - gdk_draw_layout(obj, gc, - x - - ((queue_tailpadding + - strlen(queuepos)) * width_approx_digits) + - (width_approx_digits / 4), - y + abs(descent), layout); - g_object_unref(layout); - } - - g_free(title); - } - - - /* - * Drop target hovering over the playlist, so draw some hint where the - * drop will occur. - * - * This is (currently? unfixably?) broken when dragging files from Qt/KDE apps, - * probably due to DnD signaling problems (actually i have no clue). - * - */ - - if (pl->pl_drag_motion) { - guint pos, plength, lpadding; - gint x, y, plx, ply; - - if (cfg.show_numbers_in_pl) { - lpadding = gint_count_digits(playlist_get_length_nolock()) + 1; - lpadding = ((lpadding + 1) * width_approx_digits); - } - else { - lpadding = 3; - }; - - /* We already hold the mutex and have the playlist locked, so call - the non-locking function. */ - plength = playlist_get_length_nolock(); - - x = pl->drag_motion_x; - y = pl->drag_motion_y; - - plx = pl->pl_widget.x; - ply = pl->pl_widget.y; - - if ((x > pl->pl_widget.x) && !(x > pl->pl_widget.width)) { - - if ((y > pl->pl_widget.y) - && !(y > (pl->pl_widget.height + ply))) { - - pos = ((y - ((Widget *) pl)->y) / pl->pl_fheight) + - pl->pl_first; - - if (pos > (plength)) { - pos = plength; - } - - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_CURRENT)); - - gdk_draw_line(obj, gc, pl->pl_widget.x, - pl->pl_widget.y + ((pos - pl->pl_first) * pl->pl_fheight), - pl->pl_widget.width + pl->pl_widget.x - 1, - pl->pl_widget.y + - ((pos - pl->pl_first) * pl->pl_fheight)); - } - - } - - /* When dropping on the borders of the playlist, outside the text area, - * files get appended at the end of the list. Show that too. - */ - - if ((y < ply) || (y > pl->pl_widget.height + ply)) { - if ((y >= 0) || (y <= (pl->pl_widget.height + ply))) { - pos = plength; - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_CURRENT)); - - gdk_draw_line(obj, gc, pl->pl_widget.x, - pl->pl_widget.y + - ((pos - pl->pl_first) * pl->pl_fheight), - pl->pl_widget.width + pl->pl_widget.x - 1, - pl->pl_widget.y + - ((pos - pl->pl_first) * pl->pl_fheight)); - - } - } - } - - gdk_gc_set_foreground(gc, - skin_get_color(bmp_active_skin, - SKIN_PLEDIT_NORMAL)); - - if (cfg.show_numbers_in_pl) { - - padding_plength = playlist_get_length_nolock(); - - if (padding_plength == 0) { - padding_dwidth = 0; - } - else { - padding_dwidth = gint_count_digits(playlist_get_length_nolock()); - } - - padding = - (padding_dwidth * - width_approx_digits) + width_approx_digits; - - - /* For italic or oblique fonts we add another half of the - * approximate width */ - if (has_slant) - padding += width_approx_digits_half; - - if (cfg.show_separator_in_pl) { - gdk_draw_line(obj, gc, - pl->pl_widget.x + padding, - pl->pl_widget.y, - pl->pl_widget.x + padding, - pl->pl_widget.y + pl->pl_widget.height - 1); - } - } - - if (tpadding_dwidth != 0) - { - tpadding = (tpadding_dwidth * width_approx_digits) + (width_approx_digits * 1.5); - - if (has_slant) - tpadding += width_approx_digits_half; - - if (cfg.show_separator_in_pl) { - gdk_draw_line(obj, gc, - pl->pl_widget.x + pl->pl_widget.width - tpadding, - pl->pl_widget.y, - pl->pl_widget.x + pl->pl_widget.width - tpadding, - pl->pl_widget.y + pl->pl_widget.height - 1); - } - } - - gdk_gc_set_clip_origin(gc, 0, 0); - gdk_gc_set_clip_rectangle(gc, NULL); - - PLAYLIST_UNLOCK(); - - gdk_flush(); - - g_free(playlist_rect); -} - - -PlayList_List * -create_playlist_list(GList ** wlist, - GdkPixmap * parent, - GdkGC * gc, - gint x, gint y, - gint w, gint h) -{ - PlayList_List *pl; - - pl = g_new0(PlayList_List, 1); - widget_init(&pl->pl_widget, parent, gc, x, y, w, h, TRUE); - - pl->pl_widget.button_press_cb = - (WidgetButtonPressFunc) playlist_list_button_press_cb; - pl->pl_widget.button_release_cb = - (WidgetButtonReleaseFunc) playlist_list_button_release_cb; - pl->pl_widget.motion_cb = (WidgetMotionFunc) playlist_list_motion_cb; - pl->pl_widget.draw = playlist_list_draw; - - pl->pl_prev_selected = -1; - pl->pl_prev_min = -1; - pl->pl_prev_max = -1; - - widget_list_add(wlist, WIDGET(pl)); - -#ifdef GDK_WINDOWING_X11 - gdk_window_set_events (gdk_get_default_root_window(), GDK_PROPERTY_CHANGE_MASK); - gdk_window_add_filter (gdk_get_default_root_window(), (GdkFilterFunc)root_event_cb, pl); -#endif - - return pl; -} - -void -playlist_list_set_font(const gchar * font) -{ - - /* Welcome to bad hack central 2k3 */ - - gchar *font_lower; - gint width_temp; - gint width_temp_0; - - playlist_list_font = pango_font_description_from_string(font); - - text_get_extents(font, - "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ", - &width_approx_letters, NULL, &ascent, &descent); - - width_approx_letters = (width_approx_letters / 53); - - /* Experimental: We don't weigh the 1 into total because it's width is almost always - * very different from the rest - */ - text_get_extents(font, "023456789", &width_approx_digits, NULL, NULL, - NULL); - width_approx_digits = (width_approx_digits / 9); - - /* Precache some often used calculations */ - width_approx_digits_half = width_approx_digits / 2; - - /* FIXME: We assume that any other number is broader than the "1" */ - text_get_extents(font, "1", &width_temp, NULL, NULL, NULL); - text_get_extents(font, "2", &width_temp_0, NULL, NULL, NULL); - - if (abs(width_temp_0 - width_temp) < 2) { - width_delta_digit_one = 0; - } - else { - width_delta_digit_one = ((width_temp_0 - width_temp) / 2) + 2; - } - - text_get_extents(font, ":", &width_colon, NULL, NULL, NULL); - width_colon_third = width_colon / 4; - - font_lower = g_utf8_strdown(font, strlen(font)); - /* This doesn't take any i18n into account, but i think there is none with TTF fonts - * FIXME: This can probably be retrieved trough Pango too - */ - has_slant = g_strstr_len(font_lower, strlen(font_lower), "oblique") - || g_strstr_len(font_lower, strlen(font_lower), "italic"); - - g_free(font_lower); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/playlist_list.h --- a/audacious/playlist_list.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef PLAYLIST_LIST_H -#define PLAYLIST_LIST_H - -#include -#include -#include - -#include "widget.h" - -#define PLAYLIST_LIST(x) ((PlayList_List *)(x)) -struct _PlayList_List { - Widget pl_widget; - gint pl_first, pl_fheight, pl_prev_selected, pl_prev_min, pl_prev_max; - gint pl_num_visible, pl_drag_pos; - gboolean pl_dragging, pl_auto_drag_down, pl_auto_drag_up; - gint pl_auto_drag_up_tag, pl_auto_drag_down_tag; - gboolean pl_drag_motion; - gint drag_motion_x, drag_motion_y; - gboolean pl_tooltips; -}; - -typedef struct _PlayList_List PlayList_List; - -PlayList_List *create_playlist_list(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y, gint w, - gint h); -void playlist_list_move_up(PlayList_List * pl); -void playlist_list_move_down(PlayList_List * pl); -int playlist_list_get_playlist_position(PlayList_List * pl, gint x, gint y); -void playlist_list_set_font(const gchar * font); -GdkPixmap *rootpix; -GdkPixmap *shade_pixmap(GdkDrawable *in, gint x, gint y, gint x_offset, gint y_offset, gint w, gint h, GdkColor *shade_color); -GdkDrawable *get_transparency_pixmap(void); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/playlist_slider.c --- a/audacious/playlist_slider.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "playlist_slider.h" - -#include - -#include "playlist.h" -#include "ui_playlist.h" -#include "skin.h" -#include "widget.h" - -void -playlistslider_draw(Widget * w) -{ - PlaylistSlider *ps = (PlaylistSlider *) w; - GdkPixmap *obj; - gint y, skinx; - - g_return_if_fail(ps != NULL); - g_return_if_fail(ps->ps_list != NULL); - - if (playlist_get_length() > ps->ps_list->pl_num_visible) - y = (ps->ps_list->pl_first * (ps->ps_widget.height - 19)) / - (playlist_get_length() - ps->ps_list->pl_num_visible); - else - y = 0; - - obj = ps->ps_widget.parent; - - if (ps->ps_back_image) { - if (skin_get_id() != ps->ps_skin_id) - ps->ps_skin_id = skin_get_id(); - else if (ps->ps_widget.height == ps->ps_prev_height) - gdk_draw_image(obj, ps->ps_widget.gc, - ps->ps_back_image, 0, 0, - ps->ps_widget.x, - ps->ps_widget.y + ps->ps_prev_y, 8, 18); - gdk_image_destroy(ps->ps_back_image); - } - - ps->ps_prev_y = y; - ps->ps_prev_height = ps->ps_widget.height; - ps->ps_back_image = gdk_drawable_get_image(obj, ps->ps_widget.x, - ps->ps_widget.y + y, 8, 18); - if (ps->ps_is_draging) - skinx = 61; - else - skinx = 52; - - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, SKIN_PLEDIT, - skinx, 53, ps->ps_widget.x, ps->ps_widget.y + y, 8, 18); -} - -static void -playlistslider_set_pos(PlaylistSlider * ps, gint y) -{ - gint pos; - - y = CLAMP(y, 0, ps->ps_widget.height - 19); - - pos = (y * (playlist_get_length() - ps->ps_list->pl_num_visible)) / - (ps->ps_widget.height - 19); - playlistwin_set_toprow(pos); -} - - -void -playlistslider_button_press_cb(GtkWidget * widget, - GdkEventButton * event, PlaylistSlider * ps) -{ - gint y = event->y - ps->ps_widget.y; - - if (!widget_contains(&ps->ps_widget, event->x, event->y)) - return; - - if (event->button != 1 && event->button != 2) - return; - - if ((y >= ps->ps_prev_y && y < ps->ps_prev_y + 18)) { - ps->ps_is_draging |= event->button; - ps->ps_drag_y = y - ps->ps_prev_y; - widget_draw(WIDGET(ps)); - } - else if (event->button == 2) { - playlistslider_set_pos(ps, y); - ps->ps_is_draging |= event->button; - ps->ps_drag_y = 0; - widget_draw(WIDGET(ps)); - } - else { - gint n = ps->ps_list->pl_num_visible / 2; - if (y < ps->ps_prev_y) - n *= -1; - playlistwin_scroll(n); - } -} - -void -playlistslider_button_release_cb(GtkWidget * widget, - GdkEventButton * event, - PlaylistSlider * ps) -{ - if (ps->ps_is_draging) { - ps->ps_is_draging &= ~event->button; - widget_draw(WIDGET(ps)); - } -} - -void -playlistslider_motion_cb(GtkWidget * widget, GdkEventMotion * event, - PlaylistSlider * ps) -{ - gint y; - - if (!ps->ps_is_draging) - return; - - y = event->y - ps->ps_widget.y - ps->ps_drag_y; - playlistslider_set_pos(ps, y); -} - -PlaylistSlider * -create_playlistslider(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y, gint h, - PlayList_List * list) -{ - PlaylistSlider *ps; - - ps = g_new0(PlaylistSlider, 1); - widget_init(&ps->ps_widget, parent, gc, x, y, 8, h, 1); - - ps->ps_widget.button_press_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - playlistslider_button_press_cb; - - ps->ps_widget.button_release_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - playlistslider_button_release_cb; - - ps->ps_widget.motion_cb = - (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) - playlistslider_motion_cb; - - ps->ps_widget.draw = playlistslider_draw; - ps->ps_list = list; - - widget_list_add(wlist, WIDGET(ps)); - return ps; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/playlist_slider.h --- a/audacious/playlist_slider.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef PLAYLIST_SLIDER_H -#define PLAYLIST_SLIDER_H - -#include -#include - -#include "playlist_list.h" -#include "widget.h" - -#define PLAYLIST_SLIDER(x) ((PlayerlistSlider *)(x)) -struct _PlaylistSlider { - Widget ps_widget; - PlayList_List *ps_list; - gboolean ps_is_draging; - gint ps_drag_y, ps_prev_y, ps_prev_height; - GdkImage *ps_back_image; - gint ps_skin_id; -}; - -typedef struct _PlaylistSlider PlaylistSlider; - -PlaylistSlider *create_playlistslider(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y, gint h, - PlayList_List * list); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/playstatus.c --- a/audacious/playstatus.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* XMMS - Cross-platform multimedia player - * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "playstatus.h" - -#include -#include - -#include "skin.h" -#include "widget.h" - -void -playstatus_draw(Widget * w) -{ - PlayStatus *ps = PLAY_STATUS(w); - GdkPixmap *obj; - - if (!w) - return; - - obj = ps->ps_widget.parent; - if (ps->ps_status == STATUS_STOP && ps->ps_status_buffering == TRUE) - ps->ps_status_buffering = FALSE; - if (ps->ps_status == STATUS_PLAY && ps->ps_status_buffering == TRUE) - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 39, 0, ps->ps_widget.x, - ps->ps_widget.y, 3, 9); - else if (ps->ps_status == STATUS_PLAY) - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 36, 0, ps->ps_widget.x, - ps->ps_widget.y, 3, 9); - else - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 27, 0, ps->ps_widget.x, - ps->ps_widget.y, 2, 9); - switch (ps->ps_status) { - case STATUS_STOP: - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 18, 0, - ps->ps_widget.x + 2, ps->ps_widget.y, 9, 9); - break; - case STATUS_PAUSE: - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 9, 0, - ps->ps_widget.x + 2, ps->ps_widget.y, 9, 9); - break; - case STATUS_PLAY: - skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, - SKIN_PLAYPAUSE, 1, 0, - ps->ps_widget.x + 3, ps->ps_widget.y, 8, 9); - break; - } -} - -void -playstatus_set_status(PlayStatus * ps, PStatus status) -{ - if (!ps) - return; - - ps->ps_status = status; - widget_draw(WIDGET(ps)); -} - -void -playstatus_set_status_buffering(PlayStatus * ps, gboolean status) -{ - if (!ps) - return; - - ps->ps_status_buffering = status; - widget_draw(WIDGET(ps)); -} - -PlayStatus * -create_playstatus(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y) -{ - PlayStatus *ps; - - ps = g_new0(PlayStatus, 1); - widget_init(&ps->ps_widget, parent, gc, x, y, 11, 9, TRUE); - ps->ps_widget.draw = playstatus_draw; - - widget_list_add(wlist, WIDGET(ps)); - return ps; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/playstatus.h --- a/audacious/playstatus.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* XMMS - Cross-platform multimedia player - * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef PLAYSTATUS_H -#define PLAYSTATUS_H - -#include "widget.h" - -typedef enum { - STATUS_STOP, STATUS_PAUSE, STATUS_PLAY -} PStatus; - -#define PLAY_STATUS(x) ((PlayStatus *)(x)) -struct _PlayStatus { - Widget ps_widget; - PStatus ps_status; - gboolean ps_status_buffering; -}; - -typedef struct _PlayStatus PlayStatus; - -void playstatus_set_status(PlayStatus * ps, PStatus status); -void playstatus_set_status_buffering(PlayStatus * ps, gboolean status); -PlayStatus *create_playstatus(GList ** wlist, GdkPixmap * parent, - GdkGC * gc, gint x, gint y); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/prefswin.c --- a/audacious/prefswin.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/prefswin.c Wed Aug 09 02:47:22 2006 -0700 @@ -48,7 +48,7 @@ #include "visualization.h" #include "main.h" -#include "skin.h" +#include "widgets/skin.h" #include "urldecode.h" #include "util.h" #include "dnd.h" @@ -57,7 +57,6 @@ #include "mainwin.h" #include "ui_playlist.h" #include "skinwin.h" -#include "playlist_list.h" #include "build_stamp.h" #include "prefswin.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/sbutton.c --- a/audacious/sbutton.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "sbutton.h" - -#include -#include -#include - -void -sbutton_button_press_cb(GtkWidget * widget, - GdkEventButton * event, - SButton * button) -{ - if (event->button != 1) - return; - - if (widget_contains(&button->sb_widget, event->x, event->y)) { - button->sb_pressed = 1; - button->sb_inside = 1; - } -} - -void -sbutton_button_release_cb(GtkWidget * widget, GdkEventButton * event, - SButton * button) -{ - if (event->button != 1) - return; - if (button->sb_inside && button->sb_pressed) { - button->sb_inside = 0; - if (button->sb_push_cb) - button->sb_push_cb(); - } - if (button->sb_pressed) - button->sb_pressed = 0; -} - -void -sbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, - SButton * button) -{ - int inside; - - if (!button->sb_pressed) - return; - - inside = widget_contains(&button->sb_widget, event->x, event->y); - - if (inside != button->sb_inside) - button->sb_inside = inside; -} - -SButton * -create_sbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, void (*cb) (void)) -{ - SButton *b; - - b = g_new0(SButton, 1); - widget_init(&b->sb_widget, parent, gc, x, y, w, h, 1); - b->sb_widget.button_press_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - sbutton_button_press_cb; - b->sb_widget.button_release_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - sbutton_button_release_cb; - b->sb_widget.motion_cb = - (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) - sbutton_motion_cb; - b->sb_push_cb = cb; - - widget_list_add(wlist, WIDGET(b)); - return b; -} - -void -free_sbutton(SButton * b) -{ - g_free(b); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/sbutton.h --- a/audacious/sbutton.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef SBUTTON_H -#define SBUTTON_H - -#include -#include - -#include "widget.h" - -#define SBUTTON(x) ((SButton *)(x)) -struct _SButton { - Widget sb_widget; - gint sb_pressed, sb_inside; - void (*sb_push_cb) (void); -}; - -typedef struct _SButton SButton; - -SButton *create_sbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, void (*cb) (void)); -void free_sbutton(SButton * b); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/skin.c --- a/audacious/skin.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1260 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -/* TODO: enforce default sizes! */ - -#include -#include -#include -#include -#include - -#include "equalizer.h" -#include "main.h" -#include "ui_playlist.h" -#include "skin.h" -#include "skinwin.h" -#include "util.h" - -#include "debug.h" - -#include -#include - -#define EXTENSION_TARGETS 7 - -static gchar *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg", - "gif", "jpg", "jpeg" }; - -struct _SkinPixmapIdMapping { - SkinPixmapId id; - const gchar *name; - const gchar *alt_name; - gint width, height; -}; - -struct _SkinMaskInfo { - gint width, height; - gchar *inistr; -}; - -typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping; -typedef struct _SkinMaskInfo SkinMaskInfo; - - -Skin *bmp_active_skin = NULL; - -static gint skin_current_num; - -static SkinMaskInfo skin_mask_info[] = { - {275, 116, "Normal"}, - {275, 16, "WindowShade"}, - {275, 116, "Equalizer"}, - {275, 16, "EqualizerWS"} -}; - -static SkinPixmapIdMapping skin_pixmap_id_map[] = { - {SKIN_MAIN, "main", NULL, 0, 0}, - {SKIN_CBUTTONS, "cbuttons", NULL, 0, 0}, - {SKIN_SHUFREP, "shufrep", NULL, 0, 0}, - {SKIN_TEXT, "text", NULL, 0, 0}, - {SKIN_TITLEBAR, "titlebar", NULL, 0, 0}, - {SKIN_VOLUME, "volume", NULL, 0, 0}, - {SKIN_BALANCE, "balance", "volume", 0, 0}, - {SKIN_MONOSTEREO, "monoster", NULL, 0, 0}, - {SKIN_PLAYPAUSE, "playpaus", NULL, 0, 0}, - {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0}, - {SKIN_POSBAR, "posbar", NULL, 0, 0}, - {SKIN_EQMAIN, "eqmain", NULL, 0, 0}, - {SKIN_PLEDIT, "pledit", NULL, 0, 0}, - {SKIN_EQ_EX, "eq_ex", NULL, 0, 0} -}; - -static guint skin_pixmap_id_map_size = G_N_ELEMENTS(skin_pixmap_id_map); - -static const guchar skin_default_viscolor[24][3] = { - {9, 34, 53}, - {10, 18, 26}, - {0, 54, 108}, - {0, 58, 116}, - {0, 62, 124}, - {0, 66, 132}, - {0, 70, 140}, - {0, 74, 148}, - {0, 78, 156}, - {0, 82, 164}, - {0, 86, 172}, - {0, 92, 184}, - {0, 98, 196}, - {0, 104, 208}, - {0, 110, 220}, - {0, 116, 232}, - {0, 122, 244}, - {0, 128, 255}, - {0, 128, 255}, - {0, 104, 208}, - {0, 80, 160}, - {0, 56, 112}, - {0, 32, 64}, - {200, 200, 200} -}; - -static GdkBitmap * -skin_create_transparent_mask(const gchar *, - const gchar *, - const gchar *, - GdkWindow *, - gint, gint); - -static void -skin_setup_masks(Skin * skin); - -static void -skin_set_default_vis_color(Skin * skin); - - -void -skin_lock(Skin * skin) -{ - g_mutex_lock(skin->lock); -} - -void -skin_unlock(Skin * skin) -{ - g_mutex_unlock(skin->lock); -} - -gboolean -bmp_active_skin_reload(void) -{ - return bmp_active_skin_load(bmp_active_skin->path); -} - -gboolean -bmp_active_skin_load(const gchar * path) -{ - g_return_val_if_fail(bmp_active_skin != NULL, FALSE); - - memset(&bmp_active_skin->properties, 0, sizeof(SkinProperties)); - - if (!skin_load(bmp_active_skin, path)) - return FALSE; - - skin_setup_masks(bmp_active_skin); - - if (cfg.playlist_transparent) - { - if (rootpix != NULL) - g_object_unref(rootpix); - - rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), - skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); - } - - draw_main_window(TRUE); - draw_playlist_window(TRUE); - draw_equalizer_window(TRUE); - - vis_set_window(mainwin_vis, mainwin->window); - playlistwin_update_list(); - - return TRUE; -} - -void -skin_pixmap_free(SkinPixmap * p) -{ - g_return_if_fail(p != NULL); - g_return_if_fail(p->pixmap != NULL); - - g_object_unref(p->pixmap); - p->pixmap = NULL; -} - -Skin * -skin_new(void) -{ - Skin *skin; - skin = g_new0(Skin, 1); - skin->lock = g_mutex_new(); - return skin; -} - -void -skin_free(Skin * skin) -{ - gint i; - - g_return_if_fail(skin != NULL); - - skin_lock(skin); - - for (i = 0; i < SKIN_PIXMAP_COUNT; i++) - skin_pixmap_free(&skin->pixmaps[i]); - - for (i = 0; i < SKIN_PIXMAP_COUNT; i++) { - if (skin->masks[i]) - g_object_unref(skin->masks[i]); - - skin->masks[i] = NULL; - } - - skin_set_default_vis_color(skin); - skin_unlock(skin); -} - -void -skin_destroy(Skin * skin) -{ - g_return_if_fail(skin != NULL); - skin_free(skin); - g_mutex_free(skin->lock); - g_free(skin); -} - -const SkinPixmapIdMapping * -skin_pixmap_id_lookup(guint id) -{ - guint i; - - for (i = 0; i < skin_pixmap_id_map_size; i++) { - if (id == skin_pixmap_id_map[i].id) { - return &skin_pixmap_id_map[i]; - } - } - - return NULL; -} - -const gchar * -skin_pixmap_id_to_name(SkinPixmapId id) -{ - guint i; - - for (i = 0; i < skin_pixmap_id_map_size; i++) { - if (id == skin_pixmap_id_map[i].id) - return skin_pixmap_id_map[i].name; - } - return NULL; -} - -static void -skin_set_default_vis_color(Skin * skin) -{ - memcpy(skin->vis_color, skin_default_viscolor, - sizeof(skin_default_viscolor)); -} - -/* - * I have rewritten this to take an array of possible targets, - * once we find a matching target we now return, instead of loop - * recursively. This allows for us to support many possible format - * targets for our skinning engine than just the original winamp - * formats. - * - * -- nenolod, 16 January 2006 - */ -gchar * -skin_pixmap_locate(const gchar * dirname, gchar ** basenames) -{ - gchar *filename; - gint i; - - for (i = 0; basenames[i]; i++) - if (!(filename = find_file_recursively(dirname, basenames[i]))) - g_free(filename); - else - return filename; - - /* can't find any targets -- sorry */ - return NULL; -} - -/* FIXME: this function is temporary. It will be removed when the skinning system - uses GdkPixbuf in place of GdkPixmap */ - -static GdkPixmap * -pixmap_new_from_file(const gchar * filename) -{ - GdkPixbuf *pixbuf; - GdkPixmap *pixmap; - gint width, height; - - if (!(pixbuf = gdk_pixbuf_new_from_file(filename, NULL))) - return NULL; - - width = gdk_pixbuf_get_width(pixbuf); - height = gdk_pixbuf_get_height(pixbuf); - - if (!(pixmap = gdk_pixmap_new(mainwin->window, width, height, - gdk_rgb_get_visual()->depth))) { - g_object_unref(pixbuf); - return NULL; - } - - gdk_pixbuf_render_to_drawable(pixbuf, pixmap, mainwin_gc, 0, 0, 0, 0, - width, height, GDK_RGB_DITHER_MAX, 0, 0); - g_object_unref(pixbuf); - - return pixmap; -} - -static gboolean -skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const gchar * path_p) -{ - const gchar *path; - gchar *filename; - gint width, height; - const SkinPixmapIdMapping *pixmap_id_mapping; - GdkPixmap *gpm; - SkinPixmap *pm = NULL; - gchar *basenames[EXTENSION_TARGETS * 2 + 1]; /* alternate basenames */ - gint i, y; - - g_return_val_if_fail(skin != NULL, FALSE); - g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE); - - pixmap_id_mapping = skin_pixmap_id_lookup(id); - g_return_val_if_fail(pixmap_id_mapping != NULL, FALSE); - - memset(&basenames, 0, sizeof(basenames)); - - for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++) - { - basenames[y] = g_strdup_printf("%s.%s", pixmap_id_mapping->name, - ext_targets[i]); - - if (pixmap_id_mapping->alt_name) - basenames[++y] = g_strdup_printf("%s.%s", - pixmap_id_mapping->alt_name, ext_targets[i]); - } - - path = path_p ? path_p : skin->path; - filename = skin_pixmap_locate(path, basenames); - - for (i = 0; basenames[i] != NULL; i++) - { - g_free(basenames[i]); - basenames[i] = NULL; - } - - if (!(gpm = pixmap_new_from_file(filename))) { - g_warning("loading of %s failed", filename); - g_free(filename); - return FALSE; - } - - g_free(filename); - - gdk_window_get_size(gpm, &width, &height); - pm = &skin->pixmaps[id]; - pm->pixmap = gpm; - pm->width = width; - pm->height = height; - pm->current_width = width; - pm->current_height = height; - - return TRUE; -} - -void -skin_mask_create(Skin * skin, - const gchar * path, - gint id, - GdkWindow * window) -{ - skin->masks[id] = - skin_create_transparent_mask(path, "region.txt", - skin_mask_info[id].inistr, window, - skin_mask_info[id].width, - skin_mask_info[id].height); -} - -static void -skin_setup_masks(Skin * skin) -{ - GdkBitmap *mask; - - if (cfg.show_wm_decorations) - return; - - if (cfg.player_visible) { - mask = skin_get_mask(skin, SKIN_MASK_MAIN + cfg.player_shaded); - gtk_widget_shape_combine_mask(mainwin, mask, 0, 0); - } - - mask = skin_get_mask(skin, SKIN_MASK_EQ + cfg.equalizer_shaded); - gtk_widget_shape_combine_mask(equalizerwin, mask, 0, 0); -} - -static GdkBitmap * -create_default_mask(GdkWindow * parent, gint w, gint h) -{ - GdkBitmap *ret; - GdkGC *gc; - GdkColor pattern; - - ret = gdk_pixmap_new(parent, w, h, 1); - gc = gdk_gc_new(ret); - pattern.pixel = 1; - gdk_gc_set_foreground(gc, &pattern); - gdk_draw_rectangle(ret, gc, TRUE, 0, 0, w, h); - gdk_gc_destroy(gc); - - return ret; -} - -static void -skin_query_color(GdkColormap * cm, GdkColor * c) -{ - XColor xc = { 0,0,0,0,0,0 }; - - xc.pixel = c->pixel; - XQueryColor(GDK_COLORMAP_XDISPLAY(cm), GDK_COLORMAP_XCOLORMAP(cm), &xc); - c->red = xc.red; - c->green = xc.green; - c->blue = xc.blue; -} - -static glong -skin_calc_luminance(GdkColor * c) -{ - return (0.212671 * c->red + 0.715160 * c->green + 0.072169 * c->blue); -} - -static void -skin_get_textcolors(GdkPixmap * text, GdkColor * bgc, GdkColor * fgc) -{ - /* - * Try to extract reasonable background and foreground colors - * from the font pixmap - */ - - GdkImage *gi; - GdkColormap *cm; - gint i; - - g_return_if_fail(text != NULL); - - /* Get the first line of text */ - gi = gdk_drawable_get_image(text, 0, 0, 152, 6); - cm = gdk_window_get_colormap(playlistwin->window); - g_return_if_fail(GDK_IS_WINDOW(playlistwin->window)); - - for (i = 0; i < 6; i++) { - GdkColor c; - gint x; - glong d, max_d; - - /* Get a pixel from the middle of the space character */ - bgc[i].pixel = gdk_image_get_pixel(gi, 151, i); - skin_query_color(cm, &bgc[i]); - - max_d = 0; - for (x = 1; x < 150; x++) { - c.pixel = gdk_image_get_pixel(gi, x, i); - skin_query_color(cm, &c); - - d = labs(skin_calc_luminance(&c) - skin_calc_luminance(&bgc[i])); - if (d > max_d) { - memcpy(&fgc[i], &c, sizeof(GdkColor)); - max_d = d; - } - } - } - gdk_image_destroy(gi); -} - -gboolean -init_skins(const gchar * path) -{ - bmp_active_skin = skin_new(); - - if (!bmp_active_skin_load(path)) { - /* FIXME: Oddly, g_message() causes a crash if path is NULL on - * Solaris (see bug #165) */ - if (path) - g_message("Unable to load skin (%s), trying default...", path); - - /* can't load configured skin, retry with default */ - if (!bmp_active_skin_load(BMP_DEFAULT_SKIN_PATH)) { - g_message("Unable to load default skin (%s)! Giving up.", - BMP_DEFAULT_SKIN_PATH); - return FALSE; - } - } - - if (cfg.random_skin_on_play) - skinlist_update(); - - return TRUE; -} - -/* - * Opens and parses a skin's hints file. - * Hints files are somewhat like "scripts" in Winamp3/5. - * We'll probably add scripts to it next. - */ -void -skin_parse_hints(Skin * skin, gchar *path_p) -{ - gchar *filename, *tmp; - - path_p = path_p ? path_p : skin->path; - - filename = find_file_recursively(path_p, "skin.hints"); - - if (filename == NULL) - return; - -#if 0 - skin->description = read_ini_string(filename, "skin", "skinDescription"); -#endif - - tmp = read_ini_string(filename, "skin", "mainwinOthertext"); - - if (tmp != NULL) - skin->properties.mainwin_othertext = atoi(tmp); -} - -static guint -hex_chars_to_int(gchar hi, gchar lo) -{ - /* - * Converts a value in the range 0x00-0xFF - * to a integer in the range 0-65535 - */ - gchar str[3]; - - str[0] = hi; - str[1] = lo; - str[2] = 0; - - return (CLAMP(strtol(str, NULL, 16), 0, 0xFF) << 8); -} - -GdkColor * -skin_load_color(const gchar * path, const gchar * file, - const gchar * section, const gchar * key, - gchar * default_hex) -{ - gchar *filename, *value; - GdkColor *color = NULL; - - filename = find_file_recursively(path, file); - if (filename || default_hex) { - if (filename) { - value = read_ini_string(filename, section, key); - if (value == NULL) { - value = g_strdup(default_hex); - } - } else { - value = g_strdup(default_hex); - } - if (value) { - gchar *ptr = value; - gint len; - - color = g_new0(GdkColor, 1); - g_strstrip(value); - - if (value[0] == '#') - ptr++; - len = strlen(ptr); - /* - * The handling of incomplete values is done this way - * to maximize winamp compatibility - */ - if (len >= 6) { - color->red = hex_chars_to_int(*ptr, *(ptr + 1)); - ptr += 2; - } - if (len >= 4) { - color->green = hex_chars_to_int(*ptr, *(ptr + 1)); - ptr += 2; - } - if (len >= 2) - color->blue = hex_chars_to_int(*ptr, *(ptr + 1)); - - gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), - color); - g_free(value); - } - if (filename) - g_free(filename); - } - return color; -} - - - -GdkBitmap * -skin_create_transparent_mask(const gchar * path, - const gchar * file, - const gchar * section, - GdkWindow * window, - gint width, - gint height) -{ - GdkBitmap *mask = NULL; - GdkGC *gc = NULL; - GdkColor pattern; - GdkPoint *gpoints; - - gchar *filename = NULL; - gboolean created_mask = FALSE; - GArray *num, *point; - guint i, j; - gint k; - - if (path) - filename = find_file_recursively(path, file); - - /* filename will be null if path wasn't set */ - if (!filename) { - return create_default_mask(window, width, height); - } - - if ((num = read_ini_array(filename, section, "NumPoints")) == NULL) { - g_free(filename); - return NULL; - } - - if ((point = read_ini_array(filename, section, "PointList")) == NULL) { - g_array_free(num, TRUE); - g_free(filename); - return NULL; - } - - mask = gdk_pixmap_new(window, width, height, 1); - gc = gdk_gc_new(mask); - - pattern.pixel = 0; - gdk_gc_set_foreground(gc, &pattern); - gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); - pattern.pixel = 1; - gdk_gc_set_foreground(gc, &pattern); - - j = 0; - for (i = 0; i < num->len; i++) { - if ((int)(point->len - j) >= (g_array_index(num, gint, i) * 2)) { - created_mask = TRUE; - gpoints = g_new(GdkPoint, g_array_index(num, gint, i)); - for (k = 0; k < g_array_index(num, gint, i); k++) { - gpoints[k].x = g_array_index(point, gint, j + k * 2); - gpoints[k].y = g_array_index(point, gint, j + k * 2 + 1); - } - j += k * 2; - gdk_draw_polygon(mask, gc, TRUE, gpoints, - g_array_index(num, gint, i)); - g_free(gpoints); - } - } - g_array_free(num, TRUE); - g_array_free(point, TRUE); - g_free(filename); - - if (!created_mask) - gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); - - gdk_gc_destroy(gc); - - return mask; -} - -void -skin_load_viscolor(Skin * skin, const gchar * path, const gchar * basename) -{ - FILE *file; - gint i, c; - gchar line[256], *filename; - GArray *a; - - g_return_if_fail(skin != NULL); - g_return_if_fail(path != NULL); - g_return_if_fail(basename != NULL); - - skin_set_default_vis_color(skin); - - filename = find_file_recursively(path, basename); - if (!filename) - return; - - if (!(file = fopen(filename, "r"))) { - g_free(filename); - return; - } - - g_free(filename); - - for (i = 0; i < 24; i++) { - if (fgets(line, 255, file)) { - a = string_to_garray(line); - if (a->len > 2) { - for (c = 0; c < 3; c++) - skin->vis_color[i][c] = g_array_index(a, gint, c); - } - g_array_free(a, TRUE); - } - else - break; - } - - fclose(file); -} - -#if 0 -static void -skin_numbers_generate_dash(Skin * skin) -{ - GdkGC *gc; - GdkPixmap *pixmap; - SkinPixmap *numbers; - - g_return_if_fail(skin != NULL); - - numbers = &skin->pixmaps[SKIN_NUMBERS]; - if (!numbers->pixmap || numbers->current_width < 99) - return; - - gc = gdk_gc_new(numbers->pixmap); - pixmap = gdk_pixmap_new(mainwin->window, 108, - numbers->current_height, - -1); - - skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 0, 0, 0, 0, 99, 13); - skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 90, 0, 99, 0, 9, 13); - skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 20, 6, 101, 6, 5, 1); - - g_object_unref(numbers->pixmap); - g_object_unref(gc); - - numbers->pixmap = pixmap; - numbers->current_width = 108; -} -#endif - -static void -skin_load_cursor(Skin * skin, const gchar * dirname) -{ - const gchar * basename = "normal.cur"; - gchar * filename = NULL; - GdkPixbuf * cursor_pixbuf = NULL; - GdkPixbufAnimation * cursor_animated = NULL; - GdkCursor * cursor_gdk = NULL; - GError * error = NULL; - - filename = find_file_recursively(dirname, basename); - - if (filename && cfg.custom_cursors) { - cursor_animated = gdk_pixbuf_animation_new_from_file(filename, &error); - cursor_pixbuf = gdk_pixbuf_animation_get_static_image(cursor_animated); - cursor_gdk = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), - cursor_pixbuf, 0, 0); - } else { - cursor_gdk = gdk_cursor_new(GDK_LEFT_PTR); - } - - gdk_window_set_cursor(mainwin->window, cursor_gdk); - gdk_window_set_cursor(playlistwin->window, cursor_gdk); - gdk_window_set_cursor(equalizerwin->window, cursor_gdk); - gdk_cursor_unref(cursor_gdk); -} - -static void -skin_load_pixmaps(Skin * skin, const gchar * path) -{ - GdkPixmap *text_pm; - guint i; - - for (i = 0; i < SKIN_PIXMAP_COUNT; i++) - skin_load_pixmap_id(skin, i, path); - - text_pm = skin->pixmaps[SKIN_TEXT].pixmap; - - if (text_pm) - skin_get_textcolors(text_pm, skin->textbg, skin->textfg); - -#if 0 - if (skin->pixmaps[SKIN_NUMBERS].pixmap) - skin_numbers_generate_dash(skin); -#endif - - skin->colors[SKIN_PLEDIT_NORMAL] = - skin_load_color(path, "pledit.txt", "text", "normal", "#2499ff"); - skin->colors[SKIN_PLEDIT_CURRENT] = - skin_load_color(path, "pledit.txt", "text", "current", "#ffeeff"); - skin->colors[SKIN_PLEDIT_NORMALBG] = - skin_load_color(path, "pledit.txt", "text", "normalbg", "#0a120a"); - skin->colors[SKIN_PLEDIT_SELECTEDBG] = - skin_load_color(path, "pledit.txt", "text", "selectedbg", "#0a124a"); - - skin_mask_create(skin, path, SKIN_MASK_MAIN, mainwin->window); - skin_mask_create(skin, path, SKIN_MASK_MAIN_SHADE, mainwin->window); - - skin_mask_create(skin, path, SKIN_MASK_EQ, equalizerwin->window); - skin_mask_create(skin, path, SKIN_MASK_EQ_SHADE, equalizerwin->window); - - skin_load_viscolor(skin, path, "viscolor.txt"); -} - -static gboolean -skin_load_nolock(Skin * skin, const gchar * path, gboolean force) -{ - gchar *cpath; - - g_return_val_if_fail(skin != NULL, FALSE); - g_return_val_if_fail(path != NULL, FALSE); - REQUIRE_LOCK(skin->lock); - - if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR)) - return FALSE; - - if (!force) { - if (skin->path) - if (!strcmp(skin->path, path)) - return FALSE; - } - - skin_current_num++; - - skin->path = g_strdup(path); - - if (!file_is_archive(path)) { - skin_load_pixmaps(skin, path); - skin_load_cursor(skin, path); - - /* Parse the hints for this skin. */ - skin_parse_hints(skin, NULL); - - return TRUE; - } - - if (!(cpath = archive_decompress(path))) { - g_message("Unable to extract skin archive (%s)", path); - return FALSE; - } - - skin_load_pixmaps(skin, cpath); - skin_load_cursor(skin, cpath); - - /* Parse the hints for this skin. */ - skin_parse_hints(skin, cpath); - - del_directory(cpath); - g_free(cpath); - - return TRUE; -} - -void -skin_install_skin(const gchar * path) -{ - gchar *command; - - g_return_if_fail(path != NULL); - - command = g_strdup_printf("cp %s %s", path, bmp_paths[BMP_PATH_USER_SKIN_DIR]); - if (system(command)) { - g_message("Unable to install skin (%s) into user directory (%s)", - path, bmp_paths[BMP_PATH_USER_SKIN_DIR]); - } - g_free(command); -} - - -gboolean -skin_load(Skin * skin, const gchar * path) -{ - gboolean error; - - g_return_val_if_fail(skin != NULL, FALSE); - - if (!path) - return FALSE; - - skin_lock(skin); - error = skin_load_nolock(skin, path, FALSE); - skin_unlock(skin); - - return error; -} - -gboolean -skin_reload_forced(void) -{ - gboolean error; - - skin_lock(bmp_active_skin); - error = skin_load_nolock(bmp_active_skin, bmp_active_skin->path, TRUE); - skin_unlock(bmp_active_skin); - - return error; -} - -void -skin_reload(Skin * skin) -{ - g_return_if_fail(skin != NULL); - skin_load_nolock(skin, skin->path, TRUE); -} - - -static SkinPixmap * -skin_get_pixmap(Skin * skin, SkinPixmapId map_id) -{ - g_return_val_if_fail(skin != NULL, NULL); - g_return_val_if_fail(map_id < SKIN_PIXMAP_COUNT, NULL); - - return &skin->pixmaps[map_id]; -} - -GdkBitmap * -skin_get_mask(Skin * skin, SkinMaskId mi) -{ - g_return_val_if_fail(skin != NULL, NULL); - g_return_val_if_fail(mi < SKIN_PIXMAP_COUNT, NULL); - - return skin->masks[mi]; -} - -GdkColor * -skin_get_color(Skin * skin, SkinColorId color_id) -{ - GdkColor *ret = NULL; - - g_return_val_if_fail(skin != NULL, NULL); - - switch (color_id) { - case SKIN_TEXTBG: - if (skin->pixmaps[SKIN_TEXT].pixmap) - ret = skin->textbg; - else - ret = skin->def_textbg; - break; - case SKIN_TEXTFG: - if (skin->pixmaps[SKIN_TEXT].pixmap) - ret = skin->textfg; - else - ret = skin->def_textfg; - break; - default: - if (color_id < SKIN_COLOR_COUNT) - ret = skin->colors[color_id]; - break; - } - return ret; -} - -void -skin_get_viscolor(Skin * skin, guchar vis_color[24][3]) -{ - gint i; - - g_return_if_fail(skin != NULL); - - for (i = 0; i < 24; i++) { - vis_color[i][0] = skin->vis_color[i][0]; - vis_color[i][1] = skin->vis_color[i][1]; - vis_color[i][2] = skin->vis_color[i][2]; - } -} - -gint -skin_get_id(void) -{ - return skin_current_num; -} - -void -skin_draw_pixmap(Skin * skin, GdkDrawable * drawable, GdkGC * gc, - SkinPixmapId pixmap_id, - gint xsrc, gint ysrc, gint xdest, gint ydest, - gint width, gint height) -{ - SkinPixmap *pixmap; - - g_return_if_fail(skin != NULL); - - pixmap = skin_get_pixmap(skin, pixmap_id); - g_return_if_fail(pixmap != NULL); - g_return_if_fail(pixmap->pixmap != NULL); - - if (xsrc > pixmap->width || ysrc > pixmap->height) - return; - - width = MIN(width, pixmap->width - xsrc); - height = MIN(height, pixmap->height - ysrc); - gdk_draw_pixmap(drawable, gc, pixmap->pixmap, xsrc, ysrc, - xdest, ydest, width, height); -} - -void -skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]) -{ - gint i; - GdkPixmap *pixmap; - GdkImage *img; - SkinPixmap *eqmainpm; - - g_return_if_fail(skin != NULL); - - eqmainpm = &skin->pixmaps[SKIN_EQMAIN]; - if (eqmainpm->pixmap && - eqmainpm->current_width >= 116 && eqmainpm->current_height >= 313) - pixmap = eqmainpm->pixmap; - else - return; - - if (!GDK_IS_DRAWABLE(pixmap)) - return; - - if (!(img = gdk_drawable_get_image(pixmap, 115, 294, 1, 19))) - return; - - for (i = 0; i < 19; i++) - colors[i] = gdk_image_get_pixel(img, 0, i); - - gdk_image_destroy(img); -} - - -static void -skin_draw_playlistwin_frame_top(Skin * skin, - GdkDrawable * drawable, - GdkGC * gc, - gint width, gint height, gboolean focus) -{ - /* The title bar skin consists of 2 sets of 4 images, 1 set - * for focused state and the other for unfocused. The 4 images - * are: - * - * a. right corner (25,20) - * b. left corner (25,20) - * c. tiler (25,20) - * d. title (100,20) - * - * min allowed width = 100+25+25 = 150 - */ - - gint i, y, c; - - /* get y offset of the pixmap set to use */ - if (focus) - y = 0; - else - y = 21; - - /* left corner */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, y, 0, 0, 25, 20); - - /* titlebar title */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 26, y, - (width - 100) / 2, 0, 100, 20); - - /* titlebar right corner */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 153, y, - width - 25, 0, 25, 20); - - /* tile draw the remaining frame */ - - /* compute tile count */ - c = (width - (100 + 25 + 25)) / 25; - - for (i = 0; i < c / 2; i++) { - /* left of title */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, - 25 + i * 25, 0, 25, 20); - - /* right of title */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, - (width + 100) / 2 + i * 25, 0, 25, 20); - } - - if (c & 1) { - /* Odd tile count, so one remaining to draw. Here we split - * it into two and draw half on either side of the title */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, - ((c / 2) * 25) + 25, 0, 12, 20); - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, - (width / 2) + ((c / 2) * 25) + 50, 0, 13, 20); - } -} - -static void -skin_draw_playlistwin_frame_bottom(Skin * skin, - GdkDrawable * drawable, - GdkGC * gc, - gint width, gint height, gboolean focus) -{ - /* The bottom frame skin consists of 1 set of 4 images. The 4 - * images are: - * - * a. left corner with menu buttons (125,38) - * b. visualization window (75,38) - * c. right corner with play buttons (150,38) - * d. frame tile (25,38) - * - * (min allowed width = 125+150+25=300 - */ - - gint i, c; - - /* bottom left corner (menu buttons) */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, 72, - 0, height - 38, 125, 38); - - c = (width - 275) / 25; - - /* draw visualization window, if width allows */ - if (c >= 3) { - c -= 3; - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 205, 0, - width - (150 + 75), height - 38, 75, 38); - } - - /* Bottom right corner (playbuttons etc) */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, - 126, 72, width - 150, height - 38, 150, 38); - - /* Tile draw the remaining undrawn portions */ - for (i = 0; i < c; i++) - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 179, 0, - 125 + i * 25, height - 38, 25, 38); -} - -static void -skin_draw_playlistwin_frame_sides(Skin * skin, - GdkDrawable * drawable, - GdkGC * gc, - gint width, gint height, gboolean focus) -{ - /* The side frames consist of 2 tile images. 1 for the left, 1 for - * the right. - * a. left (12,29) - * b. right (19,29) - */ - - gint i; - - /* frame sides */ - for (i = 0; i < (height - (20 + 38)) / 29; i++) { - /* left */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, 42, - 0, 20 + i * 29, 12, 29); - - /* right */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 32, 42, - width - 19, 20 + i * 29, 19, 29); - } -} - - -void -skin_draw_playlistwin_frame(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gint width, gint height, gboolean focus) -{ - skin_draw_playlistwin_frame_top(skin, drawable, gc, width, height, focus); - skin_draw_playlistwin_frame_bottom(skin, drawable, gc, width, height, - focus); - skin_draw_playlistwin_frame_sides(skin, drawable, gc, width, height, - focus); -} - - -void -skin_draw_playlistwin_shaded(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gint width, gboolean focus) -{ - /* The shade mode titlebar skin consists of 4 images: - * a) left corner offset (72,42) size (25,14) - * b) right corner, focused offset (99,57) size (50,14) - * c) right corner, unfocused offset (99,42) size (50,14) - * d) bar tile offset (72,57) size (25,14) - */ - - gint i; - - /* left corner */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14); - - /* bar tile */ - for (i = 0; i < (width - 75) / 25; i++) - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 72, 57, - (i * 25) + 25, 0, 25, 14); - - /* right corner */ - skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 99, focus ? 57 : 42, - width - 50, 0, 50, 14); -} - - -void -skin_draw_mainwin_titlebar(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gboolean shaded, gboolean focus) -{ - /* The titlebar skin consists of 2 sets of 2 images, one for for - * shaded and the other for unshaded mode, giving a total of 4. - * The images are exactly 275x14 pixels, aligned and arranged - * vertically on each other in the pixmap in the following order: - * - * a) unshaded, focused offset (27, 0) - * b) unshaded, unfocused offset (27, 15) - * c) shaded, focused offset (27, 29) - * d) shaded, unfocused offset (27, 42) - */ - - gint y_offset; - - if (shaded) { - if (focus) - y_offset = 29; - else - y_offset = 42; - } - else { - if (focus) - y_offset = 0; - else - y_offset = 15; - } - - skin_draw_pixmap(skin, drawable, gc, SKIN_TITLEBAR, 27, y_offset, - 0, 0, MAINWIN_WIDTH, MAINWIN_TITLEBAR_HEIGHT); -} - -#if 0 -void -skin_draw_mainwin(Skin * skin, - GdkDrawable * drawable, GdkGC gc, - gboolean doublesize, gboolean shaded, gboolean focus) -{ - -} -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/skin.h --- a/audacious/skin.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef SKIN_H -#define SKIN_H - - -#include -#include - - -#define BMP_DEFAULT_SKIN_PATH \ - DATA_DIR G_DIR_SEPARATOR_S "Skins" G_DIR_SEPARATOR_S "Default" - - -typedef enum { - SKIN_MAIN = 0, - SKIN_CBUTTONS, - SKIN_TITLEBAR, - SKIN_SHUFREP, - SKIN_TEXT, - SKIN_VOLUME, - SKIN_BALANCE, - SKIN_MONOSTEREO, - SKIN_PLAYPAUSE, - SKIN_NUMBERS, - SKIN_POSBAR, - SKIN_PLEDIT, - SKIN_EQMAIN, - SKIN_EQ_EX, - SKIN_PIXMAP_COUNT -} SkinPixmapId; - -typedef enum { - SKIN_MASK_MAIN = 0, - SKIN_MASK_MAIN_SHADE, - SKIN_MASK_EQ, - SKIN_MASK_EQ_SHADE, - SKIN_MASK_COUNT -} SkinMaskId; - -typedef enum { - SKIN_PLEDIT_NORMAL = 0, - SKIN_PLEDIT_CURRENT, - SKIN_PLEDIT_NORMALBG, - SKIN_PLEDIT_SELECTEDBG, - SKIN_TEXTBG, - SKIN_TEXTFG, - SKIN_COLOR_COUNT -} SkinColorId; - -typedef struct _SkinProperties { - gboolean mainwin_othertext; -} SkinProperties; - -#define SKIN_PIXMAP(x) ((SkinPixmap *)(x)) -typedef struct _SkinPixmap { - GdkPixmap *pixmap; - /* GdkPixmap *def_pixmap; */ - - /* The real size of the pixmap */ - gint width, height; - - /* The size of the pixmap from the current skin, - which might be smaller */ - gint current_width, current_height; -} SkinPixmap; - - -#define SKIN(x) ((Skin *)(x)) -typedef struct _Skin { - GMutex *lock; - gchar *path; - gchar *def_path; - SkinPixmap pixmaps[SKIN_PIXMAP_COUNT]; - GdkColor textbg[6], def_textbg[6]; - GdkColor textfg[6], def_textfg[6]; - GdkColor *colors[SKIN_COLOR_COUNT]; - guchar vis_color[24][3]; - GdkBitmap *masks[SKIN_MASK_COUNT]; - SkinProperties properties; -} Skin; - -extern Skin *bmp_active_skin; - -gboolean init_skins(const gchar * path); -void cleanup_skins(void); - -gboolean bmp_active_skin_load(const gchar * path); -gboolean bmp_active_skin_reload(void); - -Skin *skin_new(void); -gboolean skin_load(Skin * skin, const gchar * path); -void skin_reload(Skin * skin); -void skin_free(Skin * skin); - -GdkBitmap *skin_get_mask(Skin * skin, SkinMaskId mi); -GdkColor *skin_get_color(Skin * skin, SkinColorId color_id); - -void skin_get_viscolor(Skin * skin, guchar vis_color[24][3]); -gint skin_get_id(void); -void skin_draw_pixmap(Skin * skin, GdkDrawable * drawable, GdkGC * gc, - SkinPixmapId pixmap_id, - gint xsrc, gint ysrc, gint xdest, gint ydest, - gint width, gint height); -void skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]); -void skin_install_skin(const gchar * path); - -void skin_draw_playlistwin_shaded(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gint width, gboolean focus); -void skin_draw_playlistwin_frame(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gint width, gint height, gboolean focus); - -void skin_draw_mainwin_titlebar(Skin * skin, - GdkDrawable * drawable, GdkGC * gc, - gboolean shaded, gboolean focus); - - -void skin_parse_hints(Skin * skin, gchar *path_p); - - -gboolean -skin_reload_forced(void); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/skinwin.c --- a/audacious/skinwin.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/skinwin.c Wed Aug 09 02:47:22 2006 -0700 @@ -34,7 +34,7 @@ #include #include "main.h" -#include "skin.h" +#include "widgets/skin.h" #include "util.h" #include diff -r 237bb7c97759 -r 06329cbf186a audacious/svis.c --- a/audacious/svis.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,204 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "svis.h" - -#include -#include -#include - -#include "main.h" -#include "mainwin.h" -#include "plugin.h" -#include "widget.h" -#include "vis.h" - -static gint svis_redraw_delays[] = { 1, 2, 4, 8 }; - -/* FIXME: Are the svis_scope_colors correct? */ -static guint8 svis_scope_colors[] = { 20, 19, 18, 19, 20 }; -static guint8 svis_vu_normal_colors[] = { 17, 17, 17, 12, 12, 12, 2, 2 }; - -#define DRAW_DS_PIXEL(ptr,value) \ - *(ptr) = (value); \ - *((ptr) + 1) = (value); \ - *((ptr) + 76) = (value); \ - *((ptr) + 77) = (value); - -#define SVIS_HEIGHT 5 -#define SVIS_WIDTH 38 - -void -svis_timeout_func(SVis * svis, guchar * data) -{ - static GTimer *timer = NULL; - gulong micros = 9999999; - gboolean falloff = FALSE; - gint i; - - if (!timer) { - timer = g_timer_new(); - g_timer_start(timer); - } - else { - g_timer_elapsed(timer, µs); - if (micros > 14000) - g_timer_reset(timer); - - } - - if (cfg.vis_type == INPUT_VIS_ANALYZER) { - if (micros > 14000) - falloff = TRUE; - - for (i = 0; i < 2; i++) { - if (falloff || data) { - if (data && data[i] > svis->vs_data[i]) - svis->vs_data[i] = data[i]; - else if (falloff) { - if (svis->vs_data[i] >= 2) - svis->vs_data[i] -= 2; - else - svis->vs_data[i] = 0; - } - } - - } - } - else if (data) { - for (i = 0; i < 75; i++) - svis->vs_data[i] = data[i]; - } - - if (micros > 14000) { - if (!svis->vs_refresh_delay) { - svis_draw((Widget *) svis); - svis->vs_refresh_delay = svis_redraw_delays[cfg.vis_refresh]; - - } - svis->vs_refresh_delay--; - } -} - -void -svis_draw(Widget * w) -{ - SVis *svis = (SVis *) w; - gint x, y, h; - guchar svis_color[24][3]; - guchar rgb_data[SVIS_WIDTH * 2 * SVIS_HEIGHT * 2], *ptr, c; - guint32 colors[24]; - GdkRgbCmap *cmap; - - GDK_THREADS_ENTER(); - - skin_get_viscolor(bmp_active_skin, svis_color); - for (y = 0; y < 24; y++) { - colors[y] = - svis_color[y][0] << 16 | svis_color[y][1] << 8 | svis_color[y][2]; - } - cmap = gdk_rgb_cmap_new(colors, 24); - - memset(rgb_data, 0, SVIS_WIDTH * SVIS_HEIGHT); - if (cfg.vis_type == VIS_ANALYZER) { - switch (cfg.vu_mode) { - case VU_NORMAL: - for (y = 0; y < 2; y++) { - ptr = rgb_data + ((y * 3) * 38); - h = (svis->vs_data[y] * 7) / 37; - for (x = 0; x < h; x++, ptr += 5) { - c = svis_vu_normal_colors[x]; - *(ptr) = c; - *(ptr + 1) = c; - *(ptr + 2) = c; - *(ptr + 38) = c; - *(ptr + 39) = c; - *(ptr + 40) = c; - } - } - break; - case VU_SMOOTH: - for (y = 0; y < 2; y++) { - ptr = rgb_data + ((y * 3) * SVIS_WIDTH); - for (x = 0; x < svis->vs_data[y]; x++, ptr++) { - c = 17 - ((x * 15) / 37); - *(ptr) = c; - *(ptr + 38) = c; - } - } - break; - } - } - else if (cfg.vis_type == VIS_SCOPE) { - for (x = 0; x < 38; x++) { - h = svis->vs_data[x << 1] / 3; - ptr = rgb_data + ((4 - h) * 38) + x; - *ptr = svis_scope_colors[h]; - } - } - - gdk_draw_indexed_image(mainwin->window, mainwin_gc, - svis->vs_widget.x, svis->vs_widget.y, - svis->vs_widget.width, - svis->vs_widget.height, - GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, - 38, cmap); - - gdk_rgb_cmap_free(cmap); - GDK_THREADS_LEAVE(); -} - -void -svis_clear_data(SVis * svis) -{ - gint i; - - if (!svis) - return; - - for (i = 0; i < 75; i++) { - svis->vs_data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0; - } -} - -void -svis_clear(SVis * svis) -{ - gdk_window_clear_area(mainwin->window, svis->vs_widget.x, - svis->vs_widget.y, svis->vs_widget.width, - svis->vs_widget.height); -} - -SVis * -create_svis(GList ** wlist, - GdkPixmap * parent, - GdkGC * gc, - gint x, gint y) -{ - SVis *svis; - - svis = g_new0(SVis, 1); - widget_init(&svis->vs_widget, parent, gc, x, y, SVIS_WIDTH, SVIS_HEIGHT, - 1); - - widget_list_add(wlist, WIDGET(svis)); - return svis; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/svis.h --- a/audacious/svis.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef SVIS_H -#define SVIS_H - -#include -#include - -#include "svis.h" -#include "widget.h" - -#define SVIS(x) ((SVis *)(x)) -struct _SVis { - Widget vs_widget; - gint vs_data[75]; - gint vs_refresh_delay; -}; - -typedef struct _SVis SVis; - -void svis_draw(Widget * w); -void svis_timeout_func(SVis * svis, guchar * data); -SVis *create_svis(GList ** wlist, GdkPixmap * parent, GdkGC * gc, gint x, - gint y); -void svis_set_data(SVis * vis, guchar * data); -void svis_clear_data(SVis * vis); -void svis_clear(SVis * vis); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/tbutton.c --- a/audacious/tbutton.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "tbutton.h" - -#include -#include - -#include "widget.h" - -void -tbutton_draw(Widget * w) -{ - TButton *button = TBUTTON(w); - GdkPixmap *obj; - - obj = button->tb_widget.parent; - - if (button->tb_pressed && button->tb_inside) { - if (button->tb_selected) { - skin_draw_pixmap(bmp_active_skin, obj, - button->tb_widget.gc, - button->tb_skin_index, - button->tb_psx, button->tb_psy, - button->tb_widget.x, button->tb_widget.y, - button->tb_widget.width, - button->tb_widget.height); - } - else { - skin_draw_pixmap(bmp_active_skin, obj, - button->tb_widget.gc, - button->tb_skin_index, - button->tb_pux, button->tb_puy, - button->tb_widget.x, button->tb_widget.y, - button->tb_widget.width, - button->tb_widget.height); - } - } - else { - if (button->tb_selected) { - skin_draw_pixmap(bmp_active_skin, obj, - button->tb_widget.gc, - button->tb_skin_index, - button->tb_nsx, button->tb_nsy, - button->tb_widget.x, button->tb_widget.y, - button->tb_widget.width, - button->tb_widget.height); - } - else { - skin_draw_pixmap(bmp_active_skin, obj, - button->tb_widget.gc, - button->tb_skin_index, - button->tb_nux, button->tb_nuy, - button->tb_widget.x, button->tb_widget.y, - button->tb_widget.width, - button->tb_widget.height); - - } - } -} - -void -tbutton_button_press_cb(GtkWidget * widget, GdkEventButton * event, - TButton * button) -{ - if (event->button != 1) - return; - - if (widget_contains(&button->tb_widget, event->x, event->y)) { - button->tb_pressed = 1; - button->tb_inside = 1; - widget_draw(WIDGET(button)); - } -} - -void -tbutton_button_release_cb(GtkWidget * widget, GdkEventButton * event, - TButton * button) -{ - if (event->button != 1) - return; - - if (button->tb_inside && button->tb_pressed) { - button->tb_inside = 0; - button->tb_selected = !button->tb_selected; - - widget_draw(WIDGET(button)); - - if (button->tb_push_cb) - button->tb_push_cb(button->tb_selected); - } - - if (button->tb_pressed) - button->tb_pressed = 0; -} - -void -tbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, - TButton * button) -{ - gint inside; - - if (!button->tb_pressed) - return; - inside = widget_contains(&button->tb_widget, event->x, event->y); - if (inside != button->tb_inside) { - button->tb_inside = inside; - widget_draw(WIDGET(button)); - } -} - -TButton * -create_tbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nux, gint nuy, - gint pux, gint puy, gint nsx, gint nsy, gint psx, - gint psy, void (*cb) (gboolean), SkinPixmapId si) -{ - TButton *b; - - b = g_new0(TButton, 1); - widget_init(&b->tb_widget, parent, gc, x, y, w, h, 1); - b->tb_widget.button_press_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - tbutton_button_press_cb; - b->tb_widget.button_release_cb = - (void (*)(GtkWidget *, GdkEventButton *, gpointer)) - tbutton_button_release_cb; - b->tb_widget.motion_cb = - (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) - tbutton_motion_cb; - b->tb_widget.draw = tbutton_draw; - b->tb_nux = nux; - b->tb_nuy = nuy; - b->tb_pux = pux; - b->tb_puy = puy; - b->tb_nsx = nsx; - b->tb_nsy = nsy; - b->tb_psx = psx; - b->tb_psy = psy; - b->tb_push_cb = cb; - b->tb_skin_index = si; - - widget_list_add(wlist, WIDGET(b)); - return b; -} - -void -tbutton_set_toggled(TButton * tb, gboolean toggled) -{ - tb->tb_selected = toggled; - widget_draw(WIDGET(tb)); -} - -void -free_tbutton(TButton * b) -{ - g_free(b); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/tbutton.h --- a/audacious/tbutton.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef TBUTTON_H -#define TBUTTON_H - -#include - -#include "skin.h" -#include "widget.h" - -#define TBUTTON(x) ((TButton *)(x)) -struct _TButton { - Widget tb_widget; - gint tb_nux, tb_nuy, tb_pux, tb_puy, tb_nsx, tb_nsy, tb_psx, tb_psy; - gint tb_pressed, tb_inside, tb_selected; - void (*tb_push_cb) (gboolean); - SkinPixmapId tb_skin_index; -}; - -typedef struct _TButton TButton; - -TButton *create_tbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gint h, gint nux, gint nuy, - gint pux, gint puy, gint nsx, gint nsy, gint psx, - gint psy, void (*cb) (gboolean), SkinPixmapId si); -void tbutton_set_toggled(TButton * tb, gboolean toggled); -void free_tbutton(TButton * b); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/textbox.c --- a/audacious/textbox.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,579 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "textbox.h" - -#include -#include -#include -#include -#include -#include - -#include "main.h" -#include "util.h" - -static void textbox_generate_pixmap(TextBox * tb); - -static void -textbox_draw(Widget * w) -{ - TextBox *tb = TEXT_BOX(w); - gint cw; - GdkPixmap *obj; - GdkPixmap *src; - - g_return_if_fail(tb != NULL); - - if (tb->tb_text && - (!tb->tb_pixmap_text || strcmp(tb->tb_text, tb->tb_pixmap_text))) - textbox_generate_pixmap(tb); - - if (tb->tb_pixmap) { - if (skin_get_id() != tb->tb_skin_id) { - tb->tb_skin_id = skin_get_id(); - textbox_generate_pixmap(tb); - } - obj = tb->tb_widget.parent; - src = tb->tb_pixmap; - - cw = tb->tb_pixmap_width - tb->tb_offset; - if (cw > tb->tb_widget.width) - cw = tb->tb_widget.width; - gdk_draw_pixmap(obj, tb->tb_widget.gc, src, tb->tb_offset, 0, - tb->tb_widget.x, tb->tb_widget.y, cw, - tb->tb_widget.height); - if (cw < tb->tb_widget.width) - gdk_draw_pixmap(obj, tb->tb_widget.gc, src, 0, 0, - tb->tb_widget.x + cw, tb->tb_widget.y, - tb->tb_widget.width - cw, tb->tb_widget.height); - } -} - -static gboolean -textbox_scroll(gpointer data) -{ - TextBox *tb = TEXT_BOX(data); - - if (!tb->tb_is_dragging) { - tb->tb_offset += 1; - if (tb->tb_offset >= tb->tb_pixmap_width) - tb->tb_offset -= tb->tb_pixmap_width; - widget_draw(WIDGET(tb)); - } - - return TRUE; -} - -static void -textbox_button_press(GtkWidget * w, GdkEventButton * event, gpointer data) -{ - TextBox *tb = TEXT_BOX(data); - - if (event->button != 1) - return; - if (widget_contains(&tb->tb_widget, event->x, event->y) && - tb->tb_scroll_allowed && - tb->tb_pixmap_width > tb->tb_widget.width && tb->tb_is_scrollable) { - tb->tb_is_dragging = TRUE; - tb->tb_drag_off = tb->tb_offset; - tb->tb_drag_x = event->x; - } -} - -static void -textbox_motion(GtkWidget * w, GdkEventMotion * event, gpointer data) -{ - TextBox *tb = TEXT_BOX(data); - - if (tb->tb_is_dragging) { - if (tb->tb_scroll_allowed && - tb->tb_pixmap_width > tb->tb_widget.width) { - tb->tb_offset = tb->tb_drag_off - (event->x - tb->tb_drag_x); - - while (tb->tb_offset < 0) - tb->tb_offset += tb->tb_pixmap_width; - - while (tb->tb_offset > tb->tb_pixmap_width) - tb->tb_offset -= tb->tb_pixmap_width; - - widget_draw(WIDGET(tb)); - } - } -} - -static void -textbox_button_release(GtkWidget * w, GdkEventButton * event, gpointer data) -{ - TextBox *tb = TEXT_BOX(data); - - if (event->button == 1) - tb->tb_is_dragging = FALSE; -} - -static gboolean -textbox_should_scroll(TextBox * tb) -{ - g_return_val_if_fail(tb != NULL, FALSE); - - if (!tb->tb_scroll_allowed) - return FALSE; - - if (tb->tb_font) { - gint width; - - text_get_extents(tb->tb_fontname, tb->tb_text, &width, NULL, NULL, - NULL); - - if (width <= tb->tb_widget.width) - return FALSE; - else - return TRUE; - } - - if (g_utf8_strlen(tb->tb_text, -1) * 5 > tb->tb_widget.width) - return TRUE; - - return FALSE; -} - -void -textbox_set_text(TextBox * tb, const gchar * text) -{ - g_return_if_fail(tb != NULL); - g_return_if_fail(text != NULL); - - widget_lock(WIDGET(tb)); - - if (tb->tb_text) { - if (!strcmp(text, tb->tb_text)) { - widget_unlock(WIDGET(tb)); - return; - } - g_free(tb->tb_text); - } - - tb->tb_text = str_to_utf8(text); - - widget_unlock(WIDGET(tb)); - widget_draw(WIDGET(tb)); -} - -static void -textbox_generate_xfont_pixmap(TextBox * tb, const gchar * pixmaptext) -{ - gint length, i; - GdkGC *gc, *maskgc; - GdkColor *c, pattern; - GdkBitmap *mask; - PangoLayout *layout; - gint width; - - g_return_if_fail(tb != NULL); - g_return_if_fail(pixmaptext != NULL); - - length = g_utf8_strlen(pixmaptext, -1); - - text_get_extents(tb->tb_fontname, pixmaptext, &width, NULL, NULL, NULL); - - tb->tb_pixmap_width = MAX(width, tb->tb_widget.width); - tb->tb_pixmap = gdk_pixmap_new(mainwin->window, tb->tb_pixmap_width, - tb->tb_widget.height, - gdk_rgb_get_visual()->depth); - gc = tb->tb_widget.gc; - c = skin_get_color(bmp_active_skin, SKIN_TEXTBG); - for (i = 0; i < tb->tb_widget.height; i++) { - gdk_gc_set_foreground(gc, &c[6 * i / tb->tb_widget.height]); - gdk_draw_line(tb->tb_pixmap, gc, 0, i, tb->tb_pixmap_width, i); - } - - mask = gdk_pixmap_new(mainwin->window, tb->tb_pixmap_width, - tb->tb_widget.height, 1); - maskgc = gdk_gc_new(mask); - pattern.pixel = 0; - gdk_gc_set_foreground(maskgc, &pattern); - - gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, - tb->tb_pixmap_width, tb->tb_widget.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, tb->tb_font); - - gdk_draw_layout(tb->tb_pixmap, gc, 0, (tb->tb_font_descent / 2), layout); - g_object_unref(layout); - - g_object_unref(maskgc); - - gdk_gc_set_clip_mask(gc, mask); - c = skin_get_color(bmp_active_skin, SKIN_TEXTFG); - for (i = 0; i < tb->tb_widget.height; i++) { - gdk_gc_set_foreground(gc, &c[6 * i / tb->tb_widget.height]); - gdk_draw_line(tb->tb_pixmap, gc, 0, i, tb->tb_pixmap_width, i); - } - g_object_unref(mask); - gdk_gc_set_clip_mask(gc, NULL); -} - -static void -textbox_handle_special_char(gchar c, gint * x, gint * y) -{ - switch (c) { - case '"': - *x = 130; - *y = 0; - break; - case '\r': - *x = 50; - *y = 6; - break; - case ':': - case ';': - *x = 60; - *y = 6; - break; - case '(': - *x = 65; - *y = 6; - break; - case ')': - *x = 70; - *y = 6; - break; - case '-': - *x = 75; - *y = 6; - break; - case '`': - case '\'': - *x = 80; - *y = 6; - break; - case '!': - *x = 85; - *y = 6; - break; - case '_': - *x = 90; - *y = 6; - break; - case '+': - *x = 95; - *y = 6; - break; - case '\\': - *x = 100; - *y = 6; - break; - case '/': - *x = 105; - *y = 6; - break; - case '[': - *x = 110; - *y = 6; - break; - case ']': - *x = 115; - *y = 6; - break; - case '^': - *x = 120; - *y = 6; - break; - case '&': - *x = 125; - *y = 6; - break; - case '%': - *x = 130; - *y = 6; - break; - case '.': - case ',': - *x = 135; - *y = 6; - break; - case '=': - *x = 140; - *y = 6; - break; - case '$': - *x = 145; - *y = 6; - break; - case '#': - *x = 150; - *y = 6; - break; - case 'å': - case 'Å': - *x = 0; - *y = 12; - break; - case 'ö': - case 'Ö': - *x = 5; - *y = 12; - break; - case 'ä': - case 'Ä': - *x = 10; - *y = 12; - break; - case 'ü': - case 'Ü': - *x = 100; - *y = 0; - break; - case '?': - *x = 15; - *y = 12; - break; - case '*': - *x = 20; - *y = 12; - break; - default: - *x = 145; - *y = 0; - break; - } -} - -static void -textbox_generate_pixmap(TextBox * tb) -{ - gint length, i, x, y, wl; - gchar *pixmaptext; - GdkGC *gc; - - g_return_if_fail(tb != NULL); - - if (tb->tb_pixmap) { - g_object_unref(tb->tb_pixmap); - tb->tb_pixmap = NULL; - } - - /* - * Don't reset the offset if only text after the last '(' has - * changed. This is a hack to avoid visual noice on vbr files - * where we guess the length. - */ - if (!(tb->tb_pixmap_text && strrchr(tb->tb_text, '(') && - !strncmp(tb->tb_pixmap_text, tb->tb_text, - strrchr(tb->tb_text, '(') - tb->tb_text))) - tb->tb_offset = 0; - - g_free(tb->tb_pixmap_text); - tb->tb_pixmap_text = g_strdup(tb->tb_text); - - /* - * wl is the number of (partial) letters visible. Only makes - * sense when using skinned font. - */ - - wl = tb->tb_widget.width / 5; - if (wl * 5 != tb->tb_widget.width) - wl++; - - length = g_utf8_strlen(tb->tb_text, -1); - - tb->tb_is_scrollable = FALSE; - - if (textbox_should_scroll(tb)) { - tb->tb_is_scrollable = TRUE; - pixmaptext = g_strconcat(tb->tb_pixmap_text, " *** ", NULL); - length += 7; - } - else if (!tb->tb_font && length <= wl) { - gint pad = wl - length; - gchar *padchars = g_strnfill(pad, ' '); - - pixmaptext = g_strconcat(tb->tb_pixmap_text, padchars, NULL); - g_free(padchars); - length += pad; - } - else - pixmaptext = g_strdup(tb->tb_pixmap_text); - - - if (tb->tb_is_scrollable) { - if (tb->tb_scroll_enabled && !tb->tb_timeout_tag) { - gint tag; - tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT; - tb->tb_timeout_tag = gtk_timeout_add(tag, textbox_scroll, tb); - } - } - else { - if (tb->tb_timeout_tag) { - gtk_timeout_remove(tb->tb_timeout_tag); - tb->tb_timeout_tag = 0; - } - tb->tb_offset = 0; - } - - if (tb->tb_font) { - textbox_generate_xfont_pixmap(tb, pixmaptext); - g_free(pixmaptext); - return; - } - - tb->tb_pixmap_width = length * 5; - tb->tb_pixmap = gdk_pixmap_new(mainwin->window, - tb->tb_pixmap_width, 6, - gdk_rgb_get_visual()->depth); - gc = tb->tb_widget.gc; - - for (i = 0; i < length; i++) { - gchar c; - x = y = -1; - c = toupper(pixmaptext[i]); - if (c >= 'A' && c <= 'Z') { - x = 5 * (c - 'A'); - y = 0; - } - else if (c >= '0' && c <= '9') { - x = 5 * (c - '0'); - y = 6; - } - else - textbox_handle_special_char(c, &x, &y); - - skin_draw_pixmap(bmp_active_skin, - tb->tb_pixmap, gc, tb->tb_skin_index, - x, y, i * 5, 0, 5, 6); - } - g_free(pixmaptext); -} - -void -textbox_set_scroll(TextBox * tb, gboolean s) -{ - g_return_if_fail(tb != NULL); - - tb->tb_scroll_enabled = s; - if (tb->tb_scroll_enabled && tb->tb_is_scrollable - && tb->tb_scroll_allowed) { - gint tag; - tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT; - - if (tb->tb_timeout_tag) - { - gtk_timeout_remove(tb->tb_timeout_tag); - tb->tb_timeout_tag = 0; - } - - tb->tb_timeout_tag = gtk_timeout_add(tag, textbox_scroll, tb); - } - else - { - if (tb->tb_timeout_tag) - { - gtk_timeout_remove(tb->tb_timeout_tag); - tb->tb_timeout_tag = 0; - } - - tb->tb_offset = 0; - widget_draw(WIDGET(tb)); - } - -} - -void -textbox_set_xfont(TextBox * tb, gboolean use_xfont, const gchar * fontname) -{ - gint ascent, descent; - - g_return_if_fail(tb != NULL); - - if (tb->tb_font) { - pango_font_description_free(tb->tb_font); - tb->tb_font = NULL; - } - - tb->tb_widget.y = tb->tb_nominal_y; - tb->tb_widget.height = tb->tb_nominal_height; - - /* Make sure the pixmap is regenerated */ - if (tb->tb_pixmap_text) { - g_free(tb->tb_pixmap_text); - tb->tb_pixmap_text = NULL; - } - - if (!use_xfont || strlen(fontname) == 0) - return; - - tb->tb_font = pango_font_description_from_string(fontname); - tb->tb_fontname = g_strdup(fontname); - - text_get_extents(fontname, - "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ", - NULL, NULL, &ascent, &descent); - tb->tb_font_ascent = ascent; - tb->tb_font_descent = descent; - - - if (tb->tb_font == NULL) - return; - - tb->tb_widget.height = tb->tb_font_ascent; - if (tb->tb_widget.height > tb->tb_nominal_height) - tb->tb_widget.y -= (tb->tb_widget.height - tb->tb_nominal_height) / 2; - else - tb->tb_widget.height = tb->tb_nominal_height; -} - -TextBox * -create_textbox(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) -{ - TextBox *tb; - - tb = g_new0(TextBox, 1); - widget_init(&tb->tb_widget, parent, gc, x, y, w, 6, 1); - tb->tb_widget.button_press_cb = textbox_button_press; - tb->tb_widget.button_release_cb = textbox_button_release; - tb->tb_widget.motion_cb = textbox_motion; - tb->tb_widget.draw = textbox_draw; - tb->tb_scroll_allowed = allow_scroll; - tb->tb_scroll_enabled = TRUE; - tb->tb_skin_index = si; - tb->tb_nominal_y = y; - tb->tb_nominal_height = tb->tb_widget.height; - widget_list_add(wlist, WIDGET(tb)); - tb->tb_timeout_tag = 0; - return tb; -} - -void -textbox_free(TextBox * tb) -{ - g_return_if_fail(tb != NULL); - - if (tb->tb_pixmap) - g_object_unref(tb->tb_pixmap); - g_free(tb->tb_text); - g_free(tb); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/textbox.h --- a/audacious/textbox.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef TEXTBOX_H -#define TEXTBOX_H - -#include -#include -#include - -#include "skin.h" -#include "widget.h" - -#define TEXTBOX_SCROLL_TIMEOUT 200 -#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT 30 - -#define TEXT_BOX(x) ((TextBox *)(x)) -struct _TextBox { - Widget tb_widget; - GdkPixmap *tb_pixmap; - gchar *tb_text, *tb_pixmap_text; - gint tb_pixmap_width; - gint tb_offset; - gboolean tb_scroll_allowed, tb_scroll_enabled; - gboolean tb_is_scrollable, tb_is_dragging; - gint tb_timeout_tag, tb_drag_x, tb_drag_off; - gint tb_nominal_y, tb_nominal_height; - gint tb_skin_id; - SkinPixmapId tb_skin_index; - PangoFontDescription *tb_font; - gint tb_font_ascent, tb_font_descent; - gchar *tb_fontname; -}; - -typedef struct _TextBox TextBox; - -void textbox_set_text(TextBox * tb, const gchar * text); -void textbox_set_scroll(TextBox * tb, gboolean s); -TextBox *create_textbox(GList ** wlist, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint w, gboolean allow_scroll, - SkinPixmapId si); -void textbox_set_xfont(TextBox * tb, gboolean use_xfont, - const gchar * fontname); -void textbox_free(TextBox * tb); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/ui_fileinfo.c --- a/audacious/ui_fileinfo.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/ui_fileinfo.c Wed Aug 09 02:47:22 2006 -0700 @@ -47,7 +47,6 @@ #include "visualization.h" #include "main.h" -#include "skin.h" #include "urldecode.h" #include "util.h" #include "dnd.h" @@ -59,7 +58,6 @@ #include "mainwin.h" #include "ui_playlist.h" #include "skinwin.h" -#include "playlist_list.h" #include "build_stamp.h" #include "ui_fileinfo.h" #include "ui_playlist.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/ui_playlist.c --- a/audacious/ui_playlist.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/ui_playlist.c Wed Aug 09 02:47:22 2006 -0700 @@ -48,12 +48,12 @@ #include "mainwin.h" #include "playback.h" #include "playlist.h" -#include "playlist_list.h" -#include "playlist_slider.h" -#include "pbutton.h" -#include "sbutton.h" -#include "skin.h" -#include "textbox.h" +#include "widgets/playlist_list.h" +#include "widgets/playlist_slider.h" +#include "widgets/pbutton.h" +#include "widgets/sbutton.h" +#include "widgets/skin.h" +#include "widgets/textbox.h" #include "util.h" #include "pixmaps.h" diff -r 237bb7c97759 -r 06329cbf186a audacious/ui_playlist.h --- a/audacious/ui_playlist.h Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/ui_playlist.h Wed Aug 09 02:47:22 2006 -0700 @@ -25,8 +25,8 @@ #include #include "mainwin.h" -#include "pbutton.h" -#include "playlist_list.h" +#include "widgets/pbutton.h" +#include "widgets/playlist_list.h" #define PLAYLISTWIN_FRAME_TOP_HEIGHT 20 diff -r 237bb7c97759 -r 06329cbf186a audacious/vis.c --- a/audacious/vis.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "vis.h" - -#include -#include -#include - -#include "main.h" -#include "skin.h" -#include "widget.h" - -static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 }; -static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 }; -static const gint vis_redraw_delays[] = { 1, 2, 4, 8 }; -static const guint8 vis_scope_colors[] = - { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 }; - -void -vis_timeout_func(Vis * vis, guchar * data) -{ - static GTimer *timer = NULL; - gulong micros = 9999999; - gboolean falloff = FALSE; - gint i; - - if (!timer) { - timer = g_timer_new(); - g_timer_start(timer); - } - else { - g_timer_elapsed(timer, µs); - if (micros > 14000) - g_timer_reset(timer); - - } - - if (cfg.vis_type == VIS_ANALYZER) { - if (micros > 14000) - falloff = TRUE; - if (data || falloff) { - for (i = 0; i < 75; i++) { - if (data && data[i] > vis->vs_data[i]) { - vis->vs_data[i] = data[i]; - if (vis->vs_data[i] > vis->vs_peak[i]) { - vis->vs_peak[i] = vis->vs_data[i]; - vis->vs_peak_speed[i] = 0.01; - - } - else if (vis->vs_peak[i] > 0.0) { - vis->vs_peak[i] -= vis->vs_peak_speed[i]; - vis->vs_peak_speed[i] *= - vis_pfalloff_speeds[cfg.peaks_falloff]; - if (vis->vs_peak[i] < vis->vs_data[i]) - vis->vs_peak[i] = vis->vs_data[i]; - if (vis->vs_peak[i] < 0.0) - vis->vs_peak[i] = 0.0; - } - } - else if (falloff) { - if (vis->vs_data[i] > 0.0) { - vis->vs_data[i] -= - vis_afalloff_speeds[cfg.analyzer_falloff]; - if (vis->vs_data[i] < 0.0) - vis->vs_data[i] = 0.0; - } - if (vis->vs_peak[i] > 0.0) { - vis->vs_peak[i] -= vis->vs_peak_speed[i]; - vis->vs_peak_speed[i] *= - vis_pfalloff_speeds[cfg.peaks_falloff]; - if (vis->vs_peak[i] < vis->vs_data[i]) - vis->vs_peak[i] = vis->vs_data[i]; - if (vis->vs_peak[i] < 0.0) - vis->vs_peak[i] = 0.0; - } - } - } - } - } - else if (data) { - for (i = 0; i < 75; i++) - vis->vs_data[i] = data[i]; - } - - if (micros > 14000) { - if (!vis->vs_refresh_delay) { - vis_draw((Widget *) vis); - vis->vs_refresh_delay = vis_redraw_delays[cfg.vis_refresh]; - - } - vis->vs_refresh_delay--; - } -} - -void -vis_draw(Widget * w) -{ - Vis *vis = (Vis *) w; - gint x, y, h = 0, h2; - guchar vis_color[24][3]; - guchar rgb_data[152 * 32], *ptr, c; - guint32 colors[24]; - GdkRgbCmap *cmap; - - if (!vis->vs_widget.visible) - return; - - skin_get_viscolor(bmp_active_skin, vis_color); - for (y = 0; y < 24; y++) { - colors[y] = - vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2]; - } - cmap = gdk_rgb_cmap_new(colors, 24); - - memset(rgb_data, 0, 76 * 16); - for (y = 1; y < 16; y += 2) { - ptr = rgb_data + (y * 76); - for (x = 0; x < 76; x += 2, ptr += 2) - *ptr = 1; - } - if (cfg.vis_type == VIS_ANALYZER) { - for (x = 0; x < 75; x++) { - if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) - h = vis->vs_data[x >> 2]; - else if (cfg.analyzer_type == ANALYZER_LINES) - h = vis->vs_data[x]; - if (h && (cfg.analyzer_type == ANALYZER_LINES || - (x % 4) != 3)) { - ptr = rgb_data + ((16 - h) * 76) + x; - switch (cfg.analyzer_mode) { - case ANALYZER_NORMAL: - for (y = 0; y < h; y++, ptr += 76) - *ptr = 18 - h + y; - break; - case ANALYZER_FIRE: - for (y = 0; y < h; y++, ptr += 76) - *ptr = y + 2; - break; - case ANALYZER_VLINES: - for (y = 0; y < h; y++, ptr += 76) - *ptr = 18 - h; - break; - } - } - } - if (cfg.analyzer_peaks) { - for (x = 0; x < 75; x++) { - if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) - h = vis->vs_peak[x >> 2]; - else if (cfg.analyzer_type == ANALYZER_LINES) - h = vis->vs_peak[x]; - if (h - && (cfg.analyzer_type == ANALYZER_LINES - || (x % 4) != 3)) - rgb_data[(16 - h) * 76 + x] = 23; - } - } - } - else if (cfg.vis_type == VIS_SCOPE) { - for (x = 0; x < 75; x++) { - switch (cfg.scope_mode) { - case SCOPE_DOT: - h = vis->vs_data[x]; - ptr = rgb_data + ((15 - h) * 76) + x; - *ptr = vis_scope_colors[h]; - break; - case SCOPE_LINE: - if (x != 74) { - h = 15 - vis->vs_data[x]; - h2 = 15 - vis->vs_data[x + 1]; - if (h > h2) { - y = h; - h = h2; - h2 = y; - } - ptr = rgb_data + (h * 76) + x; - for (y = h; y <= h2; y++, ptr += 76) - *ptr = vis_scope_colors[y - 3]; - - } - else { - h = 15 - vis->vs_data[x]; - ptr = rgb_data + (h * 76) + x; - *ptr = vis_scope_colors[h]; - } - break; - case SCOPE_SOLID: - h = 15 - vis->vs_data[x]; - h2 = 9; - c = vis_scope_colors[(gint) vis->vs_data[x]]; - if (h > h2) { - y = h; - h = h2; - h2 = y; - } - ptr = rgb_data + (h * 76) + x; - for (y = h; y <= h2; y++, ptr += 76) - *ptr = c; - break; - } - } - } - - /* FIXME: The check "shouldn't" be neccessary? */ - /* if (GTK_IS_WINDOW(vis->vs_window)) { */ - GDK_THREADS_ENTER(); - gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, - vis->vs_widget.x, vis->vs_widget.y, - vis->vs_widget.width, vis->vs_widget.height, - GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, - 76, cmap); - GDK_THREADS_LEAVE(); - /* } else { - vis->vs_window = mainwin->window; - GDK_THREADS_ENTER(); - gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, - vis->vs_widget.x, vis->vs_widget.y, - vis->vs_widget.width, vis->vs_widget.height, - GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, - 76, cmap); - GDK_THREADS_LEAVE(); - } - */ - - gdk_rgb_cmap_free(cmap); -} - -void -vis_clear_data(Vis * vis) -{ - gint i; - - if (!vis) - return; - - for (i = 0; i < 75; i++) { - vis->vs_data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0; - vis->vs_peak[i] = 0; - } -} - -void -vis_clear(Vis * vis) -{ - gdk_window_clear_area(vis->vs_window, vis->vs_widget.x, - vis->vs_widget.y, vis->vs_widget.width, - vis->vs_widget.height); -} - -void -vis_set_window(Vis * vis, GdkWindow * window) -{ - vis->vs_window = window; -} - -Vis * -create_vis(GList ** wlist, - GdkPixmap * parent, - GdkWindow * window, - GdkGC * gc, - gint x, gint y, - gint width) -{ - Vis *vis; - - vis = g_new0(Vis, 1); - - widget_init(&vis->vs_widget, parent, gc, x, y, width, 16, 1); - widget_list_add(wlist, WIDGET(vis)); - - return vis; -} diff -r 237bb7c97759 -r 06329cbf186a audacious/vis.h --- a/audacious/vis.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef VIS_H -#define VIS_H - -#include -#include - -#include "widget.h" - -typedef enum { - VIS_ANALYZER, VIS_SCOPE, VIS_OFF -} VisType; - -typedef enum { - ANALYZER_NORMAL, ANALYZER_FIRE, ANALYZER_VLINES -} AnalyzerMode; - -typedef enum { - ANALYZER_LINES, ANALYZER_BARS -} AnalyzerType; - -typedef enum { - SCOPE_DOT, SCOPE_LINE, SCOPE_SOLID -} ScopeMode; - -typedef enum { - VU_NORMAL, VU_SMOOTH -} VUMode; - -typedef enum { - REFRESH_FULL, REFRESH_HALF, REFRESH_QUARTER, REFRESH_EIGTH -} RefreshRate; - -typedef enum { - FALLOFF_SLOWEST, FALLOFF_SLOW, FALLOFF_MEDIUM, FALLOFF_FAST, - FALLOFF_FASTEST -} FalloffSpeed; - -#define VIS(x) ((Vis *)(x)) -struct _Vis { - Widget vs_widget; - GdkWindow *vs_window; - gfloat vs_data[75], vs_peak[75], vs_peak_speed[75]; - gint vs_refresh_delay; -}; - -typedef struct _Vis Vis; - -void vis_draw(Widget * w); - -Vis *create_vis(GList ** wlist, GdkPixmap * parent, GdkWindow * window, - GdkGC * gc, gint x, gint y, gint width); -void vis_timeout_func(Vis * vis, guchar * data); -void vis_clear_data(Vis * vis); -void vis_clear(Vis * vis); -void vis_set_window(Vis * vis, GdkWindow * window); - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/visualization.c --- a/audacious/visualization.c Wed Aug 09 02:11:01 2006 -0700 +++ b/audacious/visualization.c Wed Aug 09 02:47:22 2006 -0700 @@ -32,9 +32,9 @@ #include "playback.h" #include "plugin.h" #include "prefswin.h" -#include "svis.h" -#include "vis.h" -#include "widget.h" +#include "widgets/svis.h" +#include "widgets/vis.h" +#include "widgets/widget.h" VisPluginData vp_data = { NULL, diff -r 237bb7c97759 -r 06329cbf186a audacious/widget.c --- a/audacious/widget.c Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,263 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "widget.h" - -#include -#include - -#include "debug.h" - - -void -widget_init(Widget * widget, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint width, gint height, gint visible) -{ - widget->parent = parent; - widget->gc = gc; - widget_set_position(widget, x, y); - widget_set_size(widget, width, height); - widget->visible = visible; - widget->redraw = TRUE; - widget->mutex = g_mutex_new(); -} - -void -widget_set_position(Widget * widget, gint x, gint y) -{ - widget->x = x; - widget->y = y; - widget_queue_redraw(widget); -} - -void -widget_set_size(Widget * widget, gint width, gint height) -{ - widget->width = width; - widget->height = height; - widget_queue_redraw(widget); -} - -void -widget_queue_redraw(Widget * widget) -{ - widget->redraw = TRUE; -} - -gboolean -widget_contains(Widget * widget, gint x, gint y) -{ - return (widget->visible && - x >= widget->x && - y >= widget->y && - x < widget->x + widget->width && - y < widget->y + widget->height); -} - -void -widget_show(Widget * widget) -{ - if (!widget) - return; - - widget->visible = TRUE; - widget_draw(widget); -} - -void -widget_hide(Widget * widget) -{ - if (!widget) - return; - - widget->visible = FALSE; -} - -gboolean -widget_is_visible(Widget * widget) -{ - if (!widget) - return FALSE; - - return widget->visible; -} - -void -widget_resize(Widget * widget, gint width, gint height) -{ - widget_set_size(widget, width, height); -} - -void -widget_move(Widget * widget, gint x, gint y) -{ - widget_lock(widget); - widget_set_position(widget, x, y); - widget_unlock(widget); -} - -void -widget_draw(Widget * widget) -{ - widget_lock(widget); - WIDGET(widget)->redraw = TRUE; - widget_unlock(widget); -} - -void -widget_draw_quick(Widget * widget) -{ - widget_lock(widget); - if (WIDGET(widget)->draw != NULL) - { - WIDGET(widget)->draw(widget); - gdk_flush(); - } - widget_unlock(widget); -} - -void -widget_list_add(GList ** list, Widget * widget) -{ - (*list) = g_list_append(*list, widget); -} - -void -handle_press_cb(GList * widget_list, GtkWidget * widget, - GdkEventButton * event) -{ - GList *wl; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - if (WIDGET(wl->data)->button_press_cb) - WIDGET(wl->data)->button_press_cb(widget, event, wl->data); - } -} - -void -handle_release_cb(GList * widget_list, GtkWidget * widget, - GdkEventButton * event) -{ - GList *wl; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - if (WIDGET(wl->data)->button_release_cb) - WIDGET(wl->data)->button_release_cb(widget, event, wl->data); - } -} - -void -handle_motion_cb(GList * widget_list, GtkWidget * widget, - GdkEventMotion * event) -{ - GList *wl; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - if (WIDGET(wl->data)->motion_cb) - WIDGET(wl->data)->motion_cb(widget, event, wl->data); - } -} - -void -handle_scroll_cb(GList * wlist, GtkWidget * widget, GdkEventScroll * event) -{ - GList *wl; - - for (wl = wlist; wl; wl = g_list_next(wl)) { - if (WIDGET(wl->data)->mouse_scroll_cb) - WIDGET(wl->data)->mouse_scroll_cb(widget, event, wl->data); - } -} - -void -widget_list_draw(GList * widget_list, gboolean * redraw, gboolean force) -{ - GList *wl; - Widget *w; - - *redraw = FALSE; - wl = widget_list; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - w = WIDGET(wl->data); - - REQUIRE_LOCK(w->mutex); - - if (!w->draw) - continue; - - if (!w->visible) - continue; - - if (w->redraw || force) { - w->draw(w); -/* w->redraw = FALSE; */ - *redraw = TRUE; - } - } -} - -void -widget_list_change_pixmap(GList * widget_list, GdkPixmap * pixmap) -{ - GList *wl; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - Widget *widget = wl->data; - widget->parent = pixmap; - widget_queue_redraw(widget); - } -} - -void -widget_list_clear_redraw(GList * widget_list) -{ - GList *wl; - - for (wl = widget_list; wl; wl = g_list_next(wl)) { - REQUIRE_LOCK(WIDGET(wl->data)->mutex); - WIDGET(wl->data)->redraw = FALSE; - } -} - -void -widget_lock(Widget * widget) -{ - g_mutex_lock(WIDGET(widget)->mutex); -} - -void -widget_unlock(Widget * widget) -{ - g_mutex_unlock(WIDGET(widget)->mutex); -} - -void -widget_list_lock(GList * widget_list) -{ - g_list_foreach(widget_list, (GFunc) widget_lock, NULL); -} - -void -widget_list_unlock(GList * widget_list) -{ - g_list_foreach(widget_list, (GFunc) widget_unlock, NULL); -} diff -r 237bb7c97759 -r 06329cbf186a audacious/widget.h --- a/audacious/widget.h Wed Aug 09 02:11:01 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -#ifndef WIDGET_H -#define WIDGET_H - - -#include -#include -#include - - -typedef struct _Widget Widget; - - -typedef void (*WidgetButtonPressFunc) (GtkWidget *, GdkEventButton *, - gpointer); -typedef void (*WidgetButtonReleaseFunc) (GtkWidget *, GdkEventButton *, - gpointer); -typedef void (*WidgetMotionFunc) (GtkWidget *, GdkEventMotion *, gpointer); -typedef void (*WidgetDrawFunc) (Widget *); -typedef void (*WidgetScrollFunc) (GtkWidget *, GdkEventScroll *, gpointer); - - -#define WIDGET(x) ((Widget *)(x)) -struct _Widget { - GdkPixmap *parent; - GdkGC *gc; - - gint x, y; - gint width, height; - - gint visible; - gboolean redraw; - - GMutex *mutex; - - WidgetButtonPressFunc button_press_cb; - WidgetButtonReleaseFunc button_release_cb; - WidgetMotionFunc motion_cb; - WidgetDrawFunc draw; - WidgetScrollFunc mouse_scroll_cb; -}; - - -void widget_init(Widget * widget, GdkPixmap * parent, GdkGC * gc, - gint x, gint y, gint width, gint height, gint visible); - -void widget_set_position(Widget * widget, gint x, gint y); -void widget_set_size(Widget * widget, gint width, gint height); -void widget_queue_redraw(Widget * widget); - -void widget_lock(Widget * widget); -void widget_unlock(Widget * widget); - -gboolean widget_contains(Widget * widget, gint x, gint y); - -void widget_show(Widget * widget); -void widget_hide(Widget * widget); -gboolean widget_is_visible(Widget * widget); - -void widget_resize(Widget * widget, gint width, gint height); -void widget_move(Widget * widget, gint x, gint y); -void widget_draw(Widget * widget); -void widget_draw_quick(Widget * widget); - -void handle_press_cb(GList * wlist, GtkWidget * widget, - GdkEventButton * event); -void handle_release_cb(GList * wlist, GtkWidget * widget, - GdkEventButton * event); -void handle_motion_cb(GList * wlist, GtkWidget * widget, - GdkEventMotion * event); -void handle_scroll_cb(GList * wlist, GtkWidget * widget, - GdkEventScroll * event); - -void widget_list_add(GList ** list, Widget * widget); -void widget_list_draw(GList * list, gboolean * redraw, gboolean force); -void widget_list_change_pixmap(GList * list, GdkPixmap * pixmap); -void widget_list_clear_redraw(GList * list); -void widget_list_lock(GList * list); -void widget_list_unlock(GList * list); - - - -#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/Makefile Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,37 @@ +include ../../mk/rules.mk +include ../../mk/objective.mk + +OBJECTIVE_LIBS_NOINST = libwidgets.a + +LDFLAGS += -Wl,-export-dynamic + +CFLAGS += \ + $(GTK_CFLAGS) \ + $(LIBGLADE_CFLAGS) \ + $(BEEP_DEFINES) \ + $(ARCH_DEFINES) \ + -I../.. \ + -I.. \ + -I../../intl + +SOURCES = \ + widget.c \ + sbutton.c \ + pbutton.c \ + tbutton.c \ + textbox.c \ + hslider.c \ + menurow.c \ + monostereo.c \ + vis.c \ + svis.c \ + number.c \ + playstatus.c \ + playlist_list.c \ + playlist_slider.c \ + eq_graph.c \ + eq_slider.c \ + skin.c + +OBJECTS = ${SOURCES:.c=.o} + diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/eq_graph.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/eq_graph.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,149 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "eq_graph.h" + +#include + +#include "main.h" +#include "skin.h" + +void +init_spline(gfloat * x, gfloat * y, gint n, gfloat * y2) +{ + gint i, k; + gfloat p, qn, sig, un, *u; + + u = (gfloat *) g_malloc(n * sizeof(gfloat)); + + y2[0] = u[0] = 0.0; + + for (i = 1; i < n - 1; i++) { + sig = ((gfloat) x[i] - x[i - 1]) / ((gfloat) x[i + 1] - x[i - 1]); + p = sig * y2[i - 1] + 2.0; + y2[i] = (sig - 1.0) / p; + u[i] = + (((gfloat) y[i + 1] - y[i]) / (x[i + 1] - x[i])) - + (((gfloat) y[i] - y[i - 1]) / (x[i] - x[i - 1])); + u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p; + } + qn = un = 0.0; + + y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0); + for (k = n - 2; k >= 0; k--) + y2[k] = y2[k] * y2[k + 1] + u[k]; + g_free(u); +} + +gfloat +eval_spline(gfloat xa[], gfloat ya[], gfloat y2a[], gint n, gfloat x) +{ + gint klo, khi, k; + gfloat h, b, a; + + klo = 0; + khi = n - 1; + while (khi - klo > 1) { + k = (khi + klo) >> 1; + if (xa[k] > x) + khi = k; + else + klo = k; + } + h = xa[khi] - xa[klo]; + a = (xa[khi] - x) / h; + b = (x - xa[klo]) / h; + return (a * ya[klo] + b * ya[khi] + + ((a * a * a - a) * y2a[klo] + + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0); +} + +void +eqgraph_draw(Widget * w) +{ + EqGraph *eg = (EqGraph *) w; + GdkPixmap *obj; + GdkColor col; + guint32 cols[19]; + gint i, y, ymin, ymax, py = 0; + gfloat x[] = { 0, 11, 23, 35, 47, 59, 71, 83, 97, 109 }, yf[10]; + + /* + * This avoids the init_spline() function to be inlined. + * Inlining the function caused troubles when compiling with + * `-O' (at least on FreeBSD). + */ + void (*__init_spline) (gfloat *, gfloat *, gint, gfloat *) = init_spline; + + obj = eg->eg_widget.parent; + skin_draw_pixmap(bmp_active_skin, obj, eg->eg_widget.gc, SKIN_EQMAIN, + 0, 294, eg->eg_widget.x, eg->eg_widget.y, + eg->eg_widget.width, eg->eg_widget.height); + skin_draw_pixmap(bmp_active_skin, obj, eg->eg_widget.gc, SKIN_EQMAIN, + 0, 314, eg->eg_widget.x, + eg->eg_widget.y + 9 + + ((cfg.equalizer_preamp * 9) / 20), + eg->eg_widget.width, 1); + + skin_get_eq_spline_colors(bmp_active_skin, cols); + + __init_spline(x, cfg.equalizer_bands, 10, yf); + for (i = 0; i < 109; i++) { + y = 9 - + (gint) ((eval_spline(x, cfg.equalizer_bands, yf, 10, i) * + 9.0) / 20.0); + if (y < 0) + y = 0; + if (y > 18) + y = 18; + if (!i) + py = y; + if (y < py) { + ymin = y; + ymax = py; + } + else { + ymin = py; + ymax = y; + } + py = y; + for (y = ymin; y <= ymax; y++) { + col.pixel = cols[y]; + gdk_gc_set_foreground(eg->eg_widget.gc, &col); + gdk_draw_point(obj, eg->eg_widget.gc, eg->eg_widget.x + i + 2, + eg->eg_widget.y + y); + } + } +} + +EqGraph * +create_eqgraph(GList ** wlist, GdkPixmap * parent, GdkGC * gc, gint x, gint y) +{ + EqGraph *eg; + + eg = g_new0(EqGraph, 1); + widget_init(&eg->eg_widget, parent, gc, x, y, 113, 19, TRUE); + eg->eg_widget.draw = eqgraph_draw; + + widget_list_add(wlist, WIDGET(eg)); + + return eg; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/eq_graph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/eq_graph.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,40 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef EQ_GRAPH_H +#define EQ_GRAPH_H + +#include +#include + +#include "widget.h" + +#define EQ_GRAPH(x) ((EqGraph *)(x)) +struct _EqGraph { + Widget eg_widget; +}; + +typedef struct _EqGraph EqGraph; + +EqGraph *create_eqgraph(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/eq_slider.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/eq_slider.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,235 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "eq_slider.h" + +#include +#include +#include +#include + +#include "equalizer.h" +#include "mainwin.h" +#include "skin.h" + +void +eqslider_set_position(EqSlider * es, + gfloat pos) +{ + es->es_position = 25 - (gint) ((pos * 25.0) / 20.0); + + if (es->es_position < 0) + es->es_position = 0; + + if (es->es_position > 50) + es->es_position = 50; + + if (es->es_position >= 24 && es->es_position <= 26) + es->es_position = 25; + + widget_draw(WIDGET(es)); +} + +gfloat +eqslider_get_position(EqSlider * es) +{ + return 20.0 - (((gfloat) es->es_position * 20.0) / 25.0); +} + +void +eqslider_draw(Widget * w) +{ + EqSlider *es = (EqSlider *) w; + GdkPixmap *obj; + SkinPixmapId src; + gint frame; + + src = SKIN_EQMAIN; + obj = es->es_widget.parent; + + frame = 27 - ((es->es_position * 27) / 50); + if (frame < 14) + skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, + (frame * 15) + 13, 164, es->es_widget.x, + es->es_widget.y, es->es_widget.width, + es->es_widget.height); + else + skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, + ((frame - 14) * 15) + 13, 229, es->es_widget.x, + es->es_widget.y, es->es_widget.width, + es->es_widget.height); + if (es->es_isdragging) + skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, 0, + 176, es->es_widget.x + 1, + es->es_widget.y + es->es_position, 11, 11); + else + skin_draw_pixmap(bmp_active_skin, obj, es->es_widget.gc, src, 0, + 164, es->es_widget.x + 1, + es->es_widget.y + es->es_position, 11, 11); +} + +void +eqslider_set_mainwin_text(EqSlider * es) +{ + gint band = 0; + const gchar *bandname[11] = { N_("PREAMP"), N_("60HZ"), N_("170HZ"), + N_("310HZ"), N_("600HZ"), N_("1KHZ"), + N_("3KHZ"), N_("6KHZ"), N_("12KHZ"), + N_("14KHZ"), N_("16KHZ") + }; + gchar *tmp; + + if (es->es_widget.x > 21) + band = ((es->es_widget.x - 78) / 18) + 1; + + tmp = + g_strdup_printf("EQ: %s: %+.1f DB", _(bandname[band]), + eqslider_get_position(es)); + mainwin_lock_info_text(tmp); + g_free(tmp); +} + +void +eqslider_button_press_cb(GtkWidget * w, + GdkEventButton * event, + gpointer data) +{ + EqSlider *es = EQ_SLIDER(data); + gint y; + + if (widget_contains(&es->es_widget, event->x, event->y)) { + if (event->button == 1) { + y = event->y - es->es_widget.y; + es->es_isdragging = TRUE; + if (y >= es->es_position && y < es->es_position + 11) + es->es_drag_y = y - es->es_position; + else { + es->es_position = y - 5; + es->es_drag_y = 5; + if (es->es_position < 0) + es->es_position = 0; + if (es->es_position > 50) + es->es_position = 50; + if (es->es_position >= 24 && es->es_position <= 26) + es->es_position = 25; + equalizerwin_eq_changed(); + } + + eqslider_set_mainwin_text(es); + widget_draw(WIDGET(es)); + } + if (event->button == 4) { + es->es_position -= 2; + if (es->es_position < 0) + es->es_position = 0; + equalizerwin_eq_changed(); + widget_draw(WIDGET(es)); + } + } +} + +void +eqslider_mouse_scroll_cb(GtkWidget * w, + GdkEventScroll * event, + gpointer data) +{ + EqSlider *es = EQ_SLIDER(data); + + if (!widget_contains(&es->es_widget, event->x, event->y)) + return; + + if (event->direction == GDK_SCROLL_UP) { + es->es_position -= 2; + + if (es->es_position < 0) + es->es_position = 0; + + equalizerwin_eq_changed(); + widget_draw(WIDGET(es)); + } + else { + es->es_position += 2; + + if (es->es_position > 50) + es->es_position = 50; + + equalizerwin_eq_changed(); + widget_draw(WIDGET(es)); + } +} + +void +eqslider_motion_cb(GtkWidget * w, + GdkEventMotion * event, + gpointer data) +{ + EqSlider *es = EQ_SLIDER(data); + gint y; + + y = event->y - es->es_widget.y; + if (es->es_isdragging) { + es->es_position = y - es->es_drag_y; + if (es->es_position < 0) + es->es_position = 0; + if (es->es_position > 50) + es->es_position = 50; + if (es->es_position >= 24 && es->es_position <= 26) + es->es_position = 25; + equalizerwin_eq_changed(); + eqslider_set_mainwin_text(es); + widget_draw(WIDGET(es)); + } +} + +void +eqslider_button_release_cb(GtkWidget * w, + GdkEventButton * event, + gpointer data) +{ + EqSlider *es = EQ_SLIDER(data); + + if (es->es_isdragging) { + es->es_isdragging = FALSE; + mainwin_release_info_text(); + widget_draw(WIDGET(es)); + } +} + +EqSlider * +create_eqslider(GList ** wlist, + GdkPixmap * parent, + GdkGC * gc, + gint x, gint y) +{ + EqSlider *es; + + es = g_new0(EqSlider, 1); + widget_init(&es->es_widget, parent, gc, x, y, 14, 63, TRUE); + es->es_widget.button_press_cb = eqslider_button_press_cb; + es->es_widget.button_release_cb = eqslider_button_release_cb; + es->es_widget.motion_cb = eqslider_motion_cb; + es->es_widget.draw = eqslider_draw; + es->es_widget.mouse_scroll_cb = eqslider_mouse_scroll_cb; + + widget_list_add(wlist, WIDGET(es)); + + return es; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/eq_slider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/eq_slider.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,44 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef EQ_SLIDER_H +#define EQ_SLIDER_H + +#include +#include + +#include "widget.h" + +#define EQ_SLIDER(x) ((EqSlider *)(x)) +struct _EqSlider { + Widget es_widget; + gint es_position; + gboolean es_isdragging; + gint es_drag_y; +}; + +typedef struct _EqSlider EqSlider; + +EqSlider *create_eqslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y); +void eqslider_set_position(EqSlider * es, gfloat pos); +gfloat eqslider_get_position(EqSlider * es); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/hslider.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/hslider.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,203 @@ +/* XMMS - Cross-platform multimedia player + * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "hslider.h" + +#include +#include +#include + +#include "skin.h" + +void +hslider_set_position(HSlider * hs, + gint pos) +{ + if (pos == hs->hs_position || hs->hs_pressed) + return; + + hs->hs_position = pos; + + if (hs->hs_frame_cb) + hs->hs_frame = hs->hs_frame_cb(hs->hs_position); + + widget_draw(WIDGET(hs)); +} + +gint +hslider_get_position(HSlider * hs) +{ + return hs->hs_position; +} + +void +hslider_draw(Widget * w) +{ + HSlider *hs = (HSlider *) w; + GdkPixmap *obj; + + obj = hs->hs_widget.parent; + + skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, + hs->hs_skin_index, hs->hs_frame_offset, + hs->hs_frame * hs->hs_frame_height, hs->hs_widget.x, + hs->hs_widget.y, hs->hs_widget.width, + hs->hs_widget.height); + if (hs->hs_pressed) + skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, + hs->hs_skin_index, hs->hs_knob_px, + hs->hs_knob_py, hs->hs_widget.x + hs->hs_position, + hs->hs_widget.y + + ((hs->hs_widget.height - hs->hs_knob_height) / 2), + hs->hs_knob_width, hs->hs_knob_height); + else + skin_draw_pixmap(bmp_active_skin, obj, hs->hs_widget.gc, + hs->hs_skin_index, hs->hs_knob_nx, hs->hs_knob_ny, + hs->hs_widget.x + hs->hs_position, + hs->hs_widget.y + + ((hs->hs_widget.height - hs->hs_knob_height) / 2), + hs->hs_knob_width, hs->hs_knob_height); +} + +void +hslider_button_press_cb(GtkWidget * w, + GdkEventButton * event, + gpointer data) +{ + HSlider *hs = HSLIDER(data); + gint x; + + if (event->button != 1) + return; + + if (widget_contains(&hs->hs_widget, event->x, event->y)) { + x = event->x - hs->hs_widget.x; + hs->hs_pressed = TRUE; + + if (x >= hs->hs_position && x < hs->hs_position + hs->hs_knob_width) + hs->hs_pressed_x = x - hs->hs_position; + else { + hs->hs_position = x - (hs->hs_knob_width / 2); + hs->hs_pressed_x = hs->hs_knob_width / 2; + if (hs->hs_position < hs->hs_min) + hs->hs_position = hs->hs_min; + if (hs->hs_position > hs->hs_max) + hs->hs_position = hs->hs_max; + if (hs->hs_frame_cb) + hs->hs_frame = hs->hs_frame_cb(hs->hs_position); + + } + + if (hs->hs_motion_cb) + hs->hs_motion_cb(hs->hs_position); + + widget_draw(WIDGET(hs)); + } +} + +void +hslider_motion_cb(GtkWidget * w, GdkEventMotion * event, gpointer data) +{ + HSlider *hs = (HSlider *) data; + gint x; + + if (hs->hs_pressed) { + if (!hs->hs_widget.visible) { + hs->hs_pressed = FALSE; + return; + } + + x = event->x - hs->hs_widget.x; + hs->hs_position = x - hs->hs_pressed_x; + + if (hs->hs_position < hs->hs_min) + hs->hs_position = hs->hs_min; + + if (hs->hs_position > hs->hs_max) + hs->hs_position = hs->hs_max; + + if (hs->hs_frame_cb) + hs->hs_frame = hs->hs_frame_cb(hs->hs_position); + + if (hs->hs_motion_cb) + hs->hs_motion_cb(hs->hs_position); + + widget_draw(WIDGET(hs)); + } +} + +void +hslider_button_release_cb(GtkWidget * w, + GdkEventButton * event, + gpointer data) +{ + HSlider *hs = HSLIDER(data); + + if (hs->hs_pressed) { + hs->hs_pressed = FALSE; + + if (hs->hs_release_cb) + hs->hs_release_cb(hs->hs_position); + + widget_draw(WIDGET(hs)); + } +} + +HSlider * +create_hslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint knx, gint kny, + gint kpx, gint kpy, gint kw, gint kh, gint fh, + gint fo, gint min, gint max, gint(*fcb) (gint), + void (*mcb) (gint), void (*rcb) (gint), SkinPixmapId si) +{ + HSlider *hs; + + hs = g_new0(HSlider, 1); + widget_init(&hs->hs_widget, parent, gc, x, y, w, h, 1); + hs->hs_widget.button_press_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + hslider_button_press_cb; + hs->hs_widget.button_release_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + hslider_button_release_cb; + hs->hs_widget.motion_cb = + (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) + hslider_motion_cb; + hs->hs_widget.draw = hslider_draw; + hs->hs_knob_nx = knx; + hs->hs_knob_ny = kny; + hs->hs_knob_px = kpx; + hs->hs_knob_py = kpy; + hs->hs_knob_width = kw; + hs->hs_knob_height = kh; + hs->hs_frame_height = fh; + hs->hs_frame_offset = fo; + hs->hs_min = min; + hs->hs_position = min; + hs->hs_max = max; + hs->hs_frame_cb = fcb; + hs->hs_motion_cb = mcb; + hs->hs_release_cb = rcb; + if (hs->hs_frame_cb) + hs->hs_frame = hs->hs_frame_cb(0); + hs->hs_skin_index = si; + + widget_list_add(wlist, WIDGET(hs)); + + return hs; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/hslider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/hslider.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,54 @@ +/* XMMS - Cross-platform multimedia player + * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef HSLIDER_H +#define HSLIDER_H + +#include +#include + +#include "skin.h" +#include "widget.h" + +#define HSLIDER(x) ((HSlider *)(x)) +struct _HSlider { + Widget hs_widget; + gint hs_frame, hs_frame_offset, hs_frame_height, hs_min, hs_max; + gint hs_knob_nx, hs_knob_ny, hs_knob_px, hs_knob_py; + gint hs_knob_width, hs_knob_height; + gint hs_position; + gboolean hs_pressed; + gint hs_pressed_x, hs_pressed_y; + gint(*hs_frame_cb) (gint); + void (*hs_motion_cb) (gint); + void (*hs_release_cb) (gint); + SkinPixmapId hs_skin_index; +}; + +typedef struct _HSlider HSlider; + +HSlider *create_hslider(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint knx, gint kny, + gint kpx, gint kpy, gint kw, gint kh, gint fh, + gint fo, gint min, gint max, gint(*fcb) (gint), + void (*mcb) (gint), void (*rcb) (gint), + SkinPixmapId si); + +void hslider_set_position(HSlider * hs, gint pos); +gint hslider_get_position(HSlider * hs); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/monostereo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/monostereo.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,93 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "monostereo.h" + +#include +#include + +#include "skin.h" +#include "widget.h" + +void +monostereo_draw(Widget * widget) +{ + MonoStereo *ms = (MonoStereo *) widget; + GdkPixmap *obj; + + obj = ms->ms_widget.parent; + + switch (ms->ms_num_channels) { + case 0: + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 29, 12, + ms->ms_widget.x, ms->ms_widget.y, 27, 12); + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 0, 12, + ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); + break; + case 1: + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 29, 0, + ms->ms_widget.x, ms->ms_widget.y, 27, 12); + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 0, 12, + ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); + break; + case 2: + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 29, 12, + ms->ms_widget.x, ms->ms_widget.y, 27, 12); + skin_draw_pixmap(bmp_active_skin, obj, ms->ms_widget.gc, + ms->ms_skin_index, 0, 0, + ms->ms_widget.x + 27, ms->ms_widget.y, 29, 12); + break; + } +} + +void +monostereo_set_num_channels(MonoStereo * ms, + gint nch) +{ + if (!ms) + return; + + ms->ms_num_channels = nch; + widget_draw(WIDGET(ms)); +} + +MonoStereo * +create_monostereo(GList ** wlist, + GdkPixmap * parent, + GdkGC * gc, + gint x, gint y, + SkinPixmapId si) +{ + MonoStereo *ms; + + ms = g_new0(MonoStereo, 1); + widget_init(&ms->ms_widget, parent, gc, x, y, 56, 12, 1); + ms->ms_widget.draw = monostereo_draw; + ms->ms_skin_index = si; + + widget_list_add(wlist, WIDGET(ms)); + return ms; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/monostereo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/monostereo.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,43 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef MONOSTEREO_H +#define MONOSTEREO_H + +#include +#include + +#include "skin.h" +#include "widget.h" + +#define MONO_STEREO(x) ((MonoStereo *)(x)) +struct _MonoStereo { + Widget ms_widget; + gint ms_num_channels; + SkinPixmapId ms_skin_index; +}; + +typedef struct _MonoStereo MonoStereo; + +MonoStereo *create_monostereo(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y, SkinPixmapId si); +void monostereo_set_num_channels(MonoStereo * ms, gint nch); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/number.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/number.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,75 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "number.h" + +#include +#include + +#include "skin.h" + +void +number_set_number(Number * nu, + gint number) +{ + if (number == nu->nu_number) + return; + + nu->nu_number = number; + widget_draw(WIDGET(nu)); +} + +void +number_draw(Widget * w) +{ + Number *nu = NUMBER(w); + GdkPixmap *obj; + + obj = nu->nu_widget.parent; + + if (nu->nu_number <= 11) + skin_draw_pixmap(bmp_active_skin, obj, nu->nu_widget.gc, + nu->nu_skin_index, nu->nu_number * 9, 0, + nu->nu_widget.x, nu->nu_widget.y, 9, 13); + else + skin_draw_pixmap(bmp_active_skin, obj, nu->nu_widget.gc, + nu->nu_skin_index, 90, 0, nu->nu_widget.x, + nu->nu_widget.y, 9, 13); +} + +Number * +create_number(GList ** wlist, + GdkPixmap * parent, + GdkGC * gc, + gint x, gint y, + SkinPixmapId si) +{ + Number *nu; + + nu = g_new0(Number, 1); + widget_init(&nu->nu_widget, parent, gc, x, y, 9, 13, 1); + nu->nu_widget.draw = number_draw; + nu->nu_number = 10; + nu->nu_skin_index = si; + + widget_list_add(wlist, WIDGET(nu)); + return nu; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/number.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/number.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,43 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef NUMBER_H +#define NUMBER_H + +#include +#include + +#include "widget.h" +#include "skin.h" + +#define NUMBER(x) ((Number *)(x)) +struct _Number { + Widget nu_widget; + gint nu_number; + SkinPixmapId nu_skin_index; +}; + +typedef struct _Number Number; + +void number_set_number(Number * nu, gint number); +Number *create_number(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, SkinPixmapId si); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/pbutton.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/pbutton.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,194 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pbutton.h" + +#include +#include +#include + +#include "skin.h" +#include "widget.h" + +void +pbutton_draw(PButton * button) +{ + GdkPixmap *obj; + + if (button->pb_allow_draw) { + obj = button->pb_widget.parent; + + if (button->pb_pressed && button->pb_inside) { + skin_draw_pixmap(bmp_active_skin, obj, + button->pb_widget.gc, + button->pb_skin_index2, button->pb_px, + button->pb_py, button->pb_widget.x, + button->pb_widget.y, + button->pb_widget.width, + button->pb_widget.height); + } + else { + skin_draw_pixmap(bmp_active_skin, obj, + button->pb_widget.gc, + button->pb_skin_index1, + button->pb_nx, button->pb_ny, + button->pb_widget.x, button->pb_widget.y, + button->pb_widget.width, + button->pb_widget.height); + } + } +} + +void +pbutton_button_press_cb(GtkWidget * widget, + GdkEventButton * event, + PButton * button) +{ + if (event->button != 1) + return; + + if (widget_contains(&button->pb_widget, event->x, event->y)) { + button->pb_pressed = 1; + button->pb_inside = 1; + widget_draw(WIDGET(button)); + if (button->pb_push_cb) + button->pb_push_cb(); + } +} + +void +pbutton_button_release_cb(GtkWidget * widget, + GdkEventButton * event, + PButton * button) +{ + if (event->button != 1) + return; + if (button->pb_inside && button->pb_pressed) { + button->pb_inside = 0; + widget_draw(WIDGET(button)); + if (button->pb_release_cb) + button->pb_release_cb(); + } + if (button->pb_pressed) + button->pb_pressed = 0; +} + +void +pbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, + PButton * button) +{ + gint inside; + + if (!button->pb_pressed) + return; + + inside = widget_contains(&button->pb_widget, event->x, event->y); + + if (inside != button->pb_inside) { + button->pb_inside = inside; + widget_draw(WIDGET(button)); + } +} + +void +pbutton_set_skin_index(PButton * b, SkinPixmapId si) +{ + b->pb_skin_index1 = b->pb_skin_index2 = si; +} + +void +pbutton_set_skin_index1(PButton * b, SkinPixmapId si) +{ + b->pb_skin_index1 = si; +} + +void +pbutton_set_skin_index2(PButton * b, SkinPixmapId si) +{ + b->pb_skin_index2 = si; +} + +void +pbutton_set_button_data(PButton * b, gint nx, gint ny, gint px, gint py) +{ + if (nx > -1) + b->pb_nx = nx; + if (ny > -1) + b->pb_ny = ny; + if (px > -1) + b->pb_px = px; + if (py > -1) + b->pb_py = py; +} + + +PButton * +create_pbutton_ex(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nx, + gint ny, gint px, gint py, void (*push_cb) (void), + void (*release_cb) (void), + SkinPixmapId si1, SkinPixmapId si2) +{ + PButton *b; + + b = g_new0(PButton, 1); + widget_init(&b->pb_widget, parent, gc, x, y, w, h, 1); + b->pb_widget.button_press_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + pbutton_button_press_cb; + b->pb_widget.button_release_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + pbutton_button_release_cb; + b->pb_widget.motion_cb = + (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) + pbutton_motion_cb; + + b->pb_widget.draw = (void (*)(Widget *)) pbutton_draw; + b->pb_nx = nx; + b->pb_ny = ny; + b->pb_px = px; + b->pb_py = py; + b->pb_push_cb = push_cb; + b->pb_release_cb = release_cb; + b->pb_skin_index1 = si1; + b->pb_skin_index2 = si2; + b->pb_allow_draw = TRUE; + b->pb_inside = 0; + b->pb_pressed = 0; + widget_list_add(wlist, WIDGET(b)); + + return b; +} + +PButton * +create_pbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nx, gint ny, + gint px, gint py, void (*cb) (void), SkinPixmapId si) +{ + return create_pbutton_ex(wlist, parent, gc, x, y, w, h, nx, ny, px, py, + NULL, cb, si, si); +} + +void +free_pbutton(PButton * b) +{ + g_free(b); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/pbutton.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/pbutton.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,59 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef PBUTTON_H +#define PBUTTON_H + +#include +#include + +#include "widget.h" +#include "skin.h" + +#define PBUTTON(x) ((PButton *)(x)) +struct _PButton { + Widget pb_widget; + gint pb_nx, pb_ny; + gint pb_px, pb_py; + gboolean pb_pressed; + gboolean pb_inside; + gboolean pb_allow_draw; + void (*pb_push_cb) (void); + void (*pb_release_cb) (void); + SkinPixmapId pb_skin_index1, pb_skin_index2; +}; + +typedef struct _PButton PButton; + +PButton *create_pbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nx, gint ny, + gint px, gint py, void (*push_cb) (void), SkinPixmapId si); +PButton *create_pbutton_ex(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nx, + gint ny, gint px, gint py, void (*push_cb) (void), + void (*release_cb) (void), SkinPixmapId si1, + SkinPixmapId si2); +void free_pbutton(PButton * b); +void pbutton_set_skin_index(PButton * b, SkinPixmapId si); +void pbutton_set_skin_index1(PButton * b, SkinPixmapId si); +void pbutton_set_skin_index2(PButton * b, SkinPixmapId si); +void pbutton_set_button_data(PButton * b, gint nx, gint ny, gint px, gint py); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playlist_list.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playlist_list.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,954 @@ +/* Audacious - Cross-platform multimedia player + * Copyright (C) 2005-2006 Audacious development team. + * + * BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * A note about Pango and some funky spacey fonts: Weirdly baselined + * fonts, or fonts with weird ascents or descents _will_ display a + * little bit weird in the playlist widget, but the display engine + * won't make it look too bad, just a little deranged. I honestly + * don't think it's worth fixing (around...), it doesn't have to be + * perfectly fitting, just the general look has to be ok, which it + * IMHO is. + * + * A second note: The numbers aren't perfectly aligned, but in the + * end it looks better when using a single Pango layout for each + * number. + */ + +#include "playlist_list.h" + +#include +#include + +#include "main.h" +#include "input.h" +#include "playback.h" +#include "playlist.h" +#include "ui_playlist.h" +#include "util.h" + +#include "debug.h" + +static PangoFontDescription *playlist_list_font = NULL; +static gint ascent, descent, width_delta_digit_one; +static gboolean has_slant; +static guint padding; + +/* FIXME: the following globals should not be needed. */ +static gint width_approx_letters; +static gint width_colon, width_colon_third; +static gint width_approx_digits, width_approx_digits_half; + +GdkPixmap *rootpix; + +void playlist_list_draw(Widget * w); + +/* Sort of stolen from XChat, but not really, as theres uses Xlib */ +static void +shade_gdkimage_generic (GdkVisual *visual, GdkImage *ximg, int bpl, int w, int h, int rm, int gm, int bm, int bg) +{ + int x, y; + int bgr = (256 - rm) * (bg & visual->red_mask); + int bgg = (256 - gm) * (bg & visual->green_mask); + int bgb = (256 - bm) * (bg & visual->blue_mask); + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + unsigned long pixel = gdk_image_get_pixel (ximg, x, y); + int r, g, b; + + r = rm * (pixel & visual->red_mask) + bgr; + g = gm * (pixel & visual->green_mask) + bgg; + b = bm * (pixel & visual->blue_mask) + bgb; + + gdk_image_put_pixel (ximg, x, y, + ((r >> 8) & visual->red_mask) | + ((g >> 8) & visual->green_mask) | + ((b >> 8) & visual->blue_mask)); + } + } +} + +/* and this is definately mine... -nenolod */ +GdkPixmap * +shade_pixmap(GdkPixmap *in, gint x, gint y, gint x_offset, gint y_offset, gint w, gint h, GdkColor *shade_color) +{ + GdkImage *ximg; + GdkPixmap *p = gdk_pixmap_new(in, w, h, -1); + GdkGC *gc = gdk_gc_new(p); + + gdk_draw_pixmap(p, gc, in, x, y, 0, 0, w, h); + + gdk_error_trap_push(); + + ximg = gdk_drawable_copy_to_image(in, NULL, x, y, 0, 0, w, h); /* copy */ + + gdk_error_trap_pop(); + + shade_gdkimage_generic(gdk_drawable_get_visual(GDK_WINDOW(playlistwin->window)), + ximg, ximg->bpl, w, h, 60, 60, 60, shade_color->pixel); + + gdk_draw_image(p, gc, ximg, 0, 0, x, y, w, h); + + g_object_unref(gc); + + return p; +} + +#ifdef GDK_WINDOWING_X11 + +#include +#include +#include + +GdkDrawable *get_transparency_pixmap(void) +{ + GdkDrawable *root; + XID *pixmaps; + GdkAtom prop_type; + gint prop_size; + GdkPixmap *pixmap; + gboolean ret; + + root = gdk_get_default_root_window(); + + pixmap = NULL; + pixmaps = NULL; + + gdk_error_trap_push(); + + ret = gdk_property_get(root, gdk_atom_intern("_XROOTPMAP_ID", TRUE), + 0, 0, INT_MAX - 3, + FALSE, + &prop_type, NULL, &prop_size, + (guchar **) &pixmaps); + + gdk_error_trap_pop(); + + if ((ret == TRUE) && (prop_type == GDK_TARGET_PIXMAP) && (prop_size >= sizeof(XID)) && (pixmaps != NULL)) + { + pixmap = gdk_pixmap_foreign_new_for_display(gdk_drawable_get_display(root), + pixmaps[0]); + + if (pixmaps != NULL) + g_free(pixmaps); + } + + return GDK_DRAWABLE(pixmap); +} + +static GdkFilterReturn +root_event_cb (GdkXEvent *xev, GdkEventProperty *event, gpointer data) +{ + static Atom at = None; + XEvent *xevent = (XEvent *)xev; + + if (xevent->type == PropertyNotify) + { + if (at == None) + at = XInternAtom (xevent->xproperty.display, "_XROOTPMAP_ID", True); + + if (at == xevent->xproperty.atom) + { + rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), + skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); + + if (cfg.playlist_transparent) + { + playlistwin_update_list(); + draw_playlist_window(TRUE); + } + } + } + + return GDK_FILTER_CONTINUE; +} + +#else + +GdkPixmap *get_transparency_pixmap(void) +{ + return NULL; +} + +#endif + +static gboolean +playlist_list_auto_drag_down_func(gpointer data) +{ + PlayList_List *pl = data; + + if (pl->pl_auto_drag_down) { + playlist_list_move_down(pl); + pl->pl_first++; + playlistwin_update_list(); + return TRUE; + } + return FALSE; +} + +static gboolean +playlist_list_auto_drag_up_func(gpointer data) +{ + PlayList_List *pl = data; + + if (pl->pl_auto_drag_up) { + playlist_list_move_up(pl); + pl->pl_first--; + playlistwin_update_list(); + return TRUE; + + } + return FALSE; +} + +void +playlist_list_move_up(PlayList_List * pl) +{ + GList *list; + + PLAYLIST_LOCK(); + if ((list = playlist_get()) == NULL) { + PLAYLIST_UNLOCK(); + return; + } + if (PLAYLIST_ENTRY(list->data)->selected) { + /* We are at the top */ + PLAYLIST_UNLOCK(); + return; + } + while (list) { + if (PLAYLIST_ENTRY(list->data)->selected) + glist_moveup(list); + list = g_list_next(list); + } + PLAYLIST_UNLOCK(); + if (pl->pl_prev_selected != -1) + pl->pl_prev_selected--; + if (pl->pl_prev_min != -1) + pl->pl_prev_min--; + if (pl->pl_prev_max != -1) + pl->pl_prev_max--; +} + +void +playlist_list_move_down(PlayList_List * pl) +{ + GList *list; + + PLAYLIST_LOCK(); + + if (!(list = g_list_last(playlist_get()))) { + PLAYLIST_UNLOCK(); + return; + } + + if (PLAYLIST_ENTRY(list->data)->selected) { + /* We are at the bottom */ + PLAYLIST_UNLOCK(); + return; + } + + while (list) { + if (PLAYLIST_ENTRY(list->data)->selected) + glist_movedown(list); + list = g_list_previous(list); + } + + PLAYLIST_UNLOCK(); + + if (pl->pl_prev_selected != -1) + pl->pl_prev_selected++; + if (pl->pl_prev_min != -1) + pl->pl_prev_min++; + if (pl->pl_prev_max != -1) + pl->pl_prev_max++; +} + +static void +playlist_list_button_press_cb(GtkWidget * widget, + GdkEventButton * event, + PlayList_List * pl) +{ + gint nr, y; + + if (event->button == 1 && pl->pl_fheight && + widget_contains(&pl->pl_widget, event->x, event->y)) { + + y = event->y - pl->pl_widget.y; + nr = (y / pl->pl_fheight) + pl->pl_first; + + if (nr >= playlist_get_length()) + nr = playlist_get_length() - 1; + + if (!(event->state & GDK_CONTROL_MASK)) + playlist_select_all(FALSE); + + if (event->state & GDK_SHIFT_MASK && pl->pl_prev_selected != -1) { + playlist_select_range(pl->pl_prev_selected, nr, TRUE); + pl->pl_prev_min = pl->pl_prev_selected; + pl->pl_prev_max = nr; + pl->pl_drag_pos = nr - pl->pl_first; + } + else { + if (playlist_select_invert(nr)) { + if (event->state & GDK_CONTROL_MASK) { + if (pl->pl_prev_min == -1) { + pl->pl_prev_min = pl->pl_prev_selected; + pl->pl_prev_max = pl->pl_prev_selected; + } + if (nr < pl->pl_prev_min) + pl->pl_prev_min = nr; + else if (nr > pl->pl_prev_max) + pl->pl_prev_max = nr; + } + else + pl->pl_prev_min = -1; + pl->pl_prev_selected = nr; + pl->pl_drag_pos = nr - pl->pl_first; + } + } + if (event->type == GDK_2BUTTON_PRESS) { + /* + * Ungrab the pointer to prevent us from + * hanging on to it during the sometimes slow + * bmp_playback_initiate(). + */ + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + playlist_set_position(nr); + if (!bmp_playback_get_playing()) + bmp_playback_initiate(); + } + + pl->pl_dragging = TRUE; + playlistwin_update_list(); + } +} + +gint +playlist_list_get_playlist_position(PlayList_List * pl, + gint x, + gint y) +{ + gint iy, length; + + if (!widget_contains(WIDGET(pl), x, y) || !pl->pl_fheight) + return -1; + + if ((length = playlist_get_length()) == 0) + return -1; + iy = y - pl->pl_widget.y; + + return (MIN((iy / pl->pl_fheight) + pl->pl_first, length - 1)); +} + +static void +playlist_list_motion_cb(GtkWidget * widget, + GdkEventMotion * event, + PlayList_List * pl) +{ + gint nr, y, off, i; + + if (pl->pl_dragging) { + y = event->y - pl->pl_widget.y; + nr = (y / pl->pl_fheight); + if (nr < 0) { + nr = 0; + if (!pl->pl_auto_drag_up) { + pl->pl_auto_drag_up = TRUE; + pl->pl_auto_drag_up_tag = + gtk_timeout_add(100, playlist_list_auto_drag_up_func, pl); + } + } + else if (pl->pl_auto_drag_up) + pl->pl_auto_drag_up = FALSE; + + if (nr >= pl->pl_num_visible) { + nr = pl->pl_num_visible - 1; + if (!pl->pl_auto_drag_down) { + pl->pl_auto_drag_down = TRUE; + pl->pl_auto_drag_down_tag = + gtk_timeout_add(100, playlist_list_auto_drag_down_func, + pl); + } + } + else if (pl->pl_auto_drag_down) + pl->pl_auto_drag_down = FALSE; + + off = nr - pl->pl_drag_pos; + if (off) { + for (i = 0; i < abs(off); i++) { + if (off < 0) + playlist_list_move_up(pl); + else + playlist_list_move_down(pl); + + } + playlistwin_update_list(); + } + pl->pl_drag_pos = nr; + } +} + +static void +playlist_list_button_release_cb(GtkWidget * widget, + GdkEventButton * event, + PlayList_List * pl) +{ + pl->pl_dragging = FALSE; + pl->pl_auto_drag_down = FALSE; + pl->pl_auto_drag_up = FALSE; +} + +static void +playlist_list_draw_string(PlayList_List * pl, + PangoFontDescription * font, + gint line, + gint width, + const gchar * text, + guint ppos) +{ + guint plist_length_int; + + PangoLayout *layout; + + REQUIRE_STATIC_LOCK(playlist); + + if (cfg.show_numbers_in_pl) { + gchar *pos_string = g_strdup_printf(cfg.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos); + plist_length_int = + gint_count_digits(playlist_get_length_nolock()) + !cfg.show_separator_in_pl + 1; /* cf.show_separator_in_pl will be 0 if false */ + + padding = plist_length_int; + padding = ((padding + 1) * width_approx_digits); + + layout = gtk_widget_create_pango_layout(playlistwin, pos_string); + pango_layout_set_font_description(layout, playlist_list_font); + pango_layout_set_width(layout, plist_length_int * 100); + + pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); + gdk_draw_layout(pl->pl_widget.parent, pl->pl_widget.gc, + pl->pl_widget.x + + (width_approx_digits * + (-1 + plist_length_int - strlen(pos_string))) + + (width_approx_digits / 4), + pl->pl_widget.y + (line - 1) * pl->pl_fheight + + ascent + abs(descent), layout); + g_free(pos_string); + g_object_unref(layout); + + if (!cfg.show_separator_in_pl) + padding -= (width_approx_digits * 1.5); + } + else { + padding = 3; + } + + width -= padding; + + layout = gtk_widget_create_pango_layout(playlistwin, text); + + pango_layout_set_font_description(layout, playlist_list_font); + pango_layout_set_width(layout, width * PANGO_SCALE); + pango_layout_set_single_paragraph_mode(layout, TRUE); + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); + gdk_draw_layout(pl->pl_widget.parent, pl->pl_widget.gc, + pl->pl_widget.x + padding + (width_approx_letters / 4), + pl->pl_widget.y + (line - 1) * pl->pl_fheight + + ascent + abs(descent), layout); + + g_object_unref(layout); +} + +void +playlist_list_draw(Widget * w) +{ + PlayList_List *pl = PLAYLIST_LIST(w); + GList *list; + GdkGC *gc; + GdkPixmap *obj; + PangoLayout *layout; + gchar *title; + gint width, height; + gint i, max_first; + guint padding, padding_dwidth, padding_plength; + guint max_time_len = 0; + gfloat queue_tailpadding = 0; + gint tpadding; + gsize tpadding_dwidth = 0; + gint x, y; + guint tail_width; + guint tail_len; + + gchar tail[100]; + gchar queuepos[255]; + gchar length[40]; + + gchar **frags; + gchar *frag0; + + gint plw_w, plw_h; + + GdkRectangle *playlist_rect; + + gc = pl->pl_widget.gc; + + width = pl->pl_widget.width; + height = pl->pl_widget.height; + + obj = pl->pl_widget.parent; + + gtk_window_get_size(GTK_WINDOW(playlistwin), &plw_w, &plw_h); + + playlist_rect = g_new0(GdkRectangle, 1); + + playlist_rect->x = 0; + playlist_rect->y = 0; + playlist_rect->width = plw_w - 17; + playlist_rect->height = plw_h - 36; + + gdk_gc_set_clip_origin(gc, 31, 58); + gdk_gc_set_clip_rectangle(gc, playlist_rect); + + if (cfg.playlist_transparent == FALSE) + { + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_NORMALBG)); + gdk_draw_rectangle(obj, gc, TRUE, pl->pl_widget.x, pl->pl_widget.y, + width, height); + } + else + { + if (!rootpix) + rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), + skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); + gdk_draw_pixmap(obj, gc, rootpix, cfg.playlist_x + pl->pl_widget.x, + cfg.playlist_y + pl->pl_widget.y, pl->pl_widget.x, pl->pl_widget.y, + width, height); + } + + if (!playlist_list_font) { + g_critical("Couldn't open playlist font"); + return; + } + + pl->pl_fheight = (ascent + abs(descent)); + pl->pl_num_visible = height / pl->pl_fheight; + + max_first = playlist_get_length() - pl->pl_num_visible; + max_first = MAX(max_first, 0); + + pl->pl_first = CLAMP(pl->pl_first, 0, max_first); + + PLAYLIST_LOCK(); + list = playlist_get(); + list = g_list_nth(list, pl->pl_first); + + /* It sucks having to run the iteration twice but this is the only + way you can reliably get the maximum width so we can get our + playlist nice and aligned... -- plasmaroo */ + + for (i = pl->pl_first; + list && i < pl->pl_first + pl->pl_num_visible; + list = g_list_next(list), i++) { + PlaylistEntry *entry = list->data; + + if (entry->length != -1) + { + g_snprintf(length, sizeof(length), "%d:%-2.2d", + entry->length / 60000, (entry->length / 1000) % 60); + tpadding_dwidth = MAX(tpadding_dwidth, strlen(length)); + } + } + + /* Reset */ + list = playlist_get(); + list = g_list_nth(list, pl->pl_first); + + for (i = pl->pl_first; + list && i < pl->pl_first + pl->pl_num_visible; + list = g_list_next(list), i++) { + gint pos; + PlaylistEntry *entry = list->data; + + if (entry->selected) { + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_SELECTEDBG)); + gdk_draw_rectangle(obj, gc, TRUE, pl->pl_widget.x, + pl->pl_widget.y + + ((i - pl->pl_first) * pl->pl_fheight), + width, pl->pl_fheight); + } + + /* FIXME: entry->title should NEVER be NULL, and there should + NEVER be a need to do a UTF-8 conversion. Playlist title + strings should be kept properly. */ + + if (!entry->title) { + gchar *basename = g_path_get_basename(entry->filename); + title = filename_to_utf8(basename); + g_free(basename); + } + else + title = str_to_utf8(entry->title); + + pos = playlist_get_queue_position(entry); + + tail[0] = 0; + queuepos[0] = 0; + length[0] = 0; + + if (pos != -1) + g_snprintf(queuepos, sizeof(queuepos), "%d", pos + 1); + + if (entry->length != -1) + { + g_snprintf(length, sizeof(length), "%d:%-2.2d", + entry->length / 60000, (entry->length / 1000) % 60); + } + + strncat(tail, length, sizeof(tail)); + tail_len = strlen(tail); + + max_time_len = MAX(max_time_len, tail_len); + + if (pos != -1 && tpadding_dwidth <= 0) + tail_width = width - (width_approx_digits * (strlen(queuepos) + 2.25)); + else if (pos != -1) + tail_width = width - (width_approx_digits * (tpadding_dwidth + strlen(queuepos) + 4)); + else if (tpadding_dwidth > 0) + tail_width = width - (width_approx_digits * (tpadding_dwidth + 2.5)); + else + tail_width = width; + + if (i == playlist_get_position_nolock()) + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_CURRENT)); + else + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_NORMAL)); + playlist_list_draw_string(pl, playlist_list_font, + i - pl->pl_first, tail_width, title, + i + 1); + + x = pl->pl_widget.x + width - width_approx_digits * 2; + y = pl->pl_widget.y + ((i - pl->pl_first) - + 1) * pl->pl_fheight + ascent; + + frags = NULL; + frag0 = NULL; + + if ((strlen(tail) > 0) && (tail != NULL)) { + frags = g_strsplit(tail, ":", 0); + frag0 = g_strconcat(frags[0], ":", NULL); + + layout = gtk_widget_create_pango_layout(playlistwin, frags[1]); + pango_layout_set_font_description(layout, playlist_list_font); + pango_layout_set_width(layout, tail_len * 100); + pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); + gdk_draw_layout(obj, gc, x - (0.5 * width_approx_digits), + y + abs(descent), layout); + g_object_unref(layout); + + layout = gtk_widget_create_pango_layout(playlistwin, frag0); + pango_layout_set_font_description(layout, playlist_list_font); + pango_layout_set_width(layout, tail_len * 100); + pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); + gdk_draw_layout(obj, gc, x - (0.75 * width_approx_digits), + y + abs(descent), layout); + g_object_unref(layout); + + g_free(frag0); + g_strfreev(frags); + } + + if (pos != -1) { + + /* DON'T remove the commented code yet please -- Milosz */ + + if (tpadding_dwidth > 0) + queue_tailpadding = tpadding_dwidth + 1; + else + queue_tailpadding = -0.75; + + gdk_draw_rectangle(obj, gc, FALSE, + x - + (((queue_tailpadding + + strlen(queuepos)) * + width_approx_digits) + + (width_approx_digits / 4)), + y + abs(descent), + (strlen(queuepos)) * + width_approx_digits + + (width_approx_digits / 2), + pl->pl_fheight - 2); + + layout = + gtk_widget_create_pango_layout(playlistwin, queuepos); + pango_layout_set_font_description(layout, playlist_list_font); + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + + gdk_draw_layout(obj, gc, + x - + ((queue_tailpadding + + strlen(queuepos)) * width_approx_digits) + + (width_approx_digits / 4), + y + abs(descent), layout); + g_object_unref(layout); + } + + g_free(title); + } + + + /* + * Drop target hovering over the playlist, so draw some hint where the + * drop will occur. + * + * This is (currently? unfixably?) broken when dragging files from Qt/KDE apps, + * probably due to DnD signaling problems (actually i have no clue). + * + */ + + if (pl->pl_drag_motion) { + guint pos, plength, lpadding; + gint x, y, plx, ply; + + if (cfg.show_numbers_in_pl) { + lpadding = gint_count_digits(playlist_get_length_nolock()) + 1; + lpadding = ((lpadding + 1) * width_approx_digits); + } + else { + lpadding = 3; + }; + + /* We already hold the mutex and have the playlist locked, so call + the non-locking function. */ + plength = playlist_get_length_nolock(); + + x = pl->drag_motion_x; + y = pl->drag_motion_y; + + plx = pl->pl_widget.x; + ply = pl->pl_widget.y; + + if ((x > pl->pl_widget.x) && !(x > pl->pl_widget.width)) { + + if ((y > pl->pl_widget.y) + && !(y > (pl->pl_widget.height + ply))) { + + pos = ((y - ((Widget *) pl)->y) / pl->pl_fheight) + + pl->pl_first; + + if (pos > (plength)) { + pos = plength; + } + + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_CURRENT)); + + gdk_draw_line(obj, gc, pl->pl_widget.x, + pl->pl_widget.y + ((pos - pl->pl_first) * pl->pl_fheight), + pl->pl_widget.width + pl->pl_widget.x - 1, + pl->pl_widget.y + + ((pos - pl->pl_first) * pl->pl_fheight)); + } + + } + + /* When dropping on the borders of the playlist, outside the text area, + * files get appended at the end of the list. Show that too. + */ + + if ((y < ply) || (y > pl->pl_widget.height + ply)) { + if ((y >= 0) || (y <= (pl->pl_widget.height + ply))) { + pos = plength; + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_CURRENT)); + + gdk_draw_line(obj, gc, pl->pl_widget.x, + pl->pl_widget.y + + ((pos - pl->pl_first) * pl->pl_fheight), + pl->pl_widget.width + pl->pl_widget.x - 1, + pl->pl_widget.y + + ((pos - pl->pl_first) * pl->pl_fheight)); + + } + } + } + + gdk_gc_set_foreground(gc, + skin_get_color(bmp_active_skin, + SKIN_PLEDIT_NORMAL)); + + if (cfg.show_numbers_in_pl) { + + padding_plength = playlist_get_length_nolock(); + + if (padding_plength == 0) { + padding_dwidth = 0; + } + else { + padding_dwidth = gint_count_digits(playlist_get_length_nolock()); + } + + padding = + (padding_dwidth * + width_approx_digits) + width_approx_digits; + + + /* For italic or oblique fonts we add another half of the + * approximate width */ + if (has_slant) + padding += width_approx_digits_half; + + if (cfg.show_separator_in_pl) { + gdk_draw_line(obj, gc, + pl->pl_widget.x + padding, + pl->pl_widget.y, + pl->pl_widget.x + padding, + pl->pl_widget.y + pl->pl_widget.height - 1); + } + } + + if (tpadding_dwidth != 0) + { + tpadding = (tpadding_dwidth * width_approx_digits) + (width_approx_digits * 1.5); + + if (has_slant) + tpadding += width_approx_digits_half; + + if (cfg.show_separator_in_pl) { + gdk_draw_line(obj, gc, + pl->pl_widget.x + pl->pl_widget.width - tpadding, + pl->pl_widget.y, + pl->pl_widget.x + pl->pl_widget.width - tpadding, + pl->pl_widget.y + pl->pl_widget.height - 1); + } + } + + gdk_gc_set_clip_origin(gc, 0, 0); + gdk_gc_set_clip_rectangle(gc, NULL); + + PLAYLIST_UNLOCK(); + + gdk_flush(); + + g_free(playlist_rect); +} + + +PlayList_List * +create_playlist_list(GList ** wlist, + GdkPixmap * parent, + GdkGC * gc, + gint x, gint y, + gint w, gint h) +{ + PlayList_List *pl; + + pl = g_new0(PlayList_List, 1); + widget_init(&pl->pl_widget, parent, gc, x, y, w, h, TRUE); + + pl->pl_widget.button_press_cb = + (WidgetButtonPressFunc) playlist_list_button_press_cb; + pl->pl_widget.button_release_cb = + (WidgetButtonReleaseFunc) playlist_list_button_release_cb; + pl->pl_widget.motion_cb = (WidgetMotionFunc) playlist_list_motion_cb; + pl->pl_widget.draw = playlist_list_draw; + + pl->pl_prev_selected = -1; + pl->pl_prev_min = -1; + pl->pl_prev_max = -1; + + widget_list_add(wlist, WIDGET(pl)); + +#ifdef GDK_WINDOWING_X11 + gdk_window_set_events (gdk_get_default_root_window(), GDK_PROPERTY_CHANGE_MASK); + gdk_window_add_filter (gdk_get_default_root_window(), (GdkFilterFunc)root_event_cb, pl); +#endif + + return pl; +} + +void +playlist_list_set_font(const gchar * font) +{ + + /* Welcome to bad hack central 2k3 */ + + gchar *font_lower; + gint width_temp; + gint width_temp_0; + + playlist_list_font = pango_font_description_from_string(font); + + text_get_extents(font, + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ", + &width_approx_letters, NULL, &ascent, &descent); + + width_approx_letters = (width_approx_letters / 53); + + /* Experimental: We don't weigh the 1 into total because it's width is almost always + * very different from the rest + */ + text_get_extents(font, "023456789", &width_approx_digits, NULL, NULL, + NULL); + width_approx_digits = (width_approx_digits / 9); + + /* Precache some often used calculations */ + width_approx_digits_half = width_approx_digits / 2; + + /* FIXME: We assume that any other number is broader than the "1" */ + text_get_extents(font, "1", &width_temp, NULL, NULL, NULL); + text_get_extents(font, "2", &width_temp_0, NULL, NULL, NULL); + + if (abs(width_temp_0 - width_temp) < 2) { + width_delta_digit_one = 0; + } + else { + width_delta_digit_one = ((width_temp_0 - width_temp) / 2) + 2; + } + + text_get_extents(font, ":", &width_colon, NULL, NULL, NULL); + width_colon_third = width_colon / 4; + + font_lower = g_utf8_strdown(font, strlen(font)); + /* This doesn't take any i18n into account, but i think there is none with TTF fonts + * FIXME: This can probably be retrieved trough Pango too + */ + has_slant = g_strstr_len(font_lower, strlen(font_lower), "oblique") + || g_strstr_len(font_lower, strlen(font_lower), "italic"); + + g_free(font_lower); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playlist_list.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playlist_list.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,56 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLAYLIST_LIST_H +#define PLAYLIST_LIST_H + +#include +#include +#include + +#include "widget.h" + +#define PLAYLIST_LIST(x) ((PlayList_List *)(x)) +struct _PlayList_List { + Widget pl_widget; + gint pl_first, pl_fheight, pl_prev_selected, pl_prev_min, pl_prev_max; + gint pl_num_visible, pl_drag_pos; + gboolean pl_dragging, pl_auto_drag_down, pl_auto_drag_up; + gint pl_auto_drag_up_tag, pl_auto_drag_down_tag; + gboolean pl_drag_motion; + gint drag_motion_x, drag_motion_y; + gboolean pl_tooltips; +}; + +typedef struct _PlayList_List PlayList_List; + +PlayList_List *create_playlist_list(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y, gint w, + gint h); +void playlist_list_move_up(PlayList_List * pl); +void playlist_list_move_down(PlayList_List * pl); +int playlist_list_get_playlist_position(PlayList_List * pl, gint x, gint y); +void playlist_list_set_font(const gchar * font); +GdkPixmap *rootpix; +GdkPixmap *shade_pixmap(GdkDrawable *in, gint x, gint y, gint x_offset, gint y_offset, gint w, gint h, GdkColor *shade_color); +GdkDrawable *get_transparency_pixmap(void); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playlist_slider.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playlist_slider.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,168 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "playlist_slider.h" + +#include + +#include "playlist.h" +#include "ui_playlist.h" +#include "skin.h" +#include "widget.h" + +void +playlistslider_draw(Widget * w) +{ + PlaylistSlider *ps = (PlaylistSlider *) w; + GdkPixmap *obj; + gint y, skinx; + + g_return_if_fail(ps != NULL); + g_return_if_fail(ps->ps_list != NULL); + + if (playlist_get_length() > ps->ps_list->pl_num_visible) + y = (ps->ps_list->pl_first * (ps->ps_widget.height - 19)) / + (playlist_get_length() - ps->ps_list->pl_num_visible); + else + y = 0; + + obj = ps->ps_widget.parent; + + if (ps->ps_back_image) { + if (skin_get_id() != ps->ps_skin_id) + ps->ps_skin_id = skin_get_id(); + else if (ps->ps_widget.height == ps->ps_prev_height) + gdk_draw_image(obj, ps->ps_widget.gc, + ps->ps_back_image, 0, 0, + ps->ps_widget.x, + ps->ps_widget.y + ps->ps_prev_y, 8, 18); + gdk_image_destroy(ps->ps_back_image); + } + + ps->ps_prev_y = y; + ps->ps_prev_height = ps->ps_widget.height; + ps->ps_back_image = gdk_drawable_get_image(obj, ps->ps_widget.x, + ps->ps_widget.y + y, 8, 18); + if (ps->ps_is_draging) + skinx = 61; + else + skinx = 52; + + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, SKIN_PLEDIT, + skinx, 53, ps->ps_widget.x, ps->ps_widget.y + y, 8, 18); +} + +static void +playlistslider_set_pos(PlaylistSlider * ps, gint y) +{ + gint pos; + + y = CLAMP(y, 0, ps->ps_widget.height - 19); + + pos = (y * (playlist_get_length() - ps->ps_list->pl_num_visible)) / + (ps->ps_widget.height - 19); + playlistwin_set_toprow(pos); +} + + +void +playlistslider_button_press_cb(GtkWidget * widget, + GdkEventButton * event, PlaylistSlider * ps) +{ + gint y = event->y - ps->ps_widget.y; + + if (!widget_contains(&ps->ps_widget, event->x, event->y)) + return; + + if (event->button != 1 && event->button != 2) + return; + + if ((y >= ps->ps_prev_y && y < ps->ps_prev_y + 18)) { + ps->ps_is_draging |= event->button; + ps->ps_drag_y = y - ps->ps_prev_y; + widget_draw(WIDGET(ps)); + } + else if (event->button == 2) { + playlistslider_set_pos(ps, y); + ps->ps_is_draging |= event->button; + ps->ps_drag_y = 0; + widget_draw(WIDGET(ps)); + } + else { + gint n = ps->ps_list->pl_num_visible / 2; + if (y < ps->ps_prev_y) + n *= -1; + playlistwin_scroll(n); + } +} + +void +playlistslider_button_release_cb(GtkWidget * widget, + GdkEventButton * event, + PlaylistSlider * ps) +{ + if (ps->ps_is_draging) { + ps->ps_is_draging &= ~event->button; + widget_draw(WIDGET(ps)); + } +} + +void +playlistslider_motion_cb(GtkWidget * widget, GdkEventMotion * event, + PlaylistSlider * ps) +{ + gint y; + + if (!ps->ps_is_draging) + return; + + y = event->y - ps->ps_widget.y - ps->ps_drag_y; + playlistslider_set_pos(ps, y); +} + +PlaylistSlider * +create_playlistslider(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y, gint h, + PlayList_List * list) +{ + PlaylistSlider *ps; + + ps = g_new0(PlaylistSlider, 1); + widget_init(&ps->ps_widget, parent, gc, x, y, 8, h, 1); + + ps->ps_widget.button_press_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + playlistslider_button_press_cb; + + ps->ps_widget.button_release_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + playlistslider_button_release_cb; + + ps->ps_widget.motion_cb = + (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) + playlistslider_motion_cb; + + ps->ps_widget.draw = playlistslider_draw; + ps->ps_list = list; + + widget_list_add(wlist, WIDGET(ps)); + return ps; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playlist_slider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playlist_slider.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,47 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLAYLIST_SLIDER_H +#define PLAYLIST_SLIDER_H + +#include +#include + +#include "playlist_list.h" +#include "widget.h" + +#define PLAYLIST_SLIDER(x) ((PlayerlistSlider *)(x)) +struct _PlaylistSlider { + Widget ps_widget; + PlayList_List *ps_list; + gboolean ps_is_draging; + gint ps_drag_y, ps_prev_y, ps_prev_height; + GdkImage *ps_back_image; + gint ps_skin_id; +}; + +typedef struct _PlaylistSlider PlaylistSlider; + +PlaylistSlider *create_playlistslider(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y, gint h, + PlayList_List * list); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playstatus.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playstatus.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,102 @@ +/* XMMS - Cross-platform multimedia player + * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "playstatus.h" + +#include +#include + +#include "skin.h" +#include "widget.h" + +void +playstatus_draw(Widget * w) +{ + PlayStatus *ps = PLAY_STATUS(w); + GdkPixmap *obj; + + if (!w) + return; + + obj = ps->ps_widget.parent; + if (ps->ps_status == STATUS_STOP && ps->ps_status_buffering == TRUE) + ps->ps_status_buffering = FALSE; + if (ps->ps_status == STATUS_PLAY && ps->ps_status_buffering == TRUE) + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 39, 0, ps->ps_widget.x, + ps->ps_widget.y, 3, 9); + else if (ps->ps_status == STATUS_PLAY) + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 36, 0, ps->ps_widget.x, + ps->ps_widget.y, 3, 9); + else + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 27, 0, ps->ps_widget.x, + ps->ps_widget.y, 2, 9); + switch (ps->ps_status) { + case STATUS_STOP: + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 18, 0, + ps->ps_widget.x + 2, ps->ps_widget.y, 9, 9); + break; + case STATUS_PAUSE: + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 9, 0, + ps->ps_widget.x + 2, ps->ps_widget.y, 9, 9); + break; + case STATUS_PLAY: + skin_draw_pixmap(bmp_active_skin, obj, ps->ps_widget.gc, + SKIN_PLAYPAUSE, 1, 0, + ps->ps_widget.x + 3, ps->ps_widget.y, 8, 9); + break; + } +} + +void +playstatus_set_status(PlayStatus * ps, PStatus status) +{ + if (!ps) + return; + + ps->ps_status = status; + widget_draw(WIDGET(ps)); +} + +void +playstatus_set_status_buffering(PlayStatus * ps, gboolean status) +{ + if (!ps) + return; + + ps->ps_status_buffering = status; + widget_draw(WIDGET(ps)); +} + +PlayStatus * +create_playstatus(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y) +{ + PlayStatus *ps; + + ps = g_new0(PlayStatus, 1); + widget_init(&ps->ps_widget, parent, gc, x, y, 11, 9, TRUE); + ps->ps_widget.draw = playstatus_draw; + + widget_list_add(wlist, WIDGET(ps)); + return ps; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/playstatus.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/playstatus.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,41 @@ +/* XMMS - Cross-platform multimedia player + * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef PLAYSTATUS_H +#define PLAYSTATUS_H + +#include "widget.h" + +typedef enum { + STATUS_STOP, STATUS_PAUSE, STATUS_PLAY +} PStatus; + +#define PLAY_STATUS(x) ((PlayStatus *)(x)) +struct _PlayStatus { + Widget ps_widget; + PStatus ps_status; + gboolean ps_status_buffering; +}; + +typedef struct _PlayStatus PlayStatus; + +void playstatus_set_status(PlayStatus * ps, PStatus status); +void playstatus_set_status_buffering(PlayStatus * ps, gboolean status); +PlayStatus *create_playstatus(GList ** wlist, GdkPixmap * parent, + GdkGC * gc, gint x, gint y); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/sbutton.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/sbutton.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,99 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sbutton.h" + +#include +#include +#include + +void +sbutton_button_press_cb(GtkWidget * widget, + GdkEventButton * event, + SButton * button) +{ + if (event->button != 1) + return; + + if (widget_contains(&button->sb_widget, event->x, event->y)) { + button->sb_pressed = 1; + button->sb_inside = 1; + } +} + +void +sbutton_button_release_cb(GtkWidget * widget, GdkEventButton * event, + SButton * button) +{ + if (event->button != 1) + return; + if (button->sb_inside && button->sb_pressed) { + button->sb_inside = 0; + if (button->sb_push_cb) + button->sb_push_cb(); + } + if (button->sb_pressed) + button->sb_pressed = 0; +} + +void +sbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, + SButton * button) +{ + int inside; + + if (!button->sb_pressed) + return; + + inside = widget_contains(&button->sb_widget, event->x, event->y); + + if (inside != button->sb_inside) + button->sb_inside = inside; +} + +SButton * +create_sbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, void (*cb) (void)) +{ + SButton *b; + + b = g_new0(SButton, 1); + widget_init(&b->sb_widget, parent, gc, x, y, w, h, 1); + b->sb_widget.button_press_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + sbutton_button_press_cb; + b->sb_widget.button_release_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + sbutton_button_release_cb; + b->sb_widget.motion_cb = + (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) + sbutton_motion_cb; + b->sb_push_cb = cb; + + widget_list_add(wlist, WIDGET(b)); + return b; +} + +void +free_sbutton(SButton * b) +{ + g_free(b); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/sbutton.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/sbutton.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,43 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SBUTTON_H +#define SBUTTON_H + +#include +#include + +#include "widget.h" + +#define SBUTTON(x) ((SButton *)(x)) +struct _SButton { + Widget sb_widget; + gint sb_pressed, sb_inside; + void (*sb_push_cb) (void); +}; + +typedef struct _SButton SButton; + +SButton *create_sbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, void (*cb) (void)); +void free_sbutton(SButton * b); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/skin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/skin.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,1260 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* TODO: enforce default sizes! */ + +#include +#include +#include +#include +#include + +#include "equalizer.h" +#include "main.h" +#include "ui_playlist.h" +#include "skin.h" +#include "skinwin.h" +#include "util.h" + +#include "debug.h" + +#include +#include + +#define EXTENSION_TARGETS 7 + +static gchar *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg", + "gif", "jpg", "jpeg" }; + +struct _SkinPixmapIdMapping { + SkinPixmapId id; + const gchar *name; + const gchar *alt_name; + gint width, height; +}; + +struct _SkinMaskInfo { + gint width, height; + gchar *inistr; +}; + +typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping; +typedef struct _SkinMaskInfo SkinMaskInfo; + + +Skin *bmp_active_skin = NULL; + +static gint skin_current_num; + +static SkinMaskInfo skin_mask_info[] = { + {275, 116, "Normal"}, + {275, 16, "WindowShade"}, + {275, 116, "Equalizer"}, + {275, 16, "EqualizerWS"} +}; + +static SkinPixmapIdMapping skin_pixmap_id_map[] = { + {SKIN_MAIN, "main", NULL, 0, 0}, + {SKIN_CBUTTONS, "cbuttons", NULL, 0, 0}, + {SKIN_SHUFREP, "shufrep", NULL, 0, 0}, + {SKIN_TEXT, "text", NULL, 0, 0}, + {SKIN_TITLEBAR, "titlebar", NULL, 0, 0}, + {SKIN_VOLUME, "volume", NULL, 0, 0}, + {SKIN_BALANCE, "balance", "volume", 0, 0}, + {SKIN_MONOSTEREO, "monoster", NULL, 0, 0}, + {SKIN_PLAYPAUSE, "playpaus", NULL, 0, 0}, + {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0}, + {SKIN_POSBAR, "posbar", NULL, 0, 0}, + {SKIN_EQMAIN, "eqmain", NULL, 0, 0}, + {SKIN_PLEDIT, "pledit", NULL, 0, 0}, + {SKIN_EQ_EX, "eq_ex", NULL, 0, 0} +}; + +static guint skin_pixmap_id_map_size = G_N_ELEMENTS(skin_pixmap_id_map); + +static const guchar skin_default_viscolor[24][3] = { + {9, 34, 53}, + {10, 18, 26}, + {0, 54, 108}, + {0, 58, 116}, + {0, 62, 124}, + {0, 66, 132}, + {0, 70, 140}, + {0, 74, 148}, + {0, 78, 156}, + {0, 82, 164}, + {0, 86, 172}, + {0, 92, 184}, + {0, 98, 196}, + {0, 104, 208}, + {0, 110, 220}, + {0, 116, 232}, + {0, 122, 244}, + {0, 128, 255}, + {0, 128, 255}, + {0, 104, 208}, + {0, 80, 160}, + {0, 56, 112}, + {0, 32, 64}, + {200, 200, 200} +}; + +static GdkBitmap * +skin_create_transparent_mask(const gchar *, + const gchar *, + const gchar *, + GdkWindow *, + gint, gint); + +static void +skin_setup_masks(Skin * skin); + +static void +skin_set_default_vis_color(Skin * skin); + + +void +skin_lock(Skin * skin) +{ + g_mutex_lock(skin->lock); +} + +void +skin_unlock(Skin * skin) +{ + g_mutex_unlock(skin->lock); +} + +gboolean +bmp_active_skin_reload(void) +{ + return bmp_active_skin_load(bmp_active_skin->path); +} + +gboolean +bmp_active_skin_load(const gchar * path) +{ + g_return_val_if_fail(bmp_active_skin != NULL, FALSE); + + memset(&bmp_active_skin->properties, 0, sizeof(SkinProperties)); + + if (!skin_load(bmp_active_skin, path)) + return FALSE; + + skin_setup_masks(bmp_active_skin); + + if (cfg.playlist_transparent) + { + if (rootpix != NULL) + g_object_unref(rootpix); + + rootpix = shade_pixmap(get_transparency_pixmap(), 0, 0, 0, 0, gdk_screen_width(), gdk_screen_height(), + skin_get_color(bmp_active_skin, SKIN_PLEDIT_NORMALBG)); + } + + draw_main_window(TRUE); + draw_playlist_window(TRUE); + draw_equalizer_window(TRUE); + + vis_set_window(mainwin_vis, mainwin->window); + playlistwin_update_list(); + + return TRUE; +} + +void +skin_pixmap_free(SkinPixmap * p) +{ + g_return_if_fail(p != NULL); + g_return_if_fail(p->pixmap != NULL); + + g_object_unref(p->pixmap); + p->pixmap = NULL; +} + +Skin * +skin_new(void) +{ + Skin *skin; + skin = g_new0(Skin, 1); + skin->lock = g_mutex_new(); + return skin; +} + +void +skin_free(Skin * skin) +{ + gint i; + + g_return_if_fail(skin != NULL); + + skin_lock(skin); + + for (i = 0; i < SKIN_PIXMAP_COUNT; i++) + skin_pixmap_free(&skin->pixmaps[i]); + + for (i = 0; i < SKIN_PIXMAP_COUNT; i++) { + if (skin->masks[i]) + g_object_unref(skin->masks[i]); + + skin->masks[i] = NULL; + } + + skin_set_default_vis_color(skin); + skin_unlock(skin); +} + +void +skin_destroy(Skin * skin) +{ + g_return_if_fail(skin != NULL); + skin_free(skin); + g_mutex_free(skin->lock); + g_free(skin); +} + +const SkinPixmapIdMapping * +skin_pixmap_id_lookup(guint id) +{ + guint i; + + for (i = 0; i < skin_pixmap_id_map_size; i++) { + if (id == skin_pixmap_id_map[i].id) { + return &skin_pixmap_id_map[i]; + } + } + + return NULL; +} + +const gchar * +skin_pixmap_id_to_name(SkinPixmapId id) +{ + guint i; + + for (i = 0; i < skin_pixmap_id_map_size; i++) { + if (id == skin_pixmap_id_map[i].id) + return skin_pixmap_id_map[i].name; + } + return NULL; +} + +static void +skin_set_default_vis_color(Skin * skin) +{ + memcpy(skin->vis_color, skin_default_viscolor, + sizeof(skin_default_viscolor)); +} + +/* + * I have rewritten this to take an array of possible targets, + * once we find a matching target we now return, instead of loop + * recursively. This allows for us to support many possible format + * targets for our skinning engine than just the original winamp + * formats. + * + * -- nenolod, 16 January 2006 + */ +gchar * +skin_pixmap_locate(const gchar * dirname, gchar ** basenames) +{ + gchar *filename; + gint i; + + for (i = 0; basenames[i]; i++) + if (!(filename = find_file_recursively(dirname, basenames[i]))) + g_free(filename); + else + return filename; + + /* can't find any targets -- sorry */ + return NULL; +} + +/* FIXME: this function is temporary. It will be removed when the skinning system + uses GdkPixbuf in place of GdkPixmap */ + +static GdkPixmap * +pixmap_new_from_file(const gchar * filename) +{ + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; + gint width, height; + + if (!(pixbuf = gdk_pixbuf_new_from_file(filename, NULL))) + return NULL; + + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + + if (!(pixmap = gdk_pixmap_new(mainwin->window, width, height, + gdk_rgb_get_visual()->depth))) { + g_object_unref(pixbuf); + return NULL; + } + + gdk_pixbuf_render_to_drawable(pixbuf, pixmap, mainwin_gc, 0, 0, 0, 0, + width, height, GDK_RGB_DITHER_MAX, 0, 0); + g_object_unref(pixbuf); + + return pixmap; +} + +static gboolean +skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const gchar * path_p) +{ + const gchar *path; + gchar *filename; + gint width, height; + const SkinPixmapIdMapping *pixmap_id_mapping; + GdkPixmap *gpm; + SkinPixmap *pm = NULL; + gchar *basenames[EXTENSION_TARGETS * 2 + 1]; /* alternate basenames */ + gint i, y; + + g_return_val_if_fail(skin != NULL, FALSE); + g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE); + + pixmap_id_mapping = skin_pixmap_id_lookup(id); + g_return_val_if_fail(pixmap_id_mapping != NULL, FALSE); + + memset(&basenames, 0, sizeof(basenames)); + + for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++) + { + basenames[y] = g_strdup_printf("%s.%s", pixmap_id_mapping->name, + ext_targets[i]); + + if (pixmap_id_mapping->alt_name) + basenames[++y] = g_strdup_printf("%s.%s", + pixmap_id_mapping->alt_name, ext_targets[i]); + } + + path = path_p ? path_p : skin->path; + filename = skin_pixmap_locate(path, basenames); + + for (i = 0; basenames[i] != NULL; i++) + { + g_free(basenames[i]); + basenames[i] = NULL; + } + + if (!(gpm = pixmap_new_from_file(filename))) { + g_warning("loading of %s failed", filename); + g_free(filename); + return FALSE; + } + + g_free(filename); + + gdk_window_get_size(gpm, &width, &height); + pm = &skin->pixmaps[id]; + pm->pixmap = gpm; + pm->width = width; + pm->height = height; + pm->current_width = width; + pm->current_height = height; + + return TRUE; +} + +void +skin_mask_create(Skin * skin, + const gchar * path, + gint id, + GdkWindow * window) +{ + skin->masks[id] = + skin_create_transparent_mask(path, "region.txt", + skin_mask_info[id].inistr, window, + skin_mask_info[id].width, + skin_mask_info[id].height); +} + +static void +skin_setup_masks(Skin * skin) +{ + GdkBitmap *mask; + + if (cfg.show_wm_decorations) + return; + + if (cfg.player_visible) { + mask = skin_get_mask(skin, SKIN_MASK_MAIN + cfg.player_shaded); + gtk_widget_shape_combine_mask(mainwin, mask, 0, 0); + } + + mask = skin_get_mask(skin, SKIN_MASK_EQ + cfg.equalizer_shaded); + gtk_widget_shape_combine_mask(equalizerwin, mask, 0, 0); +} + +static GdkBitmap * +create_default_mask(GdkWindow * parent, gint w, gint h) +{ + GdkBitmap *ret; + GdkGC *gc; + GdkColor pattern; + + ret = gdk_pixmap_new(parent, w, h, 1); + gc = gdk_gc_new(ret); + pattern.pixel = 1; + gdk_gc_set_foreground(gc, &pattern); + gdk_draw_rectangle(ret, gc, TRUE, 0, 0, w, h); + gdk_gc_destroy(gc); + + return ret; +} + +static void +skin_query_color(GdkColormap * cm, GdkColor * c) +{ + XColor xc = { 0,0,0,0,0,0 }; + + xc.pixel = c->pixel; + XQueryColor(GDK_COLORMAP_XDISPLAY(cm), GDK_COLORMAP_XCOLORMAP(cm), &xc); + c->red = xc.red; + c->green = xc.green; + c->blue = xc.blue; +} + +static glong +skin_calc_luminance(GdkColor * c) +{ + return (0.212671 * c->red + 0.715160 * c->green + 0.072169 * c->blue); +} + +static void +skin_get_textcolors(GdkPixmap * text, GdkColor * bgc, GdkColor * fgc) +{ + /* + * Try to extract reasonable background and foreground colors + * from the font pixmap + */ + + GdkImage *gi; + GdkColormap *cm; + gint i; + + g_return_if_fail(text != NULL); + + /* Get the first line of text */ + gi = gdk_drawable_get_image(text, 0, 0, 152, 6); + cm = gdk_window_get_colormap(playlistwin->window); + g_return_if_fail(GDK_IS_WINDOW(playlistwin->window)); + + for (i = 0; i < 6; i++) { + GdkColor c; + gint x; + glong d, max_d; + + /* Get a pixel from the middle of the space character */ + bgc[i].pixel = gdk_image_get_pixel(gi, 151, i); + skin_query_color(cm, &bgc[i]); + + max_d = 0; + for (x = 1; x < 150; x++) { + c.pixel = gdk_image_get_pixel(gi, x, i); + skin_query_color(cm, &c); + + d = labs(skin_calc_luminance(&c) - skin_calc_luminance(&bgc[i])); + if (d > max_d) { + memcpy(&fgc[i], &c, sizeof(GdkColor)); + max_d = d; + } + } + } + gdk_image_destroy(gi); +} + +gboolean +init_skins(const gchar * path) +{ + bmp_active_skin = skin_new(); + + if (!bmp_active_skin_load(path)) { + /* FIXME: Oddly, g_message() causes a crash if path is NULL on + * Solaris (see bug #165) */ + if (path) + g_message("Unable to load skin (%s), trying default...", path); + + /* can't load configured skin, retry with default */ + if (!bmp_active_skin_load(BMP_DEFAULT_SKIN_PATH)) { + g_message("Unable to load default skin (%s)! Giving up.", + BMP_DEFAULT_SKIN_PATH); + return FALSE; + } + } + + if (cfg.random_skin_on_play) + skinlist_update(); + + return TRUE; +} + +/* + * Opens and parses a skin's hints file. + * Hints files are somewhat like "scripts" in Winamp3/5. + * We'll probably add scripts to it next. + */ +void +skin_parse_hints(Skin * skin, gchar *path_p) +{ + gchar *filename, *tmp; + + path_p = path_p ? path_p : skin->path; + + filename = find_file_recursively(path_p, "skin.hints"); + + if (filename == NULL) + return; + +#if 0 + skin->description = read_ini_string(filename, "skin", "skinDescription"); +#endif + + tmp = read_ini_string(filename, "skin", "mainwinOthertext"); + + if (tmp != NULL) + skin->properties.mainwin_othertext = atoi(tmp); +} + +static guint +hex_chars_to_int(gchar hi, gchar lo) +{ + /* + * Converts a value in the range 0x00-0xFF + * to a integer in the range 0-65535 + */ + gchar str[3]; + + str[0] = hi; + str[1] = lo; + str[2] = 0; + + return (CLAMP(strtol(str, NULL, 16), 0, 0xFF) << 8); +} + +GdkColor * +skin_load_color(const gchar * path, const gchar * file, + const gchar * section, const gchar * key, + gchar * default_hex) +{ + gchar *filename, *value; + GdkColor *color = NULL; + + filename = find_file_recursively(path, file); + if (filename || default_hex) { + if (filename) { + value = read_ini_string(filename, section, key); + if (value == NULL) { + value = g_strdup(default_hex); + } + } else { + value = g_strdup(default_hex); + } + if (value) { + gchar *ptr = value; + gint len; + + color = g_new0(GdkColor, 1); + g_strstrip(value); + + if (value[0] == '#') + ptr++; + len = strlen(ptr); + /* + * The handling of incomplete values is done this way + * to maximize winamp compatibility + */ + if (len >= 6) { + color->red = hex_chars_to_int(*ptr, *(ptr + 1)); + ptr += 2; + } + if (len >= 4) { + color->green = hex_chars_to_int(*ptr, *(ptr + 1)); + ptr += 2; + } + if (len >= 2) + color->blue = hex_chars_to_int(*ptr, *(ptr + 1)); + + gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), + color); + g_free(value); + } + if (filename) + g_free(filename); + } + return color; +} + + + +GdkBitmap * +skin_create_transparent_mask(const gchar * path, + const gchar * file, + const gchar * section, + GdkWindow * window, + gint width, + gint height) +{ + GdkBitmap *mask = NULL; + GdkGC *gc = NULL; + GdkColor pattern; + GdkPoint *gpoints; + + gchar *filename = NULL; + gboolean created_mask = FALSE; + GArray *num, *point; + guint i, j; + gint k; + + if (path) + filename = find_file_recursively(path, file); + + /* filename will be null if path wasn't set */ + if (!filename) { + return create_default_mask(window, width, height); + } + + if ((num = read_ini_array(filename, section, "NumPoints")) == NULL) { + g_free(filename); + return NULL; + } + + if ((point = read_ini_array(filename, section, "PointList")) == NULL) { + g_array_free(num, TRUE); + g_free(filename); + return NULL; + } + + mask = gdk_pixmap_new(window, width, height, 1); + gc = gdk_gc_new(mask); + + pattern.pixel = 0; + gdk_gc_set_foreground(gc, &pattern); + gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); + pattern.pixel = 1; + gdk_gc_set_foreground(gc, &pattern); + + j = 0; + for (i = 0; i < num->len; i++) { + if ((int)(point->len - j) >= (g_array_index(num, gint, i) * 2)) { + created_mask = TRUE; + gpoints = g_new(GdkPoint, g_array_index(num, gint, i)); + for (k = 0; k < g_array_index(num, gint, i); k++) { + gpoints[k].x = g_array_index(point, gint, j + k * 2); + gpoints[k].y = g_array_index(point, gint, j + k * 2 + 1); + } + j += k * 2; + gdk_draw_polygon(mask, gc, TRUE, gpoints, + g_array_index(num, gint, i)); + g_free(gpoints); + } + } + g_array_free(num, TRUE); + g_array_free(point, TRUE); + g_free(filename); + + if (!created_mask) + gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); + + gdk_gc_destroy(gc); + + return mask; +} + +void +skin_load_viscolor(Skin * skin, const gchar * path, const gchar * basename) +{ + FILE *file; + gint i, c; + gchar line[256], *filename; + GArray *a; + + g_return_if_fail(skin != NULL); + g_return_if_fail(path != NULL); + g_return_if_fail(basename != NULL); + + skin_set_default_vis_color(skin); + + filename = find_file_recursively(path, basename); + if (!filename) + return; + + if (!(file = fopen(filename, "r"))) { + g_free(filename); + return; + } + + g_free(filename); + + for (i = 0; i < 24; i++) { + if (fgets(line, 255, file)) { + a = string_to_garray(line); + if (a->len > 2) { + for (c = 0; c < 3; c++) + skin->vis_color[i][c] = g_array_index(a, gint, c); + } + g_array_free(a, TRUE); + } + else + break; + } + + fclose(file); +} + +#if 0 +static void +skin_numbers_generate_dash(Skin * skin) +{ + GdkGC *gc; + GdkPixmap *pixmap; + SkinPixmap *numbers; + + g_return_if_fail(skin != NULL); + + numbers = &skin->pixmaps[SKIN_NUMBERS]; + if (!numbers->pixmap || numbers->current_width < 99) + return; + + gc = gdk_gc_new(numbers->pixmap); + pixmap = gdk_pixmap_new(mainwin->window, 108, + numbers->current_height, + -1); + + skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 0, 0, 0, 0, 99, 13); + skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 90, 0, 99, 0, 9, 13); + skin_draw_pixmap(skin, pixmap, gc, SKIN_NUMBERS, 20, 6, 101, 6, 5, 1); + + g_object_unref(numbers->pixmap); + g_object_unref(gc); + + numbers->pixmap = pixmap; + numbers->current_width = 108; +} +#endif + +static void +skin_load_cursor(Skin * skin, const gchar * dirname) +{ + const gchar * basename = "normal.cur"; + gchar * filename = NULL; + GdkPixbuf * cursor_pixbuf = NULL; + GdkPixbufAnimation * cursor_animated = NULL; + GdkCursor * cursor_gdk = NULL; + GError * error = NULL; + + filename = find_file_recursively(dirname, basename); + + if (filename && cfg.custom_cursors) { + cursor_animated = gdk_pixbuf_animation_new_from_file(filename, &error); + cursor_pixbuf = gdk_pixbuf_animation_get_static_image(cursor_animated); + cursor_gdk = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), + cursor_pixbuf, 0, 0); + } else { + cursor_gdk = gdk_cursor_new(GDK_LEFT_PTR); + } + + gdk_window_set_cursor(mainwin->window, cursor_gdk); + gdk_window_set_cursor(playlistwin->window, cursor_gdk); + gdk_window_set_cursor(equalizerwin->window, cursor_gdk); + gdk_cursor_unref(cursor_gdk); +} + +static void +skin_load_pixmaps(Skin * skin, const gchar * path) +{ + GdkPixmap *text_pm; + guint i; + + for (i = 0; i < SKIN_PIXMAP_COUNT; i++) + skin_load_pixmap_id(skin, i, path); + + text_pm = skin->pixmaps[SKIN_TEXT].pixmap; + + if (text_pm) + skin_get_textcolors(text_pm, skin->textbg, skin->textfg); + +#if 0 + if (skin->pixmaps[SKIN_NUMBERS].pixmap) + skin_numbers_generate_dash(skin); +#endif + + skin->colors[SKIN_PLEDIT_NORMAL] = + skin_load_color(path, "pledit.txt", "text", "normal", "#2499ff"); + skin->colors[SKIN_PLEDIT_CURRENT] = + skin_load_color(path, "pledit.txt", "text", "current", "#ffeeff"); + skin->colors[SKIN_PLEDIT_NORMALBG] = + skin_load_color(path, "pledit.txt", "text", "normalbg", "#0a120a"); + skin->colors[SKIN_PLEDIT_SELECTEDBG] = + skin_load_color(path, "pledit.txt", "text", "selectedbg", "#0a124a"); + + skin_mask_create(skin, path, SKIN_MASK_MAIN, mainwin->window); + skin_mask_create(skin, path, SKIN_MASK_MAIN_SHADE, mainwin->window); + + skin_mask_create(skin, path, SKIN_MASK_EQ, equalizerwin->window); + skin_mask_create(skin, path, SKIN_MASK_EQ_SHADE, equalizerwin->window); + + skin_load_viscolor(skin, path, "viscolor.txt"); +} + +static gboolean +skin_load_nolock(Skin * skin, const gchar * path, gboolean force) +{ + gchar *cpath; + + g_return_val_if_fail(skin != NULL, FALSE); + g_return_val_if_fail(path != NULL, FALSE); + REQUIRE_LOCK(skin->lock); + + if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR)) + return FALSE; + + if (!force) { + if (skin->path) + if (!strcmp(skin->path, path)) + return FALSE; + } + + skin_current_num++; + + skin->path = g_strdup(path); + + if (!file_is_archive(path)) { + skin_load_pixmaps(skin, path); + skin_load_cursor(skin, path); + + /* Parse the hints for this skin. */ + skin_parse_hints(skin, NULL); + + return TRUE; + } + + if (!(cpath = archive_decompress(path))) { + g_message("Unable to extract skin archive (%s)", path); + return FALSE; + } + + skin_load_pixmaps(skin, cpath); + skin_load_cursor(skin, cpath); + + /* Parse the hints for this skin. */ + skin_parse_hints(skin, cpath); + + del_directory(cpath); + g_free(cpath); + + return TRUE; +} + +void +skin_install_skin(const gchar * path) +{ + gchar *command; + + g_return_if_fail(path != NULL); + + command = g_strdup_printf("cp %s %s", path, bmp_paths[BMP_PATH_USER_SKIN_DIR]); + if (system(command)) { + g_message("Unable to install skin (%s) into user directory (%s)", + path, bmp_paths[BMP_PATH_USER_SKIN_DIR]); + } + g_free(command); +} + + +gboolean +skin_load(Skin * skin, const gchar * path) +{ + gboolean error; + + g_return_val_if_fail(skin != NULL, FALSE); + + if (!path) + return FALSE; + + skin_lock(skin); + error = skin_load_nolock(skin, path, FALSE); + skin_unlock(skin); + + return error; +} + +gboolean +skin_reload_forced(void) +{ + gboolean error; + + skin_lock(bmp_active_skin); + error = skin_load_nolock(bmp_active_skin, bmp_active_skin->path, TRUE); + skin_unlock(bmp_active_skin); + + return error; +} + +void +skin_reload(Skin * skin) +{ + g_return_if_fail(skin != NULL); + skin_load_nolock(skin, skin->path, TRUE); +} + + +static SkinPixmap * +skin_get_pixmap(Skin * skin, SkinPixmapId map_id) +{ + g_return_val_if_fail(skin != NULL, NULL); + g_return_val_if_fail(map_id < SKIN_PIXMAP_COUNT, NULL); + + return &skin->pixmaps[map_id]; +} + +GdkBitmap * +skin_get_mask(Skin * skin, SkinMaskId mi) +{ + g_return_val_if_fail(skin != NULL, NULL); + g_return_val_if_fail(mi < SKIN_PIXMAP_COUNT, NULL); + + return skin->masks[mi]; +} + +GdkColor * +skin_get_color(Skin * skin, SkinColorId color_id) +{ + GdkColor *ret = NULL; + + g_return_val_if_fail(skin != NULL, NULL); + + switch (color_id) { + case SKIN_TEXTBG: + if (skin->pixmaps[SKIN_TEXT].pixmap) + ret = skin->textbg; + else + ret = skin->def_textbg; + break; + case SKIN_TEXTFG: + if (skin->pixmaps[SKIN_TEXT].pixmap) + ret = skin->textfg; + else + ret = skin->def_textfg; + break; + default: + if (color_id < SKIN_COLOR_COUNT) + ret = skin->colors[color_id]; + break; + } + return ret; +} + +void +skin_get_viscolor(Skin * skin, guchar vis_color[24][3]) +{ + gint i; + + g_return_if_fail(skin != NULL); + + for (i = 0; i < 24; i++) { + vis_color[i][0] = skin->vis_color[i][0]; + vis_color[i][1] = skin->vis_color[i][1]; + vis_color[i][2] = skin->vis_color[i][2]; + } +} + +gint +skin_get_id(void) +{ + return skin_current_num; +} + +void +skin_draw_pixmap(Skin * skin, GdkDrawable * drawable, GdkGC * gc, + SkinPixmapId pixmap_id, + gint xsrc, gint ysrc, gint xdest, gint ydest, + gint width, gint height) +{ + SkinPixmap *pixmap; + + g_return_if_fail(skin != NULL); + + pixmap = skin_get_pixmap(skin, pixmap_id); + g_return_if_fail(pixmap != NULL); + g_return_if_fail(pixmap->pixmap != NULL); + + if (xsrc > pixmap->width || ysrc > pixmap->height) + return; + + width = MIN(width, pixmap->width - xsrc); + height = MIN(height, pixmap->height - ysrc); + gdk_draw_pixmap(drawable, gc, pixmap->pixmap, xsrc, ysrc, + xdest, ydest, width, height); +} + +void +skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]) +{ + gint i; + GdkPixmap *pixmap; + GdkImage *img; + SkinPixmap *eqmainpm; + + g_return_if_fail(skin != NULL); + + eqmainpm = &skin->pixmaps[SKIN_EQMAIN]; + if (eqmainpm->pixmap && + eqmainpm->current_width >= 116 && eqmainpm->current_height >= 313) + pixmap = eqmainpm->pixmap; + else + return; + + if (!GDK_IS_DRAWABLE(pixmap)) + return; + + if (!(img = gdk_drawable_get_image(pixmap, 115, 294, 1, 19))) + return; + + for (i = 0; i < 19; i++) + colors[i] = gdk_image_get_pixel(img, 0, i); + + gdk_image_destroy(img); +} + + +static void +skin_draw_playlistwin_frame_top(Skin * skin, + GdkDrawable * drawable, + GdkGC * gc, + gint width, gint height, gboolean focus) +{ + /* The title bar skin consists of 2 sets of 4 images, 1 set + * for focused state and the other for unfocused. The 4 images + * are: + * + * a. right corner (25,20) + * b. left corner (25,20) + * c. tiler (25,20) + * d. title (100,20) + * + * min allowed width = 100+25+25 = 150 + */ + + gint i, y, c; + + /* get y offset of the pixmap set to use */ + if (focus) + y = 0; + else + y = 21; + + /* left corner */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, y, 0, 0, 25, 20); + + /* titlebar title */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 26, y, + (width - 100) / 2, 0, 100, 20); + + /* titlebar right corner */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 153, y, + width - 25, 0, 25, 20); + + /* tile draw the remaining frame */ + + /* compute tile count */ + c = (width - (100 + 25 + 25)) / 25; + + for (i = 0; i < c / 2; i++) { + /* left of title */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, + 25 + i * 25, 0, 25, 20); + + /* right of title */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, + (width + 100) / 2 + i * 25, 0, 25, 20); + } + + if (c & 1) { + /* Odd tile count, so one remaining to draw. Here we split + * it into two and draw half on either side of the title */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, + ((c / 2) * 25) + 25, 0, 12, 20); + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 127, y, + (width / 2) + ((c / 2) * 25) + 50, 0, 13, 20); + } +} + +static void +skin_draw_playlistwin_frame_bottom(Skin * skin, + GdkDrawable * drawable, + GdkGC * gc, + gint width, gint height, gboolean focus) +{ + /* The bottom frame skin consists of 1 set of 4 images. The 4 + * images are: + * + * a. left corner with menu buttons (125,38) + * b. visualization window (75,38) + * c. right corner with play buttons (150,38) + * d. frame tile (25,38) + * + * (min allowed width = 125+150+25=300 + */ + + gint i, c; + + /* bottom left corner (menu buttons) */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, 72, + 0, height - 38, 125, 38); + + c = (width - 275) / 25; + + /* draw visualization window, if width allows */ + if (c >= 3) { + c -= 3; + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 205, 0, + width - (150 + 75), height - 38, 75, 38); + } + + /* Bottom right corner (playbuttons etc) */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, + 126, 72, width - 150, height - 38, 150, 38); + + /* Tile draw the remaining undrawn portions */ + for (i = 0; i < c; i++) + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 179, 0, + 125 + i * 25, height - 38, 25, 38); +} + +static void +skin_draw_playlistwin_frame_sides(Skin * skin, + GdkDrawable * drawable, + GdkGC * gc, + gint width, gint height, gboolean focus) +{ + /* The side frames consist of 2 tile images. 1 for the left, 1 for + * the right. + * a. left (12,29) + * b. right (19,29) + */ + + gint i; + + /* frame sides */ + for (i = 0; i < (height - (20 + 38)) / 29; i++) { + /* left */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 0, 42, + 0, 20 + i * 29, 12, 29); + + /* right */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 32, 42, + width - 19, 20 + i * 29, 19, 29); + } +} + + +void +skin_draw_playlistwin_frame(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gint width, gint height, gboolean focus) +{ + skin_draw_playlistwin_frame_top(skin, drawable, gc, width, height, focus); + skin_draw_playlistwin_frame_bottom(skin, drawable, gc, width, height, + focus); + skin_draw_playlistwin_frame_sides(skin, drawable, gc, width, height, + focus); +} + + +void +skin_draw_playlistwin_shaded(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gint width, gboolean focus) +{ + /* The shade mode titlebar skin consists of 4 images: + * a) left corner offset (72,42) size (25,14) + * b) right corner, focused offset (99,57) size (50,14) + * c) right corner, unfocused offset (99,42) size (50,14) + * d) bar tile offset (72,57) size (25,14) + */ + + gint i; + + /* left corner */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14); + + /* bar tile */ + for (i = 0; i < (width - 75) / 25; i++) + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 72, 57, + (i * 25) + 25, 0, 25, 14); + + /* right corner */ + skin_draw_pixmap(skin, drawable, gc, SKIN_PLEDIT, 99, focus ? 57 : 42, + width - 50, 0, 50, 14); +} + + +void +skin_draw_mainwin_titlebar(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gboolean shaded, gboolean focus) +{ + /* The titlebar skin consists of 2 sets of 2 images, one for for + * shaded and the other for unshaded mode, giving a total of 4. + * The images are exactly 275x14 pixels, aligned and arranged + * vertically on each other in the pixmap in the following order: + * + * a) unshaded, focused offset (27, 0) + * b) unshaded, unfocused offset (27, 15) + * c) shaded, focused offset (27, 29) + * d) shaded, unfocused offset (27, 42) + */ + + gint y_offset; + + if (shaded) { + if (focus) + y_offset = 29; + else + y_offset = 42; + } + else { + if (focus) + y_offset = 0; + else + y_offset = 15; + } + + skin_draw_pixmap(skin, drawable, gc, SKIN_TITLEBAR, 27, y_offset, + 0, 0, MAINWIN_WIDTH, MAINWIN_TITLEBAR_HEIGHT); +} + +#if 0 +void +skin_draw_mainwin(Skin * skin, + GdkDrawable * drawable, GdkGC gc, + gboolean doublesize, gboolean shaded, gboolean focus) +{ + +} +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/skin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/skin.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,145 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SKIN_H +#define SKIN_H + + +#include +#include + + +#define BMP_DEFAULT_SKIN_PATH \ + DATA_DIR G_DIR_SEPARATOR_S "Skins" G_DIR_SEPARATOR_S "Default" + + +typedef enum { + SKIN_MAIN = 0, + SKIN_CBUTTONS, + SKIN_TITLEBAR, + SKIN_SHUFREP, + SKIN_TEXT, + SKIN_VOLUME, + SKIN_BALANCE, + SKIN_MONOSTEREO, + SKIN_PLAYPAUSE, + SKIN_NUMBERS, + SKIN_POSBAR, + SKIN_PLEDIT, + SKIN_EQMAIN, + SKIN_EQ_EX, + SKIN_PIXMAP_COUNT +} SkinPixmapId; + +typedef enum { + SKIN_MASK_MAIN = 0, + SKIN_MASK_MAIN_SHADE, + SKIN_MASK_EQ, + SKIN_MASK_EQ_SHADE, + SKIN_MASK_COUNT +} SkinMaskId; + +typedef enum { + SKIN_PLEDIT_NORMAL = 0, + SKIN_PLEDIT_CURRENT, + SKIN_PLEDIT_NORMALBG, + SKIN_PLEDIT_SELECTEDBG, + SKIN_TEXTBG, + SKIN_TEXTFG, + SKIN_COLOR_COUNT +} SkinColorId; + +typedef struct _SkinProperties { + gboolean mainwin_othertext; +} SkinProperties; + +#define SKIN_PIXMAP(x) ((SkinPixmap *)(x)) +typedef struct _SkinPixmap { + GdkPixmap *pixmap; + /* GdkPixmap *def_pixmap; */ + + /* The real size of the pixmap */ + gint width, height; + + /* The size of the pixmap from the current skin, + which might be smaller */ + gint current_width, current_height; +} SkinPixmap; + + +#define SKIN(x) ((Skin *)(x)) +typedef struct _Skin { + GMutex *lock; + gchar *path; + gchar *def_path; + SkinPixmap pixmaps[SKIN_PIXMAP_COUNT]; + GdkColor textbg[6], def_textbg[6]; + GdkColor textfg[6], def_textfg[6]; + GdkColor *colors[SKIN_COLOR_COUNT]; + guchar vis_color[24][3]; + GdkBitmap *masks[SKIN_MASK_COUNT]; + SkinProperties properties; +} Skin; + +extern Skin *bmp_active_skin; + +gboolean init_skins(const gchar * path); +void cleanup_skins(void); + +gboolean bmp_active_skin_load(const gchar * path); +gboolean bmp_active_skin_reload(void); + +Skin *skin_new(void); +gboolean skin_load(Skin * skin, const gchar * path); +void skin_reload(Skin * skin); +void skin_free(Skin * skin); + +GdkBitmap *skin_get_mask(Skin * skin, SkinMaskId mi); +GdkColor *skin_get_color(Skin * skin, SkinColorId color_id); + +void skin_get_viscolor(Skin * skin, guchar vis_color[24][3]); +gint skin_get_id(void); +void skin_draw_pixmap(Skin * skin, GdkDrawable * drawable, GdkGC * gc, + SkinPixmapId pixmap_id, + gint xsrc, gint ysrc, gint xdest, gint ydest, + gint width, gint height); +void skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]); +void skin_install_skin(const gchar * path); + +void skin_draw_playlistwin_shaded(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gint width, gboolean focus); +void skin_draw_playlistwin_frame(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gint width, gint height, gboolean focus); + +void skin_draw_mainwin_titlebar(Skin * skin, + GdkDrawable * drawable, GdkGC * gc, + gboolean shaded, gboolean focus); + + +void skin_parse_hints(Skin * skin, gchar *path_p); + + +gboolean +skin_reload_forced(void); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/svis.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/svis.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,204 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "svis.h" + +#include +#include +#include + +#include "main.h" +#include "mainwin.h" +#include "plugin.h" +#include "widget.h" +#include "vis.h" + +static gint svis_redraw_delays[] = { 1, 2, 4, 8 }; + +/* FIXME: Are the svis_scope_colors correct? */ +static guint8 svis_scope_colors[] = { 20, 19, 18, 19, 20 }; +static guint8 svis_vu_normal_colors[] = { 17, 17, 17, 12, 12, 12, 2, 2 }; + +#define DRAW_DS_PIXEL(ptr,value) \ + *(ptr) = (value); \ + *((ptr) + 1) = (value); \ + *((ptr) + 76) = (value); \ + *((ptr) + 77) = (value); + +#define SVIS_HEIGHT 5 +#define SVIS_WIDTH 38 + +void +svis_timeout_func(SVis * svis, guchar * data) +{ + static GTimer *timer = NULL; + gulong micros = 9999999; + gboolean falloff = FALSE; + gint i; + + if (!timer) { + timer = g_timer_new(); + g_timer_start(timer); + } + else { + g_timer_elapsed(timer, µs); + if (micros > 14000) + g_timer_reset(timer); + + } + + if (cfg.vis_type == INPUT_VIS_ANALYZER) { + if (micros > 14000) + falloff = TRUE; + + for (i = 0; i < 2; i++) { + if (falloff || data) { + if (data && data[i] > svis->vs_data[i]) + svis->vs_data[i] = data[i]; + else if (falloff) { + if (svis->vs_data[i] >= 2) + svis->vs_data[i] -= 2; + else + svis->vs_data[i] = 0; + } + } + + } + } + else if (data) { + for (i = 0; i < 75; i++) + svis->vs_data[i] = data[i]; + } + + if (micros > 14000) { + if (!svis->vs_refresh_delay) { + svis_draw((Widget *) svis); + svis->vs_refresh_delay = svis_redraw_delays[cfg.vis_refresh]; + + } + svis->vs_refresh_delay--; + } +} + +void +svis_draw(Widget * w) +{ + SVis *svis = (SVis *) w; + gint x, y, h; + guchar svis_color[24][3]; + guchar rgb_data[SVIS_WIDTH * 2 * SVIS_HEIGHT * 2], *ptr, c; + guint32 colors[24]; + GdkRgbCmap *cmap; + + GDK_THREADS_ENTER(); + + skin_get_viscolor(bmp_active_skin, svis_color); + for (y = 0; y < 24; y++) { + colors[y] = + svis_color[y][0] << 16 | svis_color[y][1] << 8 | svis_color[y][2]; + } + cmap = gdk_rgb_cmap_new(colors, 24); + + memset(rgb_data, 0, SVIS_WIDTH * SVIS_HEIGHT); + if (cfg.vis_type == VIS_ANALYZER) { + switch (cfg.vu_mode) { + case VU_NORMAL: + for (y = 0; y < 2; y++) { + ptr = rgb_data + ((y * 3) * 38); + h = (svis->vs_data[y] * 7) / 37; + for (x = 0; x < h; x++, ptr += 5) { + c = svis_vu_normal_colors[x]; + *(ptr) = c; + *(ptr + 1) = c; + *(ptr + 2) = c; + *(ptr + 38) = c; + *(ptr + 39) = c; + *(ptr + 40) = c; + } + } + break; + case VU_SMOOTH: + for (y = 0; y < 2; y++) { + ptr = rgb_data + ((y * 3) * SVIS_WIDTH); + for (x = 0; x < svis->vs_data[y]; x++, ptr++) { + c = 17 - ((x * 15) / 37); + *(ptr) = c; + *(ptr + 38) = c; + } + } + break; + } + } + else if (cfg.vis_type == VIS_SCOPE) { + for (x = 0; x < 38; x++) { + h = svis->vs_data[x << 1] / 3; + ptr = rgb_data + ((4 - h) * 38) + x; + *ptr = svis_scope_colors[h]; + } + } + + gdk_draw_indexed_image(mainwin->window, mainwin_gc, + svis->vs_widget.x, svis->vs_widget.y, + svis->vs_widget.width, + svis->vs_widget.height, + GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, + 38, cmap); + + gdk_rgb_cmap_free(cmap); + GDK_THREADS_LEAVE(); +} + +void +svis_clear_data(SVis * svis) +{ + gint i; + + if (!svis) + return; + + for (i = 0; i < 75; i++) { + svis->vs_data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0; + } +} + +void +svis_clear(SVis * svis) +{ + gdk_window_clear_area(mainwin->window, svis->vs_widget.x, + svis->vs_widget.y, svis->vs_widget.width, + svis->vs_widget.height); +} + +SVis * +create_svis(GList ** wlist, + GdkPixmap * parent, + GdkGC * gc, + gint x, gint y) +{ + SVis *svis; + + svis = g_new0(SVis, 1); + widget_init(&svis->vs_widget, parent, gc, x, y, SVIS_WIDTH, SVIS_HEIGHT, + 1); + + widget_list_add(wlist, WIDGET(svis)); + return svis; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/svis.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/svis.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,47 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef SVIS_H +#define SVIS_H + +#include +#include + +#include "svis.h" +#include "widget.h" + +#define SVIS(x) ((SVis *)(x)) +struct _SVis { + Widget vs_widget; + gint vs_data[75]; + gint vs_refresh_delay; +}; + +typedef struct _SVis SVis; + +void svis_draw(Widget * w); +void svis_timeout_func(SVis * svis, guchar * data); +SVis *create_svis(GList ** wlist, GdkPixmap * parent, GdkGC * gc, gint x, + gint y); +void svis_set_data(SVis * vis, guchar * data); +void svis_clear_data(SVis * vis); +void svis_clear(SVis * vis); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/tbutton.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/tbutton.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,176 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tbutton.h" + +#include +#include + +#include "widget.h" + +void +tbutton_draw(Widget * w) +{ + TButton *button = TBUTTON(w); + GdkPixmap *obj; + + obj = button->tb_widget.parent; + + if (button->tb_pressed && button->tb_inside) { + if (button->tb_selected) { + skin_draw_pixmap(bmp_active_skin, obj, + button->tb_widget.gc, + button->tb_skin_index, + button->tb_psx, button->tb_psy, + button->tb_widget.x, button->tb_widget.y, + button->tb_widget.width, + button->tb_widget.height); + } + else { + skin_draw_pixmap(bmp_active_skin, obj, + button->tb_widget.gc, + button->tb_skin_index, + button->tb_pux, button->tb_puy, + button->tb_widget.x, button->tb_widget.y, + button->tb_widget.width, + button->tb_widget.height); + } + } + else { + if (button->tb_selected) { + skin_draw_pixmap(bmp_active_skin, obj, + button->tb_widget.gc, + button->tb_skin_index, + button->tb_nsx, button->tb_nsy, + button->tb_widget.x, button->tb_widget.y, + button->tb_widget.width, + button->tb_widget.height); + } + else { + skin_draw_pixmap(bmp_active_skin, obj, + button->tb_widget.gc, + button->tb_skin_index, + button->tb_nux, button->tb_nuy, + button->tb_widget.x, button->tb_widget.y, + button->tb_widget.width, + button->tb_widget.height); + + } + } +} + +void +tbutton_button_press_cb(GtkWidget * widget, GdkEventButton * event, + TButton * button) +{ + if (event->button != 1) + return; + + if (widget_contains(&button->tb_widget, event->x, event->y)) { + button->tb_pressed = 1; + button->tb_inside = 1; + widget_draw(WIDGET(button)); + } +} + +void +tbutton_button_release_cb(GtkWidget * widget, GdkEventButton * event, + TButton * button) +{ + if (event->button != 1) + return; + + if (button->tb_inside && button->tb_pressed) { + button->tb_inside = 0; + button->tb_selected = !button->tb_selected; + + widget_draw(WIDGET(button)); + + if (button->tb_push_cb) + button->tb_push_cb(button->tb_selected); + } + + if (button->tb_pressed) + button->tb_pressed = 0; +} + +void +tbutton_motion_cb(GtkWidget * widget, GdkEventMotion * event, + TButton * button) +{ + gint inside; + + if (!button->tb_pressed) + return; + inside = widget_contains(&button->tb_widget, event->x, event->y); + if (inside != button->tb_inside) { + button->tb_inside = inside; + widget_draw(WIDGET(button)); + } +} + +TButton * +create_tbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nux, gint nuy, + gint pux, gint puy, gint nsx, gint nsy, gint psx, + gint psy, void (*cb) (gboolean), SkinPixmapId si) +{ + TButton *b; + + b = g_new0(TButton, 1); + widget_init(&b->tb_widget, parent, gc, x, y, w, h, 1); + b->tb_widget.button_press_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + tbutton_button_press_cb; + b->tb_widget.button_release_cb = + (void (*)(GtkWidget *, GdkEventButton *, gpointer)) + tbutton_button_release_cb; + b->tb_widget.motion_cb = + (void (*)(GtkWidget *, GdkEventMotion *, gpointer)) + tbutton_motion_cb; + b->tb_widget.draw = tbutton_draw; + b->tb_nux = nux; + b->tb_nuy = nuy; + b->tb_pux = pux; + b->tb_puy = puy; + b->tb_nsx = nsx; + b->tb_nsy = nsy; + b->tb_psx = psx; + b->tb_psy = psy; + b->tb_push_cb = cb; + b->tb_skin_index = si; + + widget_list_add(wlist, WIDGET(b)); + return b; +} + +void +tbutton_set_toggled(TButton * tb, gboolean toggled) +{ + tb->tb_selected = toggled; + widget_draw(WIDGET(tb)); +} + +void +free_tbutton(TButton * b) +{ + g_free(b); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/tbutton.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/tbutton.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,48 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TBUTTON_H +#define TBUTTON_H + +#include + +#include "skin.h" +#include "widget.h" + +#define TBUTTON(x) ((TButton *)(x)) +struct _TButton { + Widget tb_widget; + gint tb_nux, tb_nuy, tb_pux, tb_puy, tb_nsx, tb_nsy, tb_psx, tb_psy; + gint tb_pressed, tb_inside, tb_selected; + void (*tb_push_cb) (gboolean); + SkinPixmapId tb_skin_index; +}; + +typedef struct _TButton TButton; + +TButton *create_tbutton(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gint h, gint nux, gint nuy, + gint pux, gint puy, gint nsx, gint nsy, gint psx, + gint psy, void (*cb) (gboolean), SkinPixmapId si); +void tbutton_set_toggled(TButton * tb, gboolean toggled); +void free_tbutton(TButton * b); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/textbox.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/textbox.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,579 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "textbox.h" + +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "util.h" + +static void textbox_generate_pixmap(TextBox * tb); + +static void +textbox_draw(Widget * w) +{ + TextBox *tb = TEXT_BOX(w); + gint cw; + GdkPixmap *obj; + GdkPixmap *src; + + g_return_if_fail(tb != NULL); + + if (tb->tb_text && + (!tb->tb_pixmap_text || strcmp(tb->tb_text, tb->tb_pixmap_text))) + textbox_generate_pixmap(tb); + + if (tb->tb_pixmap) { + if (skin_get_id() != tb->tb_skin_id) { + tb->tb_skin_id = skin_get_id(); + textbox_generate_pixmap(tb); + } + obj = tb->tb_widget.parent; + src = tb->tb_pixmap; + + cw = tb->tb_pixmap_width - tb->tb_offset; + if (cw > tb->tb_widget.width) + cw = tb->tb_widget.width; + gdk_draw_pixmap(obj, tb->tb_widget.gc, src, tb->tb_offset, 0, + tb->tb_widget.x, tb->tb_widget.y, cw, + tb->tb_widget.height); + if (cw < tb->tb_widget.width) + gdk_draw_pixmap(obj, tb->tb_widget.gc, src, 0, 0, + tb->tb_widget.x + cw, tb->tb_widget.y, + tb->tb_widget.width - cw, tb->tb_widget.height); + } +} + +static gboolean +textbox_scroll(gpointer data) +{ + TextBox *tb = TEXT_BOX(data); + + if (!tb->tb_is_dragging) { + tb->tb_offset += 1; + if (tb->tb_offset >= tb->tb_pixmap_width) + tb->tb_offset -= tb->tb_pixmap_width; + widget_draw(WIDGET(tb)); + } + + return TRUE; +} + +static void +textbox_button_press(GtkWidget * w, GdkEventButton * event, gpointer data) +{ + TextBox *tb = TEXT_BOX(data); + + if (event->button != 1) + return; + if (widget_contains(&tb->tb_widget, event->x, event->y) && + tb->tb_scroll_allowed && + tb->tb_pixmap_width > tb->tb_widget.width && tb->tb_is_scrollable) { + tb->tb_is_dragging = TRUE; + tb->tb_drag_off = tb->tb_offset; + tb->tb_drag_x = event->x; + } +} + +static void +textbox_motion(GtkWidget * w, GdkEventMotion * event, gpointer data) +{ + TextBox *tb = TEXT_BOX(data); + + if (tb->tb_is_dragging) { + if (tb->tb_scroll_allowed && + tb->tb_pixmap_width > tb->tb_widget.width) { + tb->tb_offset = tb->tb_drag_off - (event->x - tb->tb_drag_x); + + while (tb->tb_offset < 0) + tb->tb_offset += tb->tb_pixmap_width; + + while (tb->tb_offset > tb->tb_pixmap_width) + tb->tb_offset -= tb->tb_pixmap_width; + + widget_draw(WIDGET(tb)); + } + } +} + +static void +textbox_button_release(GtkWidget * w, GdkEventButton * event, gpointer data) +{ + TextBox *tb = TEXT_BOX(data); + + if (event->button == 1) + tb->tb_is_dragging = FALSE; +} + +static gboolean +textbox_should_scroll(TextBox * tb) +{ + g_return_val_if_fail(tb != NULL, FALSE); + + if (!tb->tb_scroll_allowed) + return FALSE; + + if (tb->tb_font) { + gint width; + + text_get_extents(tb->tb_fontname, tb->tb_text, &width, NULL, NULL, + NULL); + + if (width <= tb->tb_widget.width) + return FALSE; + else + return TRUE; + } + + if (g_utf8_strlen(tb->tb_text, -1) * 5 > tb->tb_widget.width) + return TRUE; + + return FALSE; +} + +void +textbox_set_text(TextBox * tb, const gchar * text) +{ + g_return_if_fail(tb != NULL); + g_return_if_fail(text != NULL); + + widget_lock(WIDGET(tb)); + + if (tb->tb_text) { + if (!strcmp(text, tb->tb_text)) { + widget_unlock(WIDGET(tb)); + return; + } + g_free(tb->tb_text); + } + + tb->tb_text = str_to_utf8(text); + + widget_unlock(WIDGET(tb)); + widget_draw(WIDGET(tb)); +} + +static void +textbox_generate_xfont_pixmap(TextBox * tb, const gchar * pixmaptext) +{ + gint length, i; + GdkGC *gc, *maskgc; + GdkColor *c, pattern; + GdkBitmap *mask; + PangoLayout *layout; + gint width; + + g_return_if_fail(tb != NULL); + g_return_if_fail(pixmaptext != NULL); + + length = g_utf8_strlen(pixmaptext, -1); + + text_get_extents(tb->tb_fontname, pixmaptext, &width, NULL, NULL, NULL); + + tb->tb_pixmap_width = MAX(width, tb->tb_widget.width); + tb->tb_pixmap = gdk_pixmap_new(mainwin->window, tb->tb_pixmap_width, + tb->tb_widget.height, + gdk_rgb_get_visual()->depth); + gc = tb->tb_widget.gc; + c = skin_get_color(bmp_active_skin, SKIN_TEXTBG); + for (i = 0; i < tb->tb_widget.height; i++) { + gdk_gc_set_foreground(gc, &c[6 * i / tb->tb_widget.height]); + gdk_draw_line(tb->tb_pixmap, gc, 0, i, tb->tb_pixmap_width, i); + } + + mask = gdk_pixmap_new(mainwin->window, tb->tb_pixmap_width, + tb->tb_widget.height, 1); + maskgc = gdk_gc_new(mask); + pattern.pixel = 0; + gdk_gc_set_foreground(maskgc, &pattern); + + gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, + tb->tb_pixmap_width, tb->tb_widget.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, tb->tb_font); + + gdk_draw_layout(tb->tb_pixmap, gc, 0, (tb->tb_font_descent / 2), layout); + g_object_unref(layout); + + g_object_unref(maskgc); + + gdk_gc_set_clip_mask(gc, mask); + c = skin_get_color(bmp_active_skin, SKIN_TEXTFG); + for (i = 0; i < tb->tb_widget.height; i++) { + gdk_gc_set_foreground(gc, &c[6 * i / tb->tb_widget.height]); + gdk_draw_line(tb->tb_pixmap, gc, 0, i, tb->tb_pixmap_width, i); + } + g_object_unref(mask); + gdk_gc_set_clip_mask(gc, NULL); +} + +static void +textbox_handle_special_char(gchar c, gint * x, gint * y) +{ + switch (c) { + case '"': + *x = 130; + *y = 0; + break; + case '\r': + *x = 50; + *y = 6; + break; + case ':': + case ';': + *x = 60; + *y = 6; + break; + case '(': + *x = 65; + *y = 6; + break; + case ')': + *x = 70; + *y = 6; + break; + case '-': + *x = 75; + *y = 6; + break; + case '`': + case '\'': + *x = 80; + *y = 6; + break; + case '!': + *x = 85; + *y = 6; + break; + case '_': + *x = 90; + *y = 6; + break; + case '+': + *x = 95; + *y = 6; + break; + case '\\': + *x = 100; + *y = 6; + break; + case '/': + *x = 105; + *y = 6; + break; + case '[': + *x = 110; + *y = 6; + break; + case ']': + *x = 115; + *y = 6; + break; + case '^': + *x = 120; + *y = 6; + break; + case '&': + *x = 125; + *y = 6; + break; + case '%': + *x = 130; + *y = 6; + break; + case '.': + case ',': + *x = 135; + *y = 6; + break; + case '=': + *x = 140; + *y = 6; + break; + case '$': + *x = 145; + *y = 6; + break; + case '#': + *x = 150; + *y = 6; + break; + case 'å': + case 'Å': + *x = 0; + *y = 12; + break; + case 'ö': + case 'Ö': + *x = 5; + *y = 12; + break; + case 'ä': + case 'Ä': + *x = 10; + *y = 12; + break; + case 'ü': + case 'Ü': + *x = 100; + *y = 0; + break; + case '?': + *x = 15; + *y = 12; + break; + case '*': + *x = 20; + *y = 12; + break; + default: + *x = 145; + *y = 0; + break; + } +} + +static void +textbox_generate_pixmap(TextBox * tb) +{ + gint length, i, x, y, wl; + gchar *pixmaptext; + GdkGC *gc; + + g_return_if_fail(tb != NULL); + + if (tb->tb_pixmap) { + g_object_unref(tb->tb_pixmap); + tb->tb_pixmap = NULL; + } + + /* + * Don't reset the offset if only text after the last '(' has + * changed. This is a hack to avoid visual noice on vbr files + * where we guess the length. + */ + if (!(tb->tb_pixmap_text && strrchr(tb->tb_text, '(') && + !strncmp(tb->tb_pixmap_text, tb->tb_text, + strrchr(tb->tb_text, '(') - tb->tb_text))) + tb->tb_offset = 0; + + g_free(tb->tb_pixmap_text); + tb->tb_pixmap_text = g_strdup(tb->tb_text); + + /* + * wl is the number of (partial) letters visible. Only makes + * sense when using skinned font. + */ + + wl = tb->tb_widget.width / 5; + if (wl * 5 != tb->tb_widget.width) + wl++; + + length = g_utf8_strlen(tb->tb_text, -1); + + tb->tb_is_scrollable = FALSE; + + if (textbox_should_scroll(tb)) { + tb->tb_is_scrollable = TRUE; + pixmaptext = g_strconcat(tb->tb_pixmap_text, " *** ", NULL); + length += 7; + } + else if (!tb->tb_font && length <= wl) { + gint pad = wl - length; + gchar *padchars = g_strnfill(pad, ' '); + + pixmaptext = g_strconcat(tb->tb_pixmap_text, padchars, NULL); + g_free(padchars); + length += pad; + } + else + pixmaptext = g_strdup(tb->tb_pixmap_text); + + + if (tb->tb_is_scrollable) { + if (tb->tb_scroll_enabled && !tb->tb_timeout_tag) { + gint tag; + tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT; + tb->tb_timeout_tag = gtk_timeout_add(tag, textbox_scroll, tb); + } + } + else { + if (tb->tb_timeout_tag) { + gtk_timeout_remove(tb->tb_timeout_tag); + tb->tb_timeout_tag = 0; + } + tb->tb_offset = 0; + } + + if (tb->tb_font) { + textbox_generate_xfont_pixmap(tb, pixmaptext); + g_free(pixmaptext); + return; + } + + tb->tb_pixmap_width = length * 5; + tb->tb_pixmap = gdk_pixmap_new(mainwin->window, + tb->tb_pixmap_width, 6, + gdk_rgb_get_visual()->depth); + gc = tb->tb_widget.gc; + + for (i = 0; i < length; i++) { + gchar c; + x = y = -1; + c = toupper(pixmaptext[i]); + if (c >= 'A' && c <= 'Z') { + x = 5 * (c - 'A'); + y = 0; + } + else if (c >= '0' && c <= '9') { + x = 5 * (c - '0'); + y = 6; + } + else + textbox_handle_special_char(c, &x, &y); + + skin_draw_pixmap(bmp_active_skin, + tb->tb_pixmap, gc, tb->tb_skin_index, + x, y, i * 5, 0, 5, 6); + } + g_free(pixmaptext); +} + +void +textbox_set_scroll(TextBox * tb, gboolean s) +{ + g_return_if_fail(tb != NULL); + + tb->tb_scroll_enabled = s; + if (tb->tb_scroll_enabled && tb->tb_is_scrollable + && tb->tb_scroll_allowed) { + gint tag; + tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT; + + if (tb->tb_timeout_tag) + { + gtk_timeout_remove(tb->tb_timeout_tag); + tb->tb_timeout_tag = 0; + } + + tb->tb_timeout_tag = gtk_timeout_add(tag, textbox_scroll, tb); + } + else + { + if (tb->tb_timeout_tag) + { + gtk_timeout_remove(tb->tb_timeout_tag); + tb->tb_timeout_tag = 0; + } + + tb->tb_offset = 0; + widget_draw(WIDGET(tb)); + } + +} + +void +textbox_set_xfont(TextBox * tb, gboolean use_xfont, const gchar * fontname) +{ + gint ascent, descent; + + g_return_if_fail(tb != NULL); + + if (tb->tb_font) { + pango_font_description_free(tb->tb_font); + tb->tb_font = NULL; + } + + tb->tb_widget.y = tb->tb_nominal_y; + tb->tb_widget.height = tb->tb_nominal_height; + + /* Make sure the pixmap is regenerated */ + if (tb->tb_pixmap_text) { + g_free(tb->tb_pixmap_text); + tb->tb_pixmap_text = NULL; + } + + if (!use_xfont || strlen(fontname) == 0) + return; + + tb->tb_font = pango_font_description_from_string(fontname); + tb->tb_fontname = g_strdup(fontname); + + text_get_extents(fontname, + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ", + NULL, NULL, &ascent, &descent); + tb->tb_font_ascent = ascent; + tb->tb_font_descent = descent; + + + if (tb->tb_font == NULL) + return; + + tb->tb_widget.height = tb->tb_font_ascent; + if (tb->tb_widget.height > tb->tb_nominal_height) + tb->tb_widget.y -= (tb->tb_widget.height - tb->tb_nominal_height) / 2; + else + tb->tb_widget.height = tb->tb_nominal_height; +} + +TextBox * +create_textbox(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) +{ + TextBox *tb; + + tb = g_new0(TextBox, 1); + widget_init(&tb->tb_widget, parent, gc, x, y, w, 6, 1); + tb->tb_widget.button_press_cb = textbox_button_press; + tb->tb_widget.button_release_cb = textbox_button_release; + tb->tb_widget.motion_cb = textbox_motion; + tb->tb_widget.draw = textbox_draw; + tb->tb_scroll_allowed = allow_scroll; + tb->tb_scroll_enabled = TRUE; + tb->tb_skin_index = si; + tb->tb_nominal_y = y; + tb->tb_nominal_height = tb->tb_widget.height; + widget_list_add(wlist, WIDGET(tb)); + tb->tb_timeout_tag = 0; + return tb; +} + +void +textbox_free(TextBox * tb) +{ + g_return_if_fail(tb != NULL); + + if (tb->tb_pixmap) + g_object_unref(tb->tb_pixmap); + g_free(tb->tb_text); + g_free(tb); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/textbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/textbox.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,64 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef TEXTBOX_H +#define TEXTBOX_H + +#include +#include +#include + +#include "skin.h" +#include "widget.h" + +#define TEXTBOX_SCROLL_TIMEOUT 200 +#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT 30 + +#define TEXT_BOX(x) ((TextBox *)(x)) +struct _TextBox { + Widget tb_widget; + GdkPixmap *tb_pixmap; + gchar *tb_text, *tb_pixmap_text; + gint tb_pixmap_width; + gint tb_offset; + gboolean tb_scroll_allowed, tb_scroll_enabled; + gboolean tb_is_scrollable, tb_is_dragging; + gint tb_timeout_tag, tb_drag_x, tb_drag_off; + gint tb_nominal_y, tb_nominal_height; + gint tb_skin_id; + SkinPixmapId tb_skin_index; + PangoFontDescription *tb_font; + gint tb_font_ascent, tb_font_descent; + gchar *tb_fontname; +}; + +typedef struct _TextBox TextBox; + +void textbox_set_text(TextBox * tb, const gchar * text); +void textbox_set_scroll(TextBox * tb, gboolean s); +TextBox *create_textbox(GList ** wlist, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint w, gboolean allow_scroll, + SkinPixmapId si); +void textbox_set_xfont(TextBox * tb, gboolean use_xfont, + const gchar * fontname); +void textbox_free(TextBox * tb); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/vis.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/vis.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,291 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "vis.h" + +#include +#include +#include + +#include "main.h" +#include "skin.h" +#include "widget.h" + +static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 }; +static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 }; +static const gint vis_redraw_delays[] = { 1, 2, 4, 8 }; +static const guint8 vis_scope_colors[] = + { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 }; + +void +vis_timeout_func(Vis * vis, guchar * data) +{ + static GTimer *timer = NULL; + gulong micros = 9999999; + gboolean falloff = FALSE; + gint i; + + if (!timer) { + timer = g_timer_new(); + g_timer_start(timer); + } + else { + g_timer_elapsed(timer, µs); + if (micros > 14000) + g_timer_reset(timer); + + } + + if (cfg.vis_type == VIS_ANALYZER) { + if (micros > 14000) + falloff = TRUE; + if (data || falloff) { + for (i = 0; i < 75; i++) { + if (data && data[i] > vis->vs_data[i]) { + vis->vs_data[i] = data[i]; + if (vis->vs_data[i] > vis->vs_peak[i]) { + vis->vs_peak[i] = vis->vs_data[i]; + vis->vs_peak_speed[i] = 0.01; + + } + else if (vis->vs_peak[i] > 0.0) { + vis->vs_peak[i] -= vis->vs_peak_speed[i]; + vis->vs_peak_speed[i] *= + vis_pfalloff_speeds[cfg.peaks_falloff]; + if (vis->vs_peak[i] < vis->vs_data[i]) + vis->vs_peak[i] = vis->vs_data[i]; + if (vis->vs_peak[i] < 0.0) + vis->vs_peak[i] = 0.0; + } + } + else if (falloff) { + if (vis->vs_data[i] > 0.0) { + vis->vs_data[i] -= + vis_afalloff_speeds[cfg.analyzer_falloff]; + if (vis->vs_data[i] < 0.0) + vis->vs_data[i] = 0.0; + } + if (vis->vs_peak[i] > 0.0) { + vis->vs_peak[i] -= vis->vs_peak_speed[i]; + vis->vs_peak_speed[i] *= + vis_pfalloff_speeds[cfg.peaks_falloff]; + if (vis->vs_peak[i] < vis->vs_data[i]) + vis->vs_peak[i] = vis->vs_data[i]; + if (vis->vs_peak[i] < 0.0) + vis->vs_peak[i] = 0.0; + } + } + } + } + } + else if (data) { + for (i = 0; i < 75; i++) + vis->vs_data[i] = data[i]; + } + + if (micros > 14000) { + if (!vis->vs_refresh_delay) { + vis_draw((Widget *) vis); + vis->vs_refresh_delay = vis_redraw_delays[cfg.vis_refresh]; + + } + vis->vs_refresh_delay--; + } +} + +void +vis_draw(Widget * w) +{ + Vis *vis = (Vis *) w; + gint x, y, h = 0, h2; + guchar vis_color[24][3]; + guchar rgb_data[152 * 32], *ptr, c; + guint32 colors[24]; + GdkRgbCmap *cmap; + + if (!vis->vs_widget.visible) + return; + + skin_get_viscolor(bmp_active_skin, vis_color); + for (y = 0; y < 24; y++) { + colors[y] = + vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2]; + } + cmap = gdk_rgb_cmap_new(colors, 24); + + memset(rgb_data, 0, 76 * 16); + for (y = 1; y < 16; y += 2) { + ptr = rgb_data + (y * 76); + for (x = 0; x < 76; x += 2, ptr += 2) + *ptr = 1; + } + if (cfg.vis_type == VIS_ANALYZER) { + for (x = 0; x < 75; x++) { + if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) + h = vis->vs_data[x >> 2]; + else if (cfg.analyzer_type == ANALYZER_LINES) + h = vis->vs_data[x]; + if (h && (cfg.analyzer_type == ANALYZER_LINES || + (x % 4) != 3)) { + ptr = rgb_data + ((16 - h) * 76) + x; + switch (cfg.analyzer_mode) { + case ANALYZER_NORMAL: + for (y = 0; y < h; y++, ptr += 76) + *ptr = 18 - h + y; + break; + case ANALYZER_FIRE: + for (y = 0; y < h; y++, ptr += 76) + *ptr = y + 2; + break; + case ANALYZER_VLINES: + for (y = 0; y < h; y++, ptr += 76) + *ptr = 18 - h; + break; + } + } + } + if (cfg.analyzer_peaks) { + for (x = 0; x < 75; x++) { + if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0) + h = vis->vs_peak[x >> 2]; + else if (cfg.analyzer_type == ANALYZER_LINES) + h = vis->vs_peak[x]; + if (h + && (cfg.analyzer_type == ANALYZER_LINES + || (x % 4) != 3)) + rgb_data[(16 - h) * 76 + x] = 23; + } + } + } + else if (cfg.vis_type == VIS_SCOPE) { + for (x = 0; x < 75; x++) { + switch (cfg.scope_mode) { + case SCOPE_DOT: + h = vis->vs_data[x]; + ptr = rgb_data + ((15 - h) * 76) + x; + *ptr = vis_scope_colors[h]; + break; + case SCOPE_LINE: + if (x != 74) { + h = 15 - vis->vs_data[x]; + h2 = 15 - vis->vs_data[x + 1]; + if (h > h2) { + y = h; + h = h2; + h2 = y; + } + ptr = rgb_data + (h * 76) + x; + for (y = h; y <= h2; y++, ptr += 76) + *ptr = vis_scope_colors[y - 3]; + + } + else { + h = 15 - vis->vs_data[x]; + ptr = rgb_data + (h * 76) + x; + *ptr = vis_scope_colors[h]; + } + break; + case SCOPE_SOLID: + h = 15 - vis->vs_data[x]; + h2 = 9; + c = vis_scope_colors[(gint) vis->vs_data[x]]; + if (h > h2) { + y = h; + h = h2; + h2 = y; + } + ptr = rgb_data + (h * 76) + x; + for (y = h; y <= h2; y++, ptr += 76) + *ptr = c; + break; + } + } + } + + /* FIXME: The check "shouldn't" be neccessary? */ + /* if (GTK_IS_WINDOW(vis->vs_window)) { */ + GDK_THREADS_ENTER(); + gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, + vis->vs_widget.x, vis->vs_widget.y, + vis->vs_widget.width, vis->vs_widget.height, + GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, + 76, cmap); + GDK_THREADS_LEAVE(); + /* } else { + vis->vs_window = mainwin->window; + GDK_THREADS_ENTER(); + gdk_draw_indexed_image(vis->vs_window, vis->vs_widget.gc, + vis->vs_widget.x, vis->vs_widget.y, + vis->vs_widget.width, vis->vs_widget.height, + GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data, + 76, cmap); + GDK_THREADS_LEAVE(); + } + */ + + gdk_rgb_cmap_free(cmap); +} + +void +vis_clear_data(Vis * vis) +{ + gint i; + + if (!vis) + return; + + for (i = 0; i < 75; i++) { + vis->vs_data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0; + vis->vs_peak[i] = 0; + } +} + +void +vis_clear(Vis * vis) +{ + gdk_window_clear_area(vis->vs_window, vis->vs_widget.x, + vis->vs_widget.y, vis->vs_widget.width, + vis->vs_widget.height); +} + +void +vis_set_window(Vis * vis, GdkWindow * window) +{ + vis->vs_window = window; +} + +Vis * +create_vis(GList ** wlist, + GdkPixmap * parent, + GdkWindow * window, + GdkGC * gc, + gint x, gint y, + gint width) +{ + Vis *vis; + + vis = g_new0(Vis, 1); + + widget_init(&vis->vs_widget, parent, gc, x, y, width, 16, 1); + widget_list_add(wlist, WIDGET(vis)); + + return vis; +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/vis.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/vis.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,77 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef VIS_H +#define VIS_H + +#include +#include + +#include "widget.h" + +typedef enum { + VIS_ANALYZER, VIS_SCOPE, VIS_OFF +} VisType; + +typedef enum { + ANALYZER_NORMAL, ANALYZER_FIRE, ANALYZER_VLINES +} AnalyzerMode; + +typedef enum { + ANALYZER_LINES, ANALYZER_BARS +} AnalyzerType; + +typedef enum { + SCOPE_DOT, SCOPE_LINE, SCOPE_SOLID +} ScopeMode; + +typedef enum { + VU_NORMAL, VU_SMOOTH +} VUMode; + +typedef enum { + REFRESH_FULL, REFRESH_HALF, REFRESH_QUARTER, REFRESH_EIGTH +} RefreshRate; + +typedef enum { + FALLOFF_SLOWEST, FALLOFF_SLOW, FALLOFF_MEDIUM, FALLOFF_FAST, + FALLOFF_FASTEST +} FalloffSpeed; + +#define VIS(x) ((Vis *)(x)) +struct _Vis { + Widget vs_widget; + GdkWindow *vs_window; + gfloat vs_data[75], vs_peak[75], vs_peak_speed[75]; + gint vs_refresh_delay; +}; + +typedef struct _Vis Vis; + +void vis_draw(Widget * w); + +Vis *create_vis(GList ** wlist, GdkPixmap * parent, GdkWindow * window, + GdkGC * gc, gint x, gint y, gint width); +void vis_timeout_func(Vis * vis, guchar * data); +void vis_clear_data(Vis * vis); +void vis_clear(Vis * vis); +void vis_set_window(Vis * vis, GdkWindow * window); + +#endif diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/widget.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/widget.c Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,263 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "widget.h" + +#include +#include + +#include "debug.h" + + +void +widget_init(Widget * widget, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint width, gint height, gint visible) +{ + widget->parent = parent; + widget->gc = gc; + widget_set_position(widget, x, y); + widget_set_size(widget, width, height); + widget->visible = visible; + widget->redraw = TRUE; + widget->mutex = g_mutex_new(); +} + +void +widget_set_position(Widget * widget, gint x, gint y) +{ + widget->x = x; + widget->y = y; + widget_queue_redraw(widget); +} + +void +widget_set_size(Widget * widget, gint width, gint height) +{ + widget->width = width; + widget->height = height; + widget_queue_redraw(widget); +} + +void +widget_queue_redraw(Widget * widget) +{ + widget->redraw = TRUE; +} + +gboolean +widget_contains(Widget * widget, gint x, gint y) +{ + return (widget->visible && + x >= widget->x && + y >= widget->y && + x < widget->x + widget->width && + y < widget->y + widget->height); +} + +void +widget_show(Widget * widget) +{ + if (!widget) + return; + + widget->visible = TRUE; + widget_draw(widget); +} + +void +widget_hide(Widget * widget) +{ + if (!widget) + return; + + widget->visible = FALSE; +} + +gboolean +widget_is_visible(Widget * widget) +{ + if (!widget) + return FALSE; + + return widget->visible; +} + +void +widget_resize(Widget * widget, gint width, gint height) +{ + widget_set_size(widget, width, height); +} + +void +widget_move(Widget * widget, gint x, gint y) +{ + widget_lock(widget); + widget_set_position(widget, x, y); + widget_unlock(widget); +} + +void +widget_draw(Widget * widget) +{ + widget_lock(widget); + WIDGET(widget)->redraw = TRUE; + widget_unlock(widget); +} + +void +widget_draw_quick(Widget * widget) +{ + widget_lock(widget); + if (WIDGET(widget)->draw != NULL) + { + WIDGET(widget)->draw(widget); + gdk_flush(); + } + widget_unlock(widget); +} + +void +widget_list_add(GList ** list, Widget * widget) +{ + (*list) = g_list_append(*list, widget); +} + +void +handle_press_cb(GList * widget_list, GtkWidget * widget, + GdkEventButton * event) +{ + GList *wl; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + if (WIDGET(wl->data)->button_press_cb) + WIDGET(wl->data)->button_press_cb(widget, event, wl->data); + } +} + +void +handle_release_cb(GList * widget_list, GtkWidget * widget, + GdkEventButton * event) +{ + GList *wl; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + if (WIDGET(wl->data)->button_release_cb) + WIDGET(wl->data)->button_release_cb(widget, event, wl->data); + } +} + +void +handle_motion_cb(GList * widget_list, GtkWidget * widget, + GdkEventMotion * event) +{ + GList *wl; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + if (WIDGET(wl->data)->motion_cb) + WIDGET(wl->data)->motion_cb(widget, event, wl->data); + } +} + +void +handle_scroll_cb(GList * wlist, GtkWidget * widget, GdkEventScroll * event) +{ + GList *wl; + + for (wl = wlist; wl; wl = g_list_next(wl)) { + if (WIDGET(wl->data)->mouse_scroll_cb) + WIDGET(wl->data)->mouse_scroll_cb(widget, event, wl->data); + } +} + +void +widget_list_draw(GList * widget_list, gboolean * redraw, gboolean force) +{ + GList *wl; + Widget *w; + + *redraw = FALSE; + wl = widget_list; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + w = WIDGET(wl->data); + + REQUIRE_LOCK(w->mutex); + + if (!w->draw) + continue; + + if (!w->visible) + continue; + + if (w->redraw || force) { + w->draw(w); +/* w->redraw = FALSE; */ + *redraw = TRUE; + } + } +} + +void +widget_list_change_pixmap(GList * widget_list, GdkPixmap * pixmap) +{ + GList *wl; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + Widget *widget = wl->data; + widget->parent = pixmap; + widget_queue_redraw(widget); + } +} + +void +widget_list_clear_redraw(GList * widget_list) +{ + GList *wl; + + for (wl = widget_list; wl; wl = g_list_next(wl)) { + REQUIRE_LOCK(WIDGET(wl->data)->mutex); + WIDGET(wl->data)->redraw = FALSE; + } +} + +void +widget_lock(Widget * widget) +{ + g_mutex_lock(WIDGET(widget)->mutex); +} + +void +widget_unlock(Widget * widget) +{ + g_mutex_unlock(WIDGET(widget)->mutex); +} + +void +widget_list_lock(GList * widget_list) +{ + g_list_foreach(widget_list, (GFunc) widget_lock, NULL); +} + +void +widget_list_unlock(GList * widget_list) +{ + g_list_foreach(widget_list, (GFunc) widget_unlock, NULL); +} diff -r 237bb7c97759 -r 06329cbf186a audacious/widgets/widget.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/widgets/widget.h Wed Aug 09 02:47:22 2006 -0700 @@ -0,0 +1,102 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef WIDGET_H +#define WIDGET_H + + +#include +#include +#include + + +typedef struct _Widget Widget; + + +typedef void (*WidgetButtonPressFunc) (GtkWidget *, GdkEventButton *, + gpointer); +typedef void (*WidgetButtonReleaseFunc) (GtkWidget *, GdkEventButton *, + gpointer); +typedef void (*WidgetMotionFunc) (GtkWidget *, GdkEventMotion *, gpointer); +typedef void (*WidgetDrawFunc) (Widget *); +typedef void (*WidgetScrollFunc) (GtkWidget *, GdkEventScroll *, gpointer); + + +#define WIDGET(x) ((Widget *)(x)) +struct _Widget { + GdkPixmap *parent; + GdkGC *gc; + + gint x, y; + gint width, height; + + gint visible; + gboolean redraw; + + GMutex *mutex; + + WidgetButtonPressFunc button_press_cb; + WidgetButtonReleaseFunc button_release_cb; + WidgetMotionFunc motion_cb; + WidgetDrawFunc draw; + WidgetScrollFunc mouse_scroll_cb; +}; + + +void widget_init(Widget * widget, GdkPixmap * parent, GdkGC * gc, + gint x, gint y, gint width, gint height, gint visible); + +void widget_set_position(Widget * widget, gint x, gint y); +void widget_set_size(Widget * widget, gint width, gint height); +void widget_queue_redraw(Widget * widget); + +void widget_lock(Widget * widget); +void widget_unlock(Widget * widget); + +gboolean widget_contains(Widget * widget, gint x, gint y); + +void widget_show(Widget * widget); +void widget_hide(Widget * widget); +gboolean widget_is_visible(Widget * widget); + +void widget_resize(Widget * widget, gint width, gint height); +void widget_move(Widget * widget, gint x, gint y); +void widget_draw(Widget * widget); +void widget_draw_quick(Widget * widget); + +void handle_press_cb(GList * wlist, GtkWidget * widget, + GdkEventButton * event); +void handle_release_cb(GList * wlist, GtkWidget * widget, + GdkEventButton * event); +void handle_motion_cb(GList * wlist, GtkWidget * widget, + GdkEventMotion * event); +void handle_scroll_cb(GList * wlist, GtkWidget * widget, + GdkEventScroll * event); + +void widget_list_add(GList ** list, Widget * widget); +void widget_list_draw(GList * list, gboolean * redraw, gboolean force); +void widget_list_change_pixmap(GList * list, GdkPixmap * pixmap); +void widget_list_clear_redraw(GList * list); +void widget_list_lock(GList * list); +void widget_list_unlock(GList * list); + + + +#endif