Mercurial > audlegacy-plugins
changeset 2647:5808b64d3f68
branch merge
author | Paula Stanciu <paula.stanciu@gmail.com> |
---|---|
date | Sun, 25 May 2008 21:29:48 +0300 |
parents | 7fbff3287a56 (current diff) 45ef6d7c0174 (diff) |
children | 6cc858a726b8 |
files | src/alsa/init.c |
diffstat | 47 files changed, 4538 insertions(+), 551 deletions(-) [+] |
line wrap: on
line diff
--- a/src/alsa/Makefile Sun May 25 21:29:07 2008 +0300 +++ b/src/alsa/Makefile Sun May 25 21:29:48 2008 +0300 @@ -3,8 +3,7 @@ SRCS = alsa.c \ about.c \ audio.c \ - configure.c \ - init.c + configure.c include ../../buildsys.mk include ../../extra.mk
--- a/src/alsa/alsa.c Sun May 25 21:29:07 2008 +0300 +++ b/src/alsa/alsa.c Sun May 25 21:29:48 2008 +0300 @@ -17,9 +17,64 @@ */ #include "alsa.h" +#include <glib.h> #include <stdlib.h> +#include <dlfcn.h> +#include <ctype.h> + +struct alsa_config alsa_cfg; + + +static void alsa_cleanup(void) +{ + if (alsa_cfg.pcm_device) { + free(alsa_cfg.pcm_device); + alsa_cfg.pcm_device = NULL; + } + + if (alsa_cfg.mixer_device) { + free(alsa_cfg.mixer_device); + alsa_cfg.mixer_device = NULL; + } +} + + +static void alsa_init(void) +{ + mcs_handle_t *cfgfile; -OutputPlugin alsa_op = + memset(&alsa_cfg, 0, sizeof (alsa_cfg)); + + alsa_cfg.buffer_time = 500; + alsa_cfg.period_time = 100; + alsa_cfg.debug = 0; + alsa_cfg.vol.left = 100; + alsa_cfg.vol.right = 100; + + cfgfile = aud_cfg_db_open(); + if (!aud_cfg_db_get_string(cfgfile, ALSA_CFGID, "pcm_device", + &alsa_cfg.pcm_device)) + alsa_cfg.pcm_device = g_strdup("default"); + g_message("device: %s", alsa_cfg.pcm_device); + if (!aud_cfg_db_get_string(cfgfile, ALSA_CFGID, "mixer_device", + &alsa_cfg.mixer_device)) + alsa_cfg.mixer_device = g_strdup("PCM"); + aud_cfg_db_get_int(cfgfile, ALSA_CFGID, "mixer_card", &alsa_cfg.mixer_card); + aud_cfg_db_get_int(cfgfile, ALSA_CFGID, "buffer_time", &alsa_cfg.buffer_time); + aud_cfg_db_get_int(cfgfile, ALSA_CFGID, "period_time", &alsa_cfg.period_time); + + aud_cfg_db_get_bool(cfgfile, ALSA_CFGID, "debug", &alsa_cfg.debug); + aud_cfg_db_close(cfgfile); + + if (dlopen("libasound.so.2", RTLD_NOW | RTLD_GLOBAL) == NULL) + { + g_message("Cannot load alsa library: %s", dlerror()); + /* FIXME, this plugin wont work... */ + } +} + + +static OutputPlugin alsa_op = { .description = "ALSA Output Plugin", .init = alsa_init, @@ -43,16 +98,3 @@ OutputPlugin *alsa_oplist[] = { &alsa_op, NULL }; DECLARE_PLUGIN(alsa, NULL, NULL, NULL, alsa_oplist, NULL, NULL, NULL, NULL) - -void alsa_cleanup(void) -{ - if (alsa_cfg.pcm_device) { - free(alsa_cfg.pcm_device); - alsa_cfg.pcm_device = NULL; - } - - if (alsa_cfg.mixer_device) { - free(alsa_cfg.mixer_device); - alsa_cfg.mixer_device = NULL; - } -}
--- a/src/alsa/alsa.h Sun May 25 21:29:07 2008 +0300 +++ b/src/alsa/alsa.h Sun May 25 21:29:48 2008 +0300 @@ -35,11 +35,7 @@ #include <gtk/gtk.h> -#ifdef WORDS_BIGENDIAN -# define IS_BIG_ENDIAN TRUE -#else -# define IS_BIG_ENDIAN FALSE -#endif +#define ALSA_CFGID "ALSA" extern OutputPlugin op; @@ -59,8 +55,6 @@ extern struct alsa_config alsa_cfg; -void alsa_init(void); -void alsa_cleanup(void); void alsa_about(void); void alsa_configure(void); int alsa_get_mixer(snd_mixer_t **mixer, int card);
--- a/src/alsa/audio.c Sun May 25 21:29:07 2008 +0300 +++ b/src/alsa/audio.c Sun May 25 21:29:48 2008 +0300 @@ -68,8 +68,6 @@ static int prebuffer_size; GStaticMutex alsa_mutex = G_STATIC_MUTEX_INIT; -static guint mixer_timeout; - struct snd_format { unsigned int rate; unsigned int channels; @@ -463,20 +461,6 @@ return 0; } -static int alsa_mixer_timeout(void *data) -{ - if (mixer) - { - snd_mixer_close(mixer); - mixer = NULL; - pcm_element = NULL; - } - mixer_timeout = 0; - mixer_start = TRUE; - - return FALSE; -} - static void alsa_cleanup_mixer(void) { pcm_element = NULL; @@ -510,10 +494,6 @@ &lr); *l = ll; *r = lr; - - if (mixer_timeout) - gtk_timeout_remove(mixer_timeout); - mixer_timeout = gtk_timeout_add(5000, alsa_mixer_timeout, NULL); }
--- a/src/alsa/configure.c Sun May 25 21:29:07 2008 +0300 +++ b/src/alsa/configure.c Sun May 25 21:29:48 2008 +0300 @@ -48,13 +48,13 @@ { mcs_handle_t *cfgfile = aud_cfg_db_open(); - aud_cfg_db_set_int(cfgfile, "ALSA", "buffer_time", alsa_cfg.buffer_time); - aud_cfg_db_set_int(cfgfile, "ALSA", "period_time", alsa_cfg.period_time); - aud_cfg_db_set_string(cfgfile,"ALSA","pcm_device", alsa_cfg.pcm_device); - aud_cfg_db_set_int(cfgfile, "ALSA", "mixer_card", alsa_cfg.mixer_card); - aud_cfg_db_set_string(cfgfile,"ALSA","mixer_device", alsa_cfg.mixer_device); - aud_cfg_db_set_int(cfgfile, "ALSA", "volume_left", alsa_cfg.vol.left); - aud_cfg_db_set_int(cfgfile, "ALSA", "volume_right", alsa_cfg.vol.right); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "buffer_time", alsa_cfg.buffer_time); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "period_time", alsa_cfg.period_time); + aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"pcm_device", alsa_cfg.pcm_device); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "mixer_card", alsa_cfg.mixer_card); + aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"mixer_device", alsa_cfg.mixer_device); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "volume_left", alsa_cfg.vol.left); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "volume_right", alsa_cfg.vol.right); aud_cfg_db_close(cfgfile); }
--- a/src/alsa/init.c Sun May 25 21:29:07 2008 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* XMMS - ALSA output plugin - * Copyright (C) 2001-2003 Matthieu Sozeau <mattam@altern.org> - * Copyright (C) 2003-2005 Haavard Kvaalen - * - * 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 <glib.h> -#include "alsa.h" -#include <dlfcn.h> -#include <ctype.h> - -struct alsa_config alsa_cfg; - -void alsa_init(void) -{ - mcs_handle_t *cfgfile; - - memset(&alsa_cfg, 0, sizeof (alsa_cfg)); - alsa_cfg.buffer_time = 500; - alsa_cfg.period_time = 100; - alsa_cfg.debug = 0; - alsa_cfg.vol.left = 100; - alsa_cfg.vol.right = 100; - - cfgfile = aud_cfg_db_open(); - if (!aud_cfg_db_get_string(cfgfile, "ALSA", "pcm_device", - &alsa_cfg.pcm_device)) - alsa_cfg.pcm_device = g_strdup("default"); - g_message("device: %s", alsa_cfg.pcm_device); - if (!aud_cfg_db_get_string(cfgfile, "ALSA", "mixer_device", - &alsa_cfg.mixer_device)) - alsa_cfg.mixer_device = g_strdup("PCM"); - aud_cfg_db_get_int(cfgfile, "ALSA", "mixer_card", &alsa_cfg.mixer_card); - aud_cfg_db_get_int(cfgfile, "ALSA", "buffer_time", &alsa_cfg.buffer_time); - aud_cfg_db_get_int(cfgfile, "ALSA", "period_time", &alsa_cfg.period_time); - - aud_cfg_db_get_bool(cfgfile, "ALSA", "debug", &alsa_cfg.debug); - aud_cfg_db_close(cfgfile); - - if (dlopen("libasound.so.2", RTLD_NOW | RTLD_GLOBAL) == NULL) - { - g_message("Cannot load alsa library: %s", dlerror()); - /* FIXME, this plugin wont work... */ - } -}
--- a/src/modplug/archive/arch_bz2.cxx Sun May 25 21:29:07 2008 +0300 +++ b/src/modplug/archive/arch_bz2.cxx Sun May 25 21:29:48 2008 +0300 @@ -40,7 +40,7 @@ return; } - if(fscanf(f, "%u", &mSize) != 1); // this is the size. + if(fscanf(f, "%u", &mSize) != 1) // this is the size. { mSize = 0; return;
--- a/src/modplug/sndmix.cxx Sun May 25 21:29:07 2008 +0300 +++ b/src/modplug/sndmix.cxx Sun May 25 21:29:48 2008 +0300 @@ -275,75 +275,77 @@ //--------------------------- { if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay) - { + { m_nPatternDelay = 0; m_nFrameDelay = 0; m_nTickCount = 0; m_nRow = m_nNextRow; - // Reset Pattern Loop Effect - if (m_nCurrentPattern != m_nNextPattern) { - if (m_nLockedPattern < MAX_ORDERS) { - m_nCurrentPattern = m_nLockedPattern; - if (!(m_dwSongFlags & SONG_ORDERLOCKED)) - m_nLockedPattern = MAX_ORDERS; - } else { - m_nCurrentPattern = m_nNextPattern; - } - - // Check if pattern is valid - if (!(m_dwSongFlags & SONG_PATTERNLOOP)) + if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern; + // Check if pattern is valid + if (!(m_dwSongFlags & SONG_PATTERNLOOP)) + { + m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; + if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; + while (m_nPattern >= MAX_PATTERNS) { + // End of song ? + if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS)) + { + //if (!m_nRepeatCount) + return FALSE; //never repeat entire song + if (!m_nRestartPos) + { + m_nMusicSpeed = m_nDefaultSpeed; + m_nMusicTempo = m_nDefaultTempo; + m_nGlobalVolume = m_nDefaultGlobalVolume; + for (UINT i=0; i<MAX_CHANNELS; i++) + { + Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; + Chn[i].nFadeOutVol = 0; + if (i < m_nChannels) + { + Chn[i].nGlobalVol = ChnSettings[i].nVolume; + Chn[i].nVolume = ChnSettings[i].nVolume; + Chn[i].nPan = ChnSettings[i].nPan; + Chn[i].nPanSwing = Chn[i].nVolSwing = 0; + Chn[i].nOldVolParam = 0; + Chn[i].nOldOffset = 0; + Chn[i].nOldHiOffset = 0; + Chn[i].nPortamentoDest = 0; + if (!Chn[i].nLength) + { + Chn[i].dwFlags = ChnSettings[i].dwFlags; + Chn[i].nLoopStart = 0; + Chn[i].nLoopEnd = 0; + Chn[i].pHeader = NULL; + Chn[i].pSample = NULL; + Chn[i].pInstrument = NULL; + } + } + } + } +// if (m_nRepeatCount > 0) m_nRepeatCount--; + m_nCurrentPattern = m_nRestartPos; + m_nRow = 0; + if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE; + } else + { + m_nCurrentPattern++; + } m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; - while (m_nPattern >= MAX_PATTERNS) - { - // End of song ? - if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS)) - { - if (m_nRepeatCount > 0) m_nRepeatCount--; - if (!m_nRepeatCount) return FALSE; - m_nCurrentPattern = m_nRestartPos; - if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) - || (!Patterns[Order[m_nCurrentPattern]])) - return FALSE; - } else { - m_nCurrentPattern++; - } - m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF; - if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE; - } - m_nNextPattern = m_nCurrentPattern; - } else if (m_nCurrentPattern < 255) { - if (m_nRepeatCount > 0) m_nRepeatCount--; - if (!m_nRepeatCount) return FALSE; } - } -#ifdef MODPLUG_TRACKER - if (m_dwSongFlags & SONG_STEP) - { - m_dwSongFlags &= ~SONG_STEP; - m_dwSongFlags |= SONG_PAUSED; - } -#endif // MODPLUG_TRACKER - if (!PatternSize[m_nPattern] || !Patterns[m_nPattern]) { - /* okay, this is wrong. allocate the pattern _NOW_ */ - Patterns[m_nPattern] = AllocatePattern(64,64); - PatternSize[m_nPattern] = 64; - PatternAllocSize[m_nPattern] = 64; + m_nNextPattern = m_nCurrentPattern; } // Weird stuff? - if (m_nPattern >= MAX_PATTERNS) return FALSE; + if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern])) return FALSE; // Should never happen - // ... sure it should: suppose there's a C70 effect before a 64-row pattern. - // It's in fact very easy to make this happen ;) - // - chisel if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0; - m_nNextRow = m_nRow + 1; + m_nNextRow = m_nRow + 1; if (m_nNextRow >= PatternSize[m_nPattern]) { if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1; - else if (m_nRepeatCount > 0) return FALSE; m_nNextRow = 0; } // Reset channel values @@ -351,18 +353,7 @@ MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels; for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++) { - /* skip realtime copyin */ - if (pChn->nRealtime) continue; - - // this is where we're going to spit out our midi - // commands... ALL WE DO is dump raw midi data to - // our super-secret "midi buffer" - // -mrsb - if (_midi_out_note) - _midi_out_note(nChn, m); - pChn->nRowNote = m->note; - if (m->instr) pChn->nLastInstr = m->instr; pChn->nRowInstr = m->instr; pChn->nRowVolCmd = m->volcmd; pChn->nRowVolume = m->vol; @@ -374,14 +365,6 @@ pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO); pChn->nCommand = 0; } - - } else if (_midi_out_note) { - MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels; - for (UINT nChn=0; nChn<m_nChannels; nChn++, m++) - { - /* m==NULL allows schism to receive notification of SDx and Scx commands */ - _midi_out_note(nChn, 0); - } } // Should we process tick0 effects? if (!m_nMusicSpeed) m_nMusicSpeed = 1;
--- a/src/neon/neon.c Sun May 25 21:29:07 2008 +0300 +++ b/src/neon/neon.c Sun May 25 21:29:48 2008 +0300 @@ -1300,7 +1300,7 @@ _LEAVE -1; } - if (newpos > content_length) { + if (newpos >= content_length) { _ERROR("<%p> Can not seek beyond end of stream", h); _LEAVE -1; }
--- a/src/sid/xs_config.c Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_config.c Sun May 25 21:29:48 2008 +0300 @@ -84,9 +84,9 @@ * Configuration specific stuff */ XS_MUTEX(xs_cfg); -struct t_xs_cfg xs_cfg; +struct xs_cfg_t xs_cfg; -static t_xs_cfg_item xs_cfgtable[] = { +static xs_cfg_item_t xs_cfgtable[] = { { CTYPE_INT, &xs_cfg.audioBitsPerSample, "audioBitsPerSample" }, { CTYPE_INT, &xs_cfg.audioChannels, "audioChannels" }, { CTYPE_INT, &xs_cfg.audioFrequency, "audioFrequency" }, @@ -135,10 +135,10 @@ { CTYPE_INT, &xs_cfg.subAutoMinTime, "subAutoMinTime" }, }; -static const gint xs_cfgtable_max = (sizeof(xs_cfgtable) / sizeof(t_xs_cfg_item)); +static const gint xs_cfgtable_max = (sizeof(xs_cfgtable) / sizeof(xs_cfgtable[0])); -static t_xs_wid_item xs_widtable[] = { +static xs_wid_item_t xs_widtable[] = { { WTYPE_BGROUP, CTYPE_INT, "cfg_res_16bit", &xs_cfg.audioBitsPerSample, XS_RES_16BIT }, { WTYPE_BGROUP, CTYPE_INT, "cfg_res_8bit", &xs_cfg.audioBitsPerSample, XS_RES_8BIT }, { WTYPE_BGROUP, CTYPE_INT, "cfg_chn_mono", &xs_cfg.audioChannels, XS_CHN_MONO }, @@ -199,7 +199,7 @@ { WTYPE_SPIN, CTYPE_INT, "cfg_subauto_mintime", &xs_cfg.subAutoMinTime, 0 }, }; -static const gint xs_widtable_max = (sizeof(xs_widtable) / sizeof(t_xs_wid_item)); +static const gint xs_widtable_max = (sizeof(xs_widtable) / sizeof(xs_widtable[0])); /* Reset/initialize the configuration @@ -304,7 +304,7 @@ */ #define XS_FITEM (4 * 2) -static gboolean xs_filter_load_into(XS_CONFIG_FILE *cfg, gint nFilter, t_xs_sid2_filter *pResult) +static gboolean xs_filter_load_into(XS_CONFIG_FILE *cfg, gint nFilter, xs_sid2_filter_t *pResult) { gchar tmpKey[64], *tmpStr; gint i, j; @@ -339,12 +339,12 @@ } -static t_xs_sid2_filter * xs_filter_load(XS_CONFIG_FILE *cfg, gint nFilter) +static xs_sid2_filter_t * xs_filter_load(XS_CONFIG_FILE *cfg, gint nFilter) { - t_xs_sid2_filter *pResult; + xs_sid2_filter_t *pResult; /* Allocate filter struct */ - if ((pResult = g_malloc0(sizeof(t_xs_sid2_filter))) == NULL) + if ((pResult = g_malloc0(sizeof(xs_sid2_filter_t))) == NULL) return NULL; if (!xs_filter_load_into(cfg, nFilter, pResult)) { @@ -355,7 +355,7 @@ } #if 0 -static gboolean xs_filter_save(XS_CONFIG_FILE *cfg, t_xs_sid2_filter *pFilter, gint nFilter) +static gboolean xs_filter_save(XS_CONFIG_FILE *cfg, xs_sid2_filter_t *pFilter, gint nFilter) { gchar *tmpValue, tmpKey[64]; gint i, j; @@ -402,14 +402,14 @@ return (inLine[*linePos] == sep); } -static gboolean xs_filters_import(const gchar *pcFilename, t_xs_sid2_filter **pFilters, gint *nFilters) +static gboolean xs_filters_import(const gchar *pcFilename, xs_sid2_filter_t **pFilters, gint *nFilters) { FILE *inFile; gchar inLine[XS_BUF_SIZE], tmpStr[XS_BUF_SIZE]; gchar *sectName = NULL; gboolean sectBegin; size_t lineNum, i; - t_xs_sid2_filter *tmpFilter; + xs_sid2_filter_t *tmpFilter; fprintf(stderr, "xs_filters_import(%s)\n", pcFilename); @@ -446,7 +446,7 @@ if (sectBegin) { /* Submit definition */ fprintf(stderr, "filter ends: %s\n", sectName); - if ((tmpFilter = g_malloc0(sizeof(t_xs_sid2_filter))) == NULL) { + if ((tmpFilter = g_malloc0(sizeof(xs_sid2_filter_t))) == NULL) { fprintf(stderr, "could not allocate ..\n"); } else { @@ -478,10 +478,10 @@ } -static gboolean xs_filters_export(const gchar *pcFilename, t_xs_sid2_filter **pFilters, gint nFilters) +static gboolean xs_filters_export(const gchar *pcFilename, xs_sid2_filter_t **pFilters, gint nFilters) { FILE *outFile; - t_xs_sid2_filter *f; + xs_sid2_filter_t *f; gint n; /* Open/create the file */ @@ -575,7 +575,7 @@ xs_filter_load_into(cfg, 0, &xs_cfg.sid2Filter); if (xs_cfg.sid2NFilterPresets > 0) { - xs_cfg.sid2FilterPresets = g_malloc0(xs_cfg.sid2NFilterPresets * sizeof(t_xs_sid2_filter *)); + xs_cfg.sid2FilterPresets = g_malloc0(xs_cfg.sid2NFilterPresets * sizeof(xs_sid2_filter_t *)); if (!xs_cfg.sid2FilterPresets) { xs_error("Allocation of sid2FilterPresets structure failed!\n"); } else { @@ -896,7 +896,7 @@ } -void xs_cfg_sp2_filter_update(XSCurve *curve, t_xs_sid2_filter *f) +void xs_cfg_sp2_filter_update(XSCurve *curve, xs_sid2_filter_t *f) { assert(curve); assert(f);
--- a/src/sid/xs_config.h Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_config.h Sun May 25 21:29:48 2008 +0300 @@ -68,13 +68,14 @@ typedef struct { - t_xs_int_point points[XS_SIDPLAY2_NFPOINTS]; - gint npoints; - gchar *name; -} t_xs_sid2_filter; + gint type; + xs_int_point_t points[XS_SIDPLAY2_NFPOINTS]; + gint npoints; + gchar *name; +} xs_sid2_filter_t; -extern struct t_xs_cfg { +extern struct xs_cfg_t { /* General audio settings */ gint audioBitsPerSample; gint audioChannels; @@ -99,8 +100,8 @@ gint sid2OptLevel; /* SIDPlay2 emulation optimization */ gint sid2Builder; /* SIDPlay2 "builder" aka SID-emu */ - t_xs_sid2_filter sid2Filter; /* Current SIDPlay2 filter */ - t_xs_sid2_filter **sid2FilterPresets; + xs_sid2_filter_t sid2Filter; /* Current SIDPlay2 filter */ + xs_sid2_filter_t **sid2FilterPresets; gint sid2NFilterPresets; @@ -158,7 +159,7 @@ gint itemType; /* Type of item (CTYPE_*) */ void *itemData; /* Pointer to variable */ gchar *itemName; /* Name of configuration item */ -} t_xs_cfg_item; +} xs_cfg_item_t; typedef struct { @@ -167,7 +168,7 @@ gchar *widName; void *itemData; gint itemSet; -} t_xs_wid_item; +} xs_wid_item_t; /* Functions
--- a/src/sid/xs_curve.c Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_curve.c Sun May 25 21:29:48 2008 +0300 @@ -252,7 +252,7 @@ GtkStateType state; GtkStyle *style; gint i, ox = -1, oy = -1; - t_xs_point *p0, *p1, *p2, *p3; + xs_point_t *p0, *p1, *p2, *p3; if (!curve->pixmap) return; @@ -624,7 +624,7 @@ { if (npoints != curve->nctlpoints) { curve->nctlpoints = npoints; - curve->ctlpoints = (t_xs_point *) g_realloc(curve->ctlpoints, + curve->ctlpoints = (xs_point_t *) g_realloc(curve->ctlpoints, curve->nctlpoints * sizeof(*curve->ctlpoints)); if (curve->ctlpoints == NULL) @@ -635,14 +635,14 @@ } -void xs_curve_get_data(XSCurve *curve, t_xs_point ***points, gint **npoints) +void xs_curve_get_data(XSCurve *curve, xs_point_t ***points, gint **npoints) { *points = &(curve->ctlpoints); *npoints = &(curve->nctlpoints); } -gboolean xs_curve_set_points(XSCurve *curve, t_xs_int_point *points, gint npoints) +gboolean xs_curve_set_points(XSCurve *curve, xs_int_point_t *points, gint npoints) { gint i; @@ -669,13 +669,13 @@ } -gboolean xs_curve_get_points(XSCurve *curve, t_xs_int_point **points, gint *npoints) +gboolean xs_curve_get_points(XSCurve *curve, xs_int_point_t **points, gint *npoints) { gint i, n; n = curve->nctlpoints - 4; - *points = g_malloc(n * sizeof(t_xs_int_point)); + *points = g_malloc(n * sizeof(xs_int_point_t)); if (*points == NULL) return FALSE;
--- a/src/sid/xs_curve.h Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_curve.h Sun May 25 21:29:48 2008 +0300 @@ -8,12 +8,12 @@ /* Macros for type-classing this GtkWidget/object */ -#define XS_TYPE_CURVE (xs_curve_get_type()) -#define XS_CURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XS_TYPE_CURVE, XSCurve)) -#define XS_CURVE_CLASS(luokka) (G_TYPE_CHECK_CLASS_CAST ((luokka), XS_TYPE_CURVE, XSCurveClass)) -#define XS_IS_CURVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XS_TYPE_CURVE)) -#define XS_IS_CURVE_CLASS(luokka) (G_TYPE_CHECK_CLASS_TYPE ((luokka), XS_TYPE_CURVE)) -#define XS_CURVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XS_TYPE_CURVE, XSCurveClass)) +#define XS_TYPE_CURVE (xs_curve_get_type()) +#define XS_CURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XS_TYPE_CURVE, XSCurve)) +#define XS_CURVE_CLASS(luokka) (G_TYPE_CHECK_CLASS_CAST ((luokka), XS_TYPE_CURVE, XSCurveClass)) +#define XS_IS_CURVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XS_TYPE_CURVE)) +#define XS_IS_CURVE_CLASS(luokka) (G_TYPE_CHECK_CLASS_TYPE ((luokka), XS_TYPE_CURVE)) +#define XS_CURVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XS_TYPE_CURVE, XSCurveClass)) /* Structures @@ -23,11 +23,11 @@ typedef struct { gfloat x,y; -} t_xs_point; +} xs_point_t; typedef struct { gint x, y; -} t_xs_int_point; +} xs_int_point_t; struct _XSCurve { GtkDrawingArea graph; @@ -42,7 +42,7 @@ /* control points */ gint nctlpoints; /* number of control points */ - t_xs_point *ctlpoints; /* array of control points */ + xs_point_t *ctlpoints; /* array of control points */ }; struct _XSCurveClass { @@ -57,9 +57,9 @@ gfloat min_x, gfloat min_y, gfloat max_x, gfloat max_y); gboolean xs_curve_realloc_data (XSCurve *curve, gint npoints); -void xs_curve_get_data (XSCurve *curve, t_xs_point ***points, gint **npoints); -gboolean xs_curve_set_points (XSCurve *curve, t_xs_int_point *points, gint npoints); -gboolean xs_curve_get_points (XSCurve *curve, t_xs_int_point **points, gint *npoints); +void xs_curve_get_data (XSCurve *curve, xs_point_t ***points, gint **npoints); +gboolean xs_curve_set_points (XSCurve *curve, xs_int_point_t *points, gint npoints); +gboolean xs_curve_get_points (XSCurve *curve, xs_int_point_t **points, gint *npoints); G_END_DECLS
--- a/src/sid/xs_sidplay1.cc Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_sidplay1.cc Sun May 25 21:29:48 2008 +0300 @@ -52,11 +52,11 @@ /* Return song information */ -#define TFUNCTION xs_sidplay1_getinfo -#define TFUNCTION2 xs_sidplay1_updateinfo -#define TTUNEINFO sidTuneInfo -#define TTUNE sidTune -#define TENGINE xs_sidplay1_t +#define TFUNCTION xs_sidplay1_getinfo +#define TFUNCTION2 xs_sidplay1_updateinfo +#define TTUNEINFO sidTuneInfo +#define TTUNE sidTune +#define TENGINE xs_sidplay1_t #include "xs_sidplay.h"
--- a/src/sid/xs_sidplay2.cc Sun May 25 21:29:07 2008 +0300 +++ b/src/sid/xs_sidplay2.cc Sun May 25 21:29:48 2008 +0300 @@ -30,22 +30,50 @@ #include <sidplay/sidplay2.h> -#ifdef HAVE_RESID_BUILDER -#include <sidplay/builders/resid.h> -#endif -#ifdef HAVE_HARDSID_BUILDER -#include <sidplay/builders/hardsid.h> +#ifdef HAVE_SIDPLAY2_COMI +# include <sidplay/sidlazyiptr.h> #endif -typedef struct { +class xs_sidplay2_t { +public: +#ifdef HAVE_SIDPLAY2_COMI + SidIPtr<ISidplay2> currEng; + SidLazyIPtr<ISidUnknown> currBuilder; +#else sidplay2 *currEng; sidbuilder *currBuilder; +#endif sid2_config_t currConfig; SidTune *currTune; guint8 *buf; size_t bufSize; -} xs_sidplay2_t; + + xs_sidplay2_t(void); + virtual ~xs_sidplay2_t(void) { ; } +}; + + +#ifdef HAVE_RESID_BUILDER +# include <sidplay/builders/resid.h> +#endif +#ifdef HAVE_HARDSID_BUILDER +# include <sidplay/builders/hardsid.h> +#endif + + +xs_sidplay2_t::xs_sidplay2_t(void) +#ifdef HAVE_SIDPLAY2_COMI +:currEng(sidplay2::create()) +#else +:currEng(NULL) +#endif +{ + buf = NULL; + bufSize = 0; + currTune = NULL; + currBuilder = NULL; +} /* We need to 'export' all this pseudo-C++ crap */ @@ -54,11 +82,11 @@ /* Return song information */ -#define TFUNCTION xs_sidplay2_getinfo -#define TFUNCTION2 xs_sidplay2_updateinfo -#define TTUNEINFO SidTuneInfo -#define TTUNE SidTune -#define TENGINE xs_sidplay2_t +#define TFUNCTION xs_sidplay2_getinfo +#define TFUNCTION2 xs_sidplay2_updateinfo +#define TTUNEINFO SidTuneInfo +#define TTUNE SidTune +#define TENGINE xs_sidplay2_t #include "xs_sidplay.h" @@ -66,7 +94,7 @@ */ gboolean xs_sidplay2_probe(xs_file_t *f) { - gchar tmpBuf[4]; + gchar tmpBuf[5]; if (!f) return FALSE; @@ -87,16 +115,18 @@ gint tmpFreq, i; xs_sidplay2_t *myEngine; sid_filter_t tmpFilter; - t_xs_sid2_filter *f; + xs_sid2_filter_t *f; assert(myStatus); /* Allocate internal structures */ - myEngine = (xs_sidplay2_t *) g_malloc0(sizeof(xs_sidplay2_t)); + myEngine = new xs_sidplay2_t(); myStatus->sidEngine = myEngine; if (!myEngine) return FALSE; /* Initialize the engine */ +#ifndef HAVE_SIDPLAY2_COMI myEngine->currEng = new sidplay2; +#endif if (!myEngine->currEng) { xs_error("[SIDPlay2] Could not initialize emulation engine.\n"); return FALSE; @@ -228,9 +258,16 @@ XSDEBUG("init builder #%i, maxsids=%i\n", xs_cfg.sid2Builder, (myEngine->currEng->info()).maxsids); #ifdef HAVE_RESID_BUILDER if (xs_cfg.sid2Builder == XS_BLD_RESID) { +#ifdef HAVE_SIDPLAY2_COMI + myEngine->currBuilder = ReSIDBuilderCreate(""); + SidLazyIPtr<IReSIDBuilder> rs(myEngine->currBuilder); + if (rs) { + myEngine->currConfig.sidEmulation = rs->iaggregate(); +#else ReSIDBuilder *rs = new ReSIDBuilder("ReSID builder"); myEngine->currBuilder = (sidbuilder *) rs; if (rs) { +#endif /* Builder object created, initialize it */ rs->create((myEngine->currEng->info()).maxsids); if (!*rs) { @@ -244,6 +281,7 @@ return FALSE; } +#ifndef HAVE_SIDPLAY2_DISTORTION // FIXME FIX ME: support other configurable parameters ... // ... WHEN/IF resid-builder+libsidplay2 gets fixed rs->sampling(tmpFreq); @@ -251,6 +289,7 @@ xs_error("reSID->sampling(%d) failed.\n", tmpFreq); return FALSE; } +#endif if (tmpFilter.points > 0) rs->filter((sid_filter_t *) &tmpFilter); @@ -266,9 +305,16 @@ #endif #ifdef HAVE_HARDSID_BUILDER if (xs_cfg.sid2Builder == XS_BLD_HARDSID) { +#ifdef HAVE_SIDPLAY2_COMI + myEngine->currBuilder = HardSIDBuilderCreate(""); + SidLazyIPtr<IHardSIDBuilder> hs(myEngine->currBuilder); + if (hs) { + myEngine->currConfig.sidEmulation = hs->iaggregate(); +#else HardSIDBuilder *hs = new HardSIDBuilder("HardSID builder"); myEngine->currBuilder = (sidbuilder *) hs; if (hs) { +#endif /* Builder object created, initialize it */ hs->create((myEngine->currEng->info()).maxsids); if (!*hs) { @@ -290,8 +336,10 @@ return FALSE; } +#ifndef HAVE_SIDPLAY2_COMI + myEngine->currConfig.sidEmulation = myEngine->currBuilder; XSDEBUG("%s\n", myEngine->currBuilder->credits()); - +#endif /* Clockspeed settings */ switch (xs_cfg.clockSpeed) { @@ -311,7 +359,6 @@ /* Configure rest of the emulation */ - myEngine->currConfig.sidEmulation = myEngine->currBuilder; if (xs_cfg.forceSpeed) { myEngine->currConfig.clockForced = true; @@ -374,14 +421,18 @@ /* Free internals */ if (myEngine->currBuilder) { +#ifndef HAVE_SIDPLAY2_COMI delete myEngine->currBuilder; +#endif myEngine->currBuilder = NULL; } +#ifndef HAVE_SIDPLAY2_COMI if (myEngine->currEng) { delete myEngine->currEng; myEngine->currEng = NULL; } +#endif if (myEngine->currTune) { delete myEngine->currTune; @@ -390,7 +441,7 @@ xs_sidplay2_delete(myStatus); - g_free(myEngine); + delete myEngine; myStatus->sidEngine = NULL; }
--- a/src/skins/Makefile Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/Makefile Sun May 25 21:29:48 2008 +0300 @@ -3,6 +3,7 @@ SRCS = plugin.c \ skins_cfg.c \ pixbuf_effects.c \ + dnd.c \ ui_skin.c \ ui_skinned_window.c \ ui_dock.c \ @@ -18,10 +19,15 @@ ui_skinned_horizontal_slider.c \ ui_skinned_equalizer_graph.c \ ui_skinned_equalizer_slider.c \ + ui_skinned_playlist.c \ + ui_skinned_playlist_slider.c \ ui_main.c \ ui_equalizer.c \ + ui_playlist.c \ ui_main_evlisteners.c \ + ui_playlist_evlisteners.c \ ui_manager.c \ + ui_hints.c \ icons-stock.c include ../../buildsys.mk @@ -29,6 +35,6 @@ plugindir := ${plugindir}/${GENERAL_PLUGIN_DIR} -CFLAGS += ${PLUGIN_CFLAGS} +CFLAGS += ${PLUGIN_CFLAGS} ${BEEP_DEFINES} CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${PANGO_CFLAGS} ${CAIRO_CFLAGS} ${PANGOCAIRO_CFLAGS} ${XRENDER_CFLAGS} ${XCOMPOSITE_CFLAGS} -I../.. -LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${PANGO_LIBS} ${CAIRO_LIBS} ${PANGOCAIRO_LIBS} ${XRENDER_LIBS} ${XCOMPOSITE_LIBS} +LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${PANGO_LIBS} ${CAIRO_LIBS} ${PANGOCAIRO_LIBS} ${XRENDER_LIBS} ${XCOMPOSITE_LIBS} ${MOWGLI_LIBS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/dnd.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,34 @@ +/* Audacious + * Copyright (C) 2005-2007 Audacious development team. + * + * Based on BMP: + * 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#include "dnd.h" + +void +aud_drag_dest_set(GtkWidget *widget) +{ + gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, + aud_drop_types, 5, + GDK_ACTION_COPY | GDK_ACTION_MOVE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/dnd.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,51 @@ +/* Audacious - Cross-platform multimedia player + * Copyright (C) 2005-2007 Audacious development team + * + * Based on BMP: + * 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_DND_H +#define AUDACIOUS_DND_H + +#include <gtk/gtk.h> + +/* Designate dropped data types that we know and care about */ +enum { + BMP_DROP_STRING, + BMP_DROP_PLAINTEXT, + BMP_DROP_URLENCODED, + BMP_DROP_SKIN, + BMP_DROP_FONT +}; + +/* Drag data format listing for gtk_drag_dest_set() */ +static const GtkTargetEntry aud_drop_types[] = { + {"text/plain", 0, BMP_DROP_PLAINTEXT}, + {"text/uri-list", 0, BMP_DROP_URLENCODED}, + {"STRING", 0, BMP_DROP_STRING}, + {"interface/x-winamp-skin", 0, BMP_DROP_SKIN}, + {"application/x-font-ttf", 0, BMP_DROP_FONT}, +}; + +void aud_drag_dest_set(GtkWidget*); + +#endif /* AUDACIOUS_DND_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/images/audacious_eq.xpm Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,93 @@ +/* XPM */ +static char *audacious_eq_icon[] = { +/* columns rows colors chars-per-pixel */ +"48 48 39 1", +" c #e36d45", +". c #e3734d", +"X c #e47650", +"o c #e57a54", +"O c #e57d59", +"+ c #e6805d", +"@ c #e68462", +"# c #e78867", +"$ c #e88665", +"% c #e88866", +"& c #e88b6b", +"* c #e98f70", +"= c #e99274", +"- c #ea9678", +"; c #ea997c", +": c #eb9d82", +"> c #eca086", +", c #eda48b", +"< c #eda88f", +"1 c #eeab93", +"2 c #efae98", +"3 c #efb09a", +"4 c #f0b29c", +"5 c #f0b5a0", +"6 c #f2bba7", +"7 c #f2bca9", +"8 c #f3c5b4", +"9 c #f4c7b8", +"0 c #f4cabb", +"q c #f5cec0", +"w c #f6d6cb", +"e c #f7d8ce", +"r c #f7dad0", +"t c #f8dcd3", +"y c #f8e0d7", +"u c #f9e3db", +"i c #fae6e0", +"p c #fae8e2", +"a c white", +/* pixels */ +"<2211111<<<<,,:,,:::::::::::-=---=====&=&&&=&&&&", +"255544422211111<<<<<<::::::::::----======&&&&&##", +"25554442222111<<,<,,:<:::::::------===&=*&&&%%$&", +"1544442222111<<<<<<:<:<:::::-:----=====&*&&&&%$%", +"2554442221111<<<:<:<::<::::::----=====&=&&%&$%%#", +"154442222111<<,<,,<:<::::-:-----====&&=&&&&&%$@$", +"14422222111<<<,,,:<<:::::::-:----====&&&&&&%%$@%", +"1442222211<<<<,,:<:::::::--:=--===&==&&&&&%%$@@%", +"1442221211<<<,,,,<,:::::-:----=-====&&&&&$$$$@@@", +"124222111<<<,,,,::::::;::-:---===*=&=&&&&&%@@@@#", +"1422211111<<<,,,,:::::;;-:----===&=&&&&&$$$#@@@@", +"12222111<taaaaa4,:::::::---=======&=&&&&%$$@@@+@", +"<222111<<taaaaa4::::::-----=-====&&&&&&&$$#@+@+@", +"<2211111<taaaaa4,::::--::---==**=&&&&&$%$#@@@++@", +"<21211<<<taaaaa3:::::::----====*=&&&&%%%$@@+@+O@", +"<21211<<<taaaaa3::::-:---=====**&&&&&%%$@@@@+++@", +"<111<<<<<taaaaa3::::;;----*-*=&&&&&&#%$$@@@+++O+", +"<111<<<,,raaaaa3:::;;;---*-*==*&&&&&%%$@@@@+++++", +",1111<<,,raaaaa2::;;-----111111&&&&%%$#@@@+++OO+", +"<11<<<<,<raaaaa2;;;;;---:aaaaap&&&%%$$@@@+++OOO+", +",8ppppi8>raaaaa3:;;;--*-;aaaaap&&%&$$$@@++@OOOOO", +",qaaaaa0,raaaaa1;;;----=-aaaaap&&%#$@@@+@+O+OOO+", +",qaaaaa0,raaaaa2;;;---==;aaaaap&&%%$#@@@OO+OOooO", +",qaaaaa0>eaaaaa1;;---===-aaaaap&%%$$@++@++OOOOo+", +",0aaaaa0,eaaaaa1;;----==-aaaaap#&$$#@@+++OOOOooO", +",0aaaaa0>raaaaa1-;--====-aaaaap#:ttttt7++OOooooO", +",qaaaaa0:taaaaa1--;==***-aaaaap$,aaaaaq+OOOooooO", +":0aaaaa9:eaaaaa1-wuuuuu&-aaaaap$,aaaaaq+OOOooo.O", +",0aaaaa0:eaaaaa1-paaaaa==aaaaap$,aaaaaqOOOooo.oO", +":0aaaaa9:eaaaaa1=paaaaa&=aaaaap@,aaaaaqOOOoooo.O", +":qaaaaa9:waaaaa1-paaaaa=-aaaaap@>aaaaaqOoOoooXXO", +":0aaaaa9:waaaaa1=paaaaa&*aaaaap@,aaaaa0O;77777*o", +">0aaaaa9:eaaaaa1=paaaaa&=aaaaap@>aaaaaqO4aaaaa3o", +":0aaaaa8;eaaaaa,-paaaaa&=aaaaai@>aaaaaqo4aaaaa3o", +":0aaaaa8;eaaaaa,=paaaaa&=aaaaap+>aaaaa0O5aaaaa3o", +":9aaaaa9;eaaaaa<*paaaaa&&aaaaai@>aaaaaqo4aaaaa3o", +":0aaaaa8;eaaaaa,&paaaaa&=aaaaap+>aaaaa0o4aaaaa2o", +":9aaaaa8-eaaaaa,=paaaaa%&aaaaau+:aaaaa0o4aaaaa2X", +":9aaaaa8;waaaaa,=paaaaa%=aaaaai+>aaaaa0o4aaaaa2X", +":9aaaaa8-eaaaaa,&paaaaa#&aaaaai+:aaaaa0o4aaaaa3X", +";8aaaaa8-waaaaa,*paaaaa#*aaaaapO:aaaaa0o3aaaaa2X", +";8aaaaa8-waaaaa,*paaaaa#&aaaaaiO:aaaaa0X3aaaaa2.", +";9aaaaa8-waaaaa>&paaaaa@&aaaaaiO:aaaaa0X3aaaaa1o", +";9aaaaa8=eaaaaa,&paaaaa@&aaaaauO:aaaaa0.3aaaaa1.", +";8aaaaa8*waaaaa:&paaaaa@&aaaaauO:aaaaa0.2aaaaa1.", +";8aaaaa8=waaaaa>&paaaaa@&aaaaaiO;aaaaa0.3aaaaa2.", +";;;;;=====***&*&#&###@@+++OOOOOooXoX..... . .", +"---=--====*****&&&&#####@@@@++++OOOOOooooXXX...o" +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/images/audacious_playlist.xpm Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,97 @@ +/* XPM */ +static char *audacious_playlist_icon[] = { +/* columns rows colors chars-per-pixel */ +"48 48 43 1", +" c #e36e45", +". c #e3734c", +"X c #e47650", +"o c #e57a54", +"O c #e57d59", +"+ c #e6815d", +"@ c #e68462", +"# c #e78867", +"$ c #e88665", +"% c #e88866", +"& c #e88b6b", +"* c #e98f70", +"= c #e99273", +"- c #ea9679", +"; c #eb997c", +": c #eb9d82", +"> c #eca086", +", c #eda48b", +"< c #eda88f", +"1 c #eeaa93", +"2 c #efae98", +"3 c #efb09a", +"4 c #f0b29c", +"5 c #f0b5a1", +"6 c #f0b8a5", +"7 c #f1bcaa", +"8 c #f2c0ae", +"9 c #f3c3b3", +"0 c #f4c7b8", +"q c #f4cabb", +"w c #f5cec1", +"e c #f5d1c4", +"r c #f6d5c9", +"t c #f7d8cd", +"y c #f8ddd4", +"u c #f8e0d7", +"i c #f9e3db", +"p c #fae6e0", +"a c #fae8e2", +"s c #fcf0eb", +"d c #fcf4f1", +"f c #fdf9f7", +"g c white", +/* pixels */ +"<22111111<<<<,,,::,:::::;;;;;;----====*=&=&&&&#&", +"2555444423111<<<<<<,,>>>:>:;;;;;---====**&&&&&#&", +"25444424312111<<<,,,,>,>>:::;;;----===&==&&&%%%#", +"1554442222111<<<,,,,,>:::::;;;----=====&&&&&%%%#", +"25544422211111<<,,,,::>::;;;;;---=====**&&&%%%$#", +"19aat22uaaaapppppppppppipppiiipiiiiiu4*&4iuuue$$", +"19ggi22sggggggggggggggggggggggggggggg7*&7ggggp%$", +"10ggi24dggggggggggggggggggggggggggggg7*&7ggggp@#", +"17trq21errreeeeeewwwwwwwqwqqq0qq00000,&&,99993@$", +"1333221111<<<,,,,,>::::;;;;-;--===***&&%##$#$@@@", +"1432211111<<<,,,>>>>:::;;;;---===***&&&&####$@@@", +"<9aar11upaappppppipipiiiiiiiu5===***&&&%2uyyyw+@", +"<0ggu11dggggggggggggggggggggg9=&=&&*&&%%7ggggp@@", +"10ggu11dggggggggggggggggggggg9===&&&&&%%7ggggp+@", +"<39961<6766666665554544442222:&=**&&&#%%=,,>>;O@", +"<11111<<<<<,,>::::::;;----=====&*&&&&%%$@@@@++++", +"<1111<<1<,,>,>::::;;;-;----=*=&&&&&%%%$$@@@+++O@", +"<0ggy<<sgggggggggggggggggggggggggggs%%$$6ggggpO+", +"<9ggy<<sgggggggggggggggggggggggggggs%%$@6ggggpO+", +",9ggy<<sgggggggggggggggggggggggggggs%%$@6ggggiO+", +",2774<,,,,>:>:::;;;----====&&&&&&%%%$$$+@+++OOO+", +",111<<,,>>>>::::;;;---=-===&=&&&%#%%$@@+++++OOO+", +",<<<,,,6665555545444422112111111<#$$@@@@&:>;;-OO", +",9ggy,,fggggggggggggggggggggggggd$$$@@+@6ggggpoO", +",9ggy,:fggggggggggggggggggggggggf$$@@@++6ggggpoO", +",7ggy,,fggggggggggggggggggggggggd$$@@+@+5ggggioO", +"><<,,,:,>::::;;;---=====&&&&&%%%$$@@+@++OOOooooO", +":<,,>,>::::;;;;----====&&=&&&%%%$@@@@OOOOOOooo.O", +":1664,:65535444442121211<11<1<,,,,>>,&+O&:;;;-oO", +",7ggy><gggggggggggggggggggggggggggggg6OO5ggggp.O", +":6ggu:,gggggggggggggggggggggggggggggg3OO5ggggi.o", +":5ppe:,ippiiiiiiiiiuiiuiuuuuuuyyyyuyy1Oo<yyyy0Xo", +">,,:::::::;;----====&&&&&%%%$$@@++++OOOOoooXXX.o", +":,,::::::;;;;--=-==***&%&&&%%$@@@+++OOOooooo.X.o", +":1ww9:<qqqqqq000000000099,%%@@@@+++OOoOo-76662.o", +":6ggy:1gggggggggggggggggg7$$@@@+++OOOOoo4ggggi.o", +":6ggy:2gggggggggggggggggg6%@@@++++OOOOoo4ggggi.X", +":2ppw:1iiiiiiiiuuiuiuuuiu2@@@@+++OOOoooo,yyyy0.o", +";::::;;;;--======&=&&&%%%$$@+@+++OOOoooo.X.... X", +";,::;;;;----=====&&&&%#$$$@@@+++OOOoOoo.o... ..X", +";1wq7;1qqq0q0000900999999979979777777;oo-66661 o", +";5ggy;5gggggggggggggggggggggggggggggg3..3ggggi .", +";5ggy;6gggggggggggggggggggggggggggggg2o.3ggggi X", +"-1wq7;<q0q000000099999979779777777777-X.=66561 .", +";;;:=;-====**=&&&&#%#$@@@@+++OOOOoooo..o.... .", +";;;;;;=-====*&&&&&#%$$@@++++OOOOooooo..... .", +";;;-;-====***&*&&###$@@@++O+OOOooo.o.... .. .", +"----=-======&=&&&#&##$$$@@@@+++OOOOOOoooo.o....o" +};
--- a/src/skins/plugin.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/plugin.c Sun May 25 21:29:48 2008 +0300 @@ -25,6 +25,8 @@ #include "ui_skinned_window.h" #include "ui_manager.h" #include "icons-stock.h" +#include "ui_main_evlisteners.h" +#include "ui_playlist_evlisteners.h" #include <audacious/i18n.h> #include <libintl.h> @@ -57,17 +59,27 @@ init_skins(config.skin); - mainwin_real_show(); + if (config.player_visible) mainwin_real_show(); + if (config.equalizer_visible) equalizerwin_show(TRUE); + if (config.playlist_visible) playlistwin_show(); return; } void skins_cleanup(void) { if (plugin_is_active == TRUE) { + skins_cfg_save(); + ui_main_evlistener_dissociate(); + ui_playlist_evlistener_dissociate(); skins_cfg_free(); gtk_widget_destroy(mainwin); - skin_free(aud_active_skin); + gtk_widget_destroy(equalizerwin); + skin_destroy(aud_active_skin); aud_active_skin = NULL; + mainwin = NULL; + equalizerwin = NULL; + playlistwin = NULL; + mainwin_info = NULL; plugin_is_active = FALSE; }
--- a/src/skins/plugin.h Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/plugin.h Sun May 25 21:29:48 2008 +0300 @@ -24,10 +24,12 @@ #include <glib.h> #include <audacious/plugin.h> #include "skins_cfg.h" +#include "ui_main.h" +#include "ui_equalizer.h" +#include "ui_playlist.h" +#include "ui_skin.h" #define PACKAGE_NAME "audacious-plugins" -#define DATA_DIR "/usr/local/share/audacious/" -extern GtkWidget *mainwin; void skins_init(void); void skins_cleanup(void);
--- a/src/skins/skins_cfg.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/skins_cfg.c Sun May 25 21:29:48 2008 +0300 @@ -22,6 +22,8 @@ #include "skins_cfg.h" #include "ui_skin.h" #include "ui_vis.h" +#include "ui_main.h" +#include "ui_playlist.h" #include <glib.h> #include <stdlib.h> #include <audacious/plugin.h> @@ -35,7 +37,10 @@ .sticky = FALSE, .scale_factor = 2.0, .always_show_cb = TRUE, + .close_dialog_open = TRUE, + .close_dialog_add = TRUE, .skin = NULL, + .filesel_path = NULL, .playlist_visible = FALSE, .equalizer_visible = FALSE, .player_visible = TRUE, @@ -78,6 +83,13 @@ .twoway_scroll = TRUE, /* use back and forth scroll */ .mainwin_use_bitmapfont = TRUE, .eq_scaled_linked = TRUE, + .use_xmms_style_fileselector = FALSE, + .show_numbers_in_pl = TRUE, + .show_separator_in_pl = TRUE, + .playlist_font = NULL, + .mainwin_font = NULL, + .show_filepopup_for_tuple = TRUE, + .filepopup_delay = 20, /* delay until the filepopup comes up */ }; typedef struct skins_cfg_boolent_t { @@ -112,6 +124,9 @@ {"warn_about_broken_gtk_engines", &config.warn_about_broken_gtk_engines, TRUE}, {"mainwin_use_bitmapfont", &config.mainwin_use_bitmapfont, TRUE}, {"eq_scaled_linked", &config.eq_scaled_linked, TRUE}, + {"show_numbers_in_pl", &config.show_numbers_in_pl, TRUE}, + {"show_separator_in_pl", &config.show_separator_in_pl, TRUE}, + {"show_filepopup_for_tuple", &config.show_filepopup_for_tuple, TRUE}, }; static gint ncfgbent = G_N_ELEMENTS(skins_boolents); @@ -148,42 +163,64 @@ {"colorize_g", &config.colorize_g, TRUE}, {"colorize_b", &config.colorize_b, TRUE}, {"snap_distance", &config.snap_distance, TRUE}, + {"filepopup_delay", &config.filepopup_delay, TRUE}, }; static gint ncfgient = G_N_ELEMENTS(skins_numents); +typedef struct skins_cfg_strent_t { + char const *se_vname; + char **se_vloc; + gboolean se_wrt; +} skins_cfg_strent; + +static skins_cfg_strent skins_strents[] = { + {"playlist_font", &config.playlist_font, TRUE}, + {"mainwin_font", &config.mainwin_font, TRUE}, + {"skin", &config.skin, FALSE}, +}; + +static gint ncfgsent = G_N_ELEMENTS(skins_strents); + void skins_cfg_free() { - if (config.skin) { g_free(config.skin); config.skin = NULL; } + gint i; + for (i = 0; i < ncfgsent; ++i) { + if (*(skins_strents[i].se_vloc) != NULL) { + g_free( *(skins_strents[i].se_vloc) ); + *(skins_strents[i].se_vloc) = NULL; + } + } } void skins_cfg_load() { mcs_handle_t *cfgfile = aud_cfg_db_open(); - /* if (!aud_cfg_db_get_int(cfgfile, "skins", "field_name", &(cfg->where))) - cfg->where = default value - if (!aud_cfg_db_get_string(cfgfile, "skins", "field_name", &(cfg->where))) - cfg->where = g_strdup("defaul"); - if (!aud_cfg_db_get_bool(cfgfile, "skins", "field_name", &(cfg->where))) - cfg->where = FALSE / TRUE; - */ - memcpy(&config, &skins_default_config, sizeof(skins_cfg_t)); int i; - + for (i = 0; i < ncfgbent; ++i) { aud_cfg_db_get_bool(cfgfile, "skins", skins_boolents[i].be_vname, skins_boolents[i].be_vloc); } - + for (i = 0; i < ncfgient; ++i) { aud_cfg_db_get_int(cfgfile, "skins", skins_numents[i].ie_vname, skins_numents[i].ie_vloc); } - if (!aud_cfg_db_get_string(cfgfile, "skins", "skin", &(config.skin))) - config.skin = g_strdup(BMP_DEFAULT_SKIN_PATH); + for (i = 0; i < ncfgsent; ++i) { + aud_cfg_db_get_string(cfgfile, "skins", + skins_strents[i].se_vname, + skins_strents[i].se_vloc); + } + + if (!config.mainwin_font) + config.mainwin_font = g_strdup(MAINWIN_DEFAULT_FONT); + + if (!config.playlist_font) + config.playlist_font = g_strdup(PLAYLISTWIN_DEFAULT_FONT); if (!aud_cfg_db_get_float(cfgfile, "skins", "scale_factor", &(config.scale_factor))) config.scale_factor = 2.0; @@ -192,18 +229,25 @@ } -void skins_cfg_save(skins_cfg_t * cfg) { +void skins_cfg_save() { mcs_handle_t *cfgfile = aud_cfg_db_open(); -/* - aud_cfg_db_set_int(cfgfile, "skins", "field_name", cfg->where); - aud_cfg_db_set_string(cfgfile, "skins", "field_name", cfg->where); - aud_cfg_db_set_bool(cfgfile, "skins", "field_name", cfg->where); -*/ - aud_cfg_db_set_string(cfgfile, "skins", "skin", cfg->skin); + if (aud_active_skin != NULL) { + if (aud_active_skin->path) + aud_cfg_db_set_string(cfgfile, "skins", "skin", aud_active_skin->path); + else + aud_cfg_db_unset_key(cfgfile, "skins", "skin"); + } int i; + for (i = 0; i < ncfgsent; ++i) { + if (skins_strents[i].se_wrt) + aud_cfg_db_set_string(cfgfile, "skins", + skins_strents[i].se_vname, + *skins_strents[i].se_vloc); + } + for (i = 0; i < ncfgbent; ++i) if (skins_boolents[i].be_wrt) aud_cfg_db_set_bool(cfgfile, "skins",
--- a/src/skins/skins_cfg.h Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/skins_cfg.h Sun May 25 21:29:48 2008 +0300 @@ -44,7 +44,10 @@ gboolean always_on_top, sticky; gfloat scale_factor; gboolean always_show_cb; + gboolean close_dialog_open; + gboolean close_dialog_add; gchar *skin; + gchar *filesel_path; gboolean player_visible, equalizer_visible, playlist_visible; gboolean player_shaded, equalizer_shaded, playlist_shaded; gboolean dim_titlebar; @@ -69,6 +72,11 @@ gboolean warn_about_broken_gtk_engines; gboolean mainwin_use_bitmapfont; gboolean eq_scaled_linked; + gboolean use_xmms_style_fileselector; + gboolean show_numbers_in_pl, show_separator_in_pl; + gchar *playlist_font, *mainwin_font; + gboolean show_filepopup_for_tuple; + gint filepopup_delay; } skins_cfg_t; extern skins_cfg_t config;
--- a/src/skins/ui_equalizer.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_equalizer.c Sun May 25 21:29:48 2008 +0300 @@ -184,14 +184,8 @@ aud_cfg->equalizer_preamp = ui_skinned_equalizer_slider_get_position(equalizerwin_preamp); for (i = 0; i < 10; i++) aud_cfg->equalizer_bands[i] = ui_skinned_equalizer_slider_get_position(equalizerwin_bands[i]); - /* um .. i think we need both of these for xmms compatibility .. - not sure. -larne */ -#if 0 - input_set_eq(aud_cfg->equalizer_active, aud_cfg->equalizer_preamp, - aud_cfg->equalizer_bands); - output_set_eq(aud_cfg->equalizer_active, aud_cfg->equalizer_preamp, - aud_cfg->equalizer_bands); -#endif + + aud_hook_call("equalizer changed", NULL); gtk_widget_queue_draw(equalizerwin_graph); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_hints.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,59 @@ +/* Audacious - Cross-platform multimedia player + * Copyright (C) 2005-2007 Audacious development team + * + * Based on BMP: + * 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#include "ui_hints.h" + +#include <glib.h> +#include <gtk/gtk.h> + +#include "ui_equalizer.h" +#include "ui_main.h" +#include "ui_playlist.h" + +#include "platform/smartinclude.h" + +void +hint_set_always(gboolean always) +{ + gtk_window_set_keep_above(GTK_WINDOW(mainwin), always); + gtk_window_set_keep_above(GTK_WINDOW(equalizerwin), always); + gtk_window_set_keep_above(GTK_WINDOW(playlistwin), always); +} + +void +hint_set_sticky(gboolean sticky) +{ + if (sticky) { + gtk_window_stick(GTK_WINDOW(mainwin)); + gtk_window_stick(GTK_WINDOW(equalizerwin)); + gtk_window_stick(GTK_WINDOW(playlistwin)); + } + else { + gtk_window_unstick(GTK_WINDOW(mainwin)); + gtk_window_unstick(GTK_WINDOW(equalizerwin)); + gtk_window_unstick(GTK_WINDOW(playlistwin)); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_hints.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,35 @@ +/* Audacious - Cross-platform multimedia player + * Copyright (C) 2005-2007 Audacious development team + * + * Based on BMP: + * 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_UI_HINTS_H +#define AUDACIOUS_UI_HINTS_H + +#include <glib.h> +#include <gtk/gtk.h> + +void hint_set_always(gboolean always); +void hint_set_sticky(gboolean sticky); + +#endif /* AUDACIOUS_UI_HINTS_H */
--- a/src/skins/ui_main.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_main.c Sun May 25 21:29:48 2008 +0300 @@ -54,24 +54,19 @@ #include "actions-mainwin.h" #include "ui_manager.h" #include "ui_equalizer.h" +#include "ui_playlist.h" +#include "ui_hints.h" +#include "dnd.h" #if 0 #include "configdb.h" -#include "dnd.h" #include "input.h" #include "main.h" #include "playback.h" #include "playlist.h" #include "pluginenum.h" #include "strings.h" -#include "ui_credits.h" #include "ui_dock.h" -#include "ui_fileinfo.h" -#include "ui_fileopener.h" -#include "ui_hints.h" -#include "ui_jumptotrack.h" #include "ui_main_evlisteners.h" -#include "ui_playlist.h" -#include "ui_preferences.h" #include "ui_skinselector.h" #include "ui_urlopener.h" #include "util.h" @@ -85,9 +80,7 @@ #include "ui_skinned_menurow.h" #include "ui_skinned_playstatus.h" #include "ui_skinned_monostereo.h" -#if 0 #include "ui_skinned_playlist.h" -#endif #include <audacious/plugin.h> #include "skins_cfg.h" @@ -352,7 +345,11 @@ static void mainwin_destroy(GtkWidget * widget, gpointer data) { +/* we should detect whether plugin got unloaded and when user indeed + wants to close audacious */ +#if 0 mainwin_quit_cb(); +#endif } static gchar *mainwin_tb_old_text = NULL; @@ -621,13 +618,10 @@ gint frequency, gint n_channels) { -#if 0 gchar *text; gchar *title; Playlist *playlist = aud_playlist_get_active(); - playback_set_sample_params(bitrate, frequency, n_channels); - GDK_THREADS_ENTER(); if (bitrate != -1) { bitrate /= 1000; @@ -672,26 +666,25 @@ g_free(text); } - title = playlist_get_info_text(playlist); + title = aud_playlist_get_info_text(playlist); mainwin_set_song_title(title); g_free(title); GDK_THREADS_LEAVE(); -#endif } void mainwin_clear_song_info(void) { -#if 0 if (!mainwin) return; /* clear title */ mainwin_set_song_title(NULL); +#if 0 /* clear sampling parameters */ playback_set_sample_params(0, 0, 0); - +#endif UI_SKINNED_HORIZONTAL_SLIDER(mainwin_position)->pressed = FALSE; UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed = FALSE; @@ -706,7 +699,7 @@ mainwin_refresh_visible(); playlistwin_hide_timer(); -#endif + ui_vis_clear_data(mainwin_vis); ui_svis_clear_data(mainwin_svis); } @@ -877,9 +870,7 @@ aud_playlist_next(playlist); break; case GDK_KP_Insert: -#if 0 - ui_jump_to_track(); -#endif + audacious_drct_jtf_show(); break; case GDK_Return: case GDK_KP_Enter: @@ -893,20 +884,18 @@ mainwin_minimize_cb(); break; case GDK_Tab: -#if 0 if (event->state & GDK_CONTROL_MASK) { if (config.equalizer_visible) gtk_window_present(GTK_WINDOW(equalizerwin)); else if (config.playlist_visible) gtk_window_present(GTK_WINDOW(playlistwin)); } -#endif break; case GDK_c: if (event->state & GDK_CONTROL_MASK) { Playlist *playlist = aud_playlist_get_active(); - gint pos = playlist_get_position(playlist); - gchar *title = playlist_get_songtitle(playlist, pos); + gint pos = aud_playlist_get_position(playlist); + gchar *title = aud_playlist_get_songtitle(playlist, pos); if (title != NULL) { GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); @@ -1010,16 +999,15 @@ /* FIXME: Disable display of current track length. It's not updated when track changes */ -#if 0 + label = gtk_label_new(_("Track length:")); gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 5); - len = aud_playlist_get_current_length() / 1000; + gint len = aud_playlist_get_current_length(aud_playlist_get_active()) / 1000; g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", len / 60, len % 60); label = gtk_label_new(time_str); gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 10); -#endif bbox = gtk_hbutton_box_new(); gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 0); @@ -1070,12 +1058,11 @@ guint time, gpointer user_data) { -#if 0 Playlist *playlist = aud_playlist_get_active(); g_return_if_fail(selection_data != NULL); g_return_if_fail(selection_data->data != NULL); - +#if 0 if (aud_str_has_prefix_nocase((gchar *) selection_data->data, "fonts:///")) { gchar *path = (gchar *) selection_data->data; @@ -1084,8 +1071,8 @@ if (decoded == NULL) return; - aud_cfg->playlist_font = g_strconcat(decoded, strrchr(aud_cfg->playlist_font, ' '), NULL); - ui_skinned_playlist_set_font(aud_cfg->playlist_font); + config.playlist_font = g_strconcat(decoded, strrchr(config.playlist_font, ' '), NULL); + ui_skinned_playlist_set_font(config.playlist_font); playlistwin_update_list(playlist); g_free(decoded); @@ -1101,11 +1088,10 @@ return; } } - +#endif aud_playlist_clear(playlist); aud_playlist_add_url(playlist, (gchar *) selection_data->data); - playback_initiate(); -#endif + audacious_drct_initiate(); } static void @@ -1122,15 +1108,14 @@ GtkWidget * entry) { Playlist *playlist = aud_playlist_get_active(); -#if 0 + const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); if (text && *text) { aud_playlist_clear(playlist); aud_playlist_add_url(playlist, text); - playback_initiate(); + audacious_drct_initiate(); } -#endif } static void @@ -1294,9 +1279,7 @@ void mainwin_eject_pushed(void) { -#if 0 - run_filebrowser(PLAY_BUTTON); -#endif + action_play_file(); } void @@ -1392,24 +1375,19 @@ audacious_drct_pause(); return; } -#if 0 - if (playlist_get_length(aud_playlist_get_active())) - playback_initiate(); + + if (aud_playlist_get_length(aud_playlist_get_active())) + audacious_drct_initiate(); else mainwin_eject_pushed(); -#endif } void mainwin_stop_pushed(void) { -#if 0 - ip_data.stop = TRUE; audacious_drct_stop(); mainwin_clear_song_info(); ab_position_a = ab_position_b = -1; - ip_data.stop = FALSE; -#endif } void @@ -1425,9 +1403,7 @@ void mainwin_repeat_pushed(gboolean toggled) { -#if 0 check_set( toggleaction_group_others , "playback repeat" , toggled ); -#endif } void mainwin_repeat_pushed_cb(void) { @@ -1451,12 +1427,10 @@ void mainwin_pl_pushed(gboolean toggled) { -#if 0 if (toggled) playlistwin_show(); else playlistwin_hide(); -#endif } gint @@ -1729,18 +1703,14 @@ mainwin_set_stopaftersong(gboolean stop) { aud_cfg->stopaftersong = stop; -#if 0 check_set(toggleaction_group_others, "stop after current song", aud_cfg->stopaftersong); -#endif } void mainwin_set_noplaylistadvance(gboolean no_advance) { aud_cfg->no_playlist_advance = no_advance; -#if 0 check_set(toggleaction_group_others, "playback no playlist advance", aud_cfg->no_playlist_advance); -#endif } static void @@ -1789,21 +1759,22 @@ Playlist *playlist = aud_playlist_get_active(); switch (action) { -#if 0 case MAINWIN_GENERAL_PREFS: - show_prefs_window(); + action_preferences(); break; case MAINWIN_GENERAL_ABOUT: - show_about_window(); + action_about_audacious(); break; - case MAINWIN_GENERAL_PLAYFILE: - run_filebrowser(NO_PLAY_BUTTON); + case MAINWIN_GENERAL_PLAYFILE: { + gboolean button = FALSE; /* FALSE = NO_PLAY_BUTTON */ + aud_hook_call("filebrowser show", &button); break; + } case MAINWIN_GENERAL_PLAYLOCATION: mainwin_show_add_url_window(); break; case MAINWIN_GENERAL_FILEINFO: - ui_fileinfo_show_current(playlist); + aud_playlist_fileinfo_current(playlist); break; case MAINWIN_GENERAL_FOCUSPLWIN: gtk_window_present(GTK_WINDOW(playlistwin)); @@ -1817,14 +1788,12 @@ else playlistwin_hide(); break; -#endif case MAINWIN_GENERAL_SHOWEQWIN: if (GTK_CHECK_MENU_ITEM(item)->active) equalizerwin_real_show(); else equalizerwin_real_hide(); break; - case MAINWIN_GENERAL_PREV: aud_playlist_prev(playlist); break; @@ -1859,9 +1828,7 @@ mainwin_jump_to_time(); break; case MAINWIN_GENERAL_JTF: -#if 0 - ui_jump_to_track(); -#endif + audacious_drct_jtf_show(); break; case MAINWIN_GENERAL_EXIT: mainwin_quit_cb(); @@ -1952,9 +1919,7 @@ UI_SKINNED_MENUROW(mainwin_menurow)->always_selected ); break; case MENUROW_FILEINFOBOX: -#if 0 - ui_fileinfo_show_current(aud_playlist_get_active()); -#endif + aud_playlist_fileinfo_current(aud_playlist_get_active()); break; case MENUROW_SCALE: gtk_toggle_action_set_active( @@ -2236,9 +2201,7 @@ } static void mainwin_info_double_clicked_cb(void) { -#if 0 - ui_fileinfo_show_current(aud_playlist_get_active()); -#endif + aud_playlist_fileinfo_current(aud_playlist_get_active()); } static void @@ -2352,7 +2315,7 @@ mainwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 27, 153, 1, SKIN_TEXT); ui_skinned_textbox_set_scroll(mainwin_info, config.autoscroll); - ui_skinned_textbox_set_xfont(mainwin_info, !config.mainwin_use_bitmapfont, aud_cfg->mainwin_font); + ui_skinned_textbox_set_xfont(mainwin_info, !config.mainwin_use_bitmapfont, config.mainwin_font); g_signal_connect(mainwin_info, "double-clicked", mainwin_info_double_clicked_cb, NULL); g_signal_connect(mainwin_info, "right-clicked", G_CALLBACK(mainwin_info_right_clicked_cb), NULL); @@ -2399,9 +2362,8 @@ mainwin_about = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_about, SKINNED_WINDOW(mainwin)->fixed, 247, 83, 20, 25); -#if 0 - g_signal_connect(mainwin_about, "clicked", show_about_window, NULL); -#endif + g_signal_connect(mainwin_about, "clicked", G_CALLBACK(action_about_audacious), NULL); + mainwin_vis = ui_vis_new(SKINNED_WINDOW(mainwin)->fixed, 24, 43, 76); g_signal_connect(mainwin_vis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL); mainwin_svis = ui_svis_new(SKINNED_WINDOW(mainwin)->fixed, 79, 5); @@ -2424,12 +2386,6 @@ mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 147, 4, 10, FALSE, SKIN_TEXT); g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); - - - aud_hook_associate("playback audio error", (void *) mainwin_stop_pushed, NULL); - aud_hook_associate("playback audio error", (void *) run_no_output_device_dialog, NULL); - - aud_hook_associate("playback seek", (HookFunction) mainwin_update_song_info, NULL); } static void @@ -2462,12 +2418,12 @@ G_CALLBACK(mainwin_scrolled), NULL); g_signal_connect(mainwin, "button_release_event", G_CALLBACK(mainwin_mouse_button_release), NULL); -#if 0 + aud_drag_dest_set(mainwin); g_signal_connect(mainwin, "key_press_event", G_CALLBACK(mainwin_keypress), NULL); -#endif + ui_main_evlistener_init(); } @@ -2497,9 +2453,9 @@ if (length == -1 && config.timer_mode == TIMER_REMAINING) config.timer_mode = TIMER_ELAPSED; -#if 0 + playlistwin_set_time(time, length, config.timer_mode); -#endif + if (config.timer_mode == TIMER_REMAINING) { if (length != -1) { ui_skinned_number_set_number(mainwin_minus_num, 11); @@ -2616,9 +2572,7 @@ action_autoscroll_songname( GtkToggleAction * action ) { mainwin_set_title_scroll(gtk_toggle_action_get_active(action)); -#if 0 playlistwin_set_sinfo_scroll(config.autoscroll); /* propagate scroll setting to playlistwin_sinfo */ -#endif } void @@ -2656,9 +2610,7 @@ UI_SKINNED_MENUROW(mainwin_menurow)->always_selected = gtk_toggle_action_get_active( action ); config.always_on_top = UI_SKINNED_MENUROW(mainwin_menurow)->always_selected; gtk_widget_queue_draw(mainwin_menurow); -#if 0 hint_set_always(config.always_on_top); -#endif } void @@ -2679,10 +2631,8 @@ void action_view_on_all_workspaces( GtkToggleAction * action ) { -#if 0 config.sticky = gtk_toggle_action_get_active( action ); hint_set_sticky(config.sticky); -#endif } void @@ -2700,9 +2650,7 @@ void action_roll_up_playlist_editor( GtkToggleAction * action ) { -#if 0 playlistwin_set_shade(gtk_toggle_action_get_active(action)); -#endif } void @@ -2717,12 +2665,10 @@ void action_show_playlist_editor( GtkToggleAction * action ) { -#if 0 if (gtk_toggle_action_get_active(action)) playlistwin_show(); else playlistwin_hide(); -#endif } void @@ -2800,17 +2746,15 @@ void action_about_audacious( void ) { -#if 0 - show_about_window(); -#endif + gboolean show = TRUE; + aud_hook_call("aboutwin show", &show); } void action_play_file( void ) { -#if 0 - run_filebrowser(PLAY_BUTTON); -#endif + gboolean button = TRUE; /* TRUE = PLAY_BUTTON */ + aud_hook_call("filebrowser show", &button); } void @@ -2861,17 +2805,13 @@ void action_current_track_info( void ) { -#if 0 - ui_fileinfo_show_current(aud_playlist_get_active()); -#endif + aud_playlist_fileinfo_current(aud_playlist_get_active()); } void action_jump_to_file( void ) { -#if 0 - ui_jump_to_track(); -#endif + audacious_drct_jtf_show(); } void @@ -2922,9 +2862,8 @@ void action_preferences( void ) { -#if 0 - show_prefs_window(); -#endif + gboolean show = TRUE; + aud_hook_call("prefswin show", &show); } void
--- a/src/skins/ui_main.h Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_main.h Sun May 25 21:29:48 2008 +0300 @@ -98,7 +98,6 @@ extern gboolean mainwin_moving; extern gboolean mainwin_focus; -extern GtkWidget *mainwin_jtf; extern GtkWidget *mainwin_eq, *mainwin_pl; extern GtkWidget *mainwin_info; @@ -172,6 +171,7 @@ guint time, gpointer user_data); +void run_no_output_device_dialog(gpointer hook_data, gpointer user_data); void mainwin_setup_menus(void); gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event);
--- a/src/skins/ui_main_evlisteners.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_main_evlisteners.c Sun May 25 21:29:48 2008 +0300 @@ -32,13 +32,11 @@ #include <audacious/plugin.h> #if 0 #include "ui_credits.h" +#endif #include "ui_equalizer.h" -#include "ui_fileopener.h" -#include "ui_jumptotrack.h" -#endif #include "ui_main.h" +#include "ui_playlist.h" #if 0 -#include "ui_playlist.h" #include "ui_preferences.h" #endif #include "ui_skinned_playstatus.h" @@ -49,6 +47,12 @@ static gint song_info_timeout_source = 0; static gint update_vis_timeout_source = 0; +typedef struct { + gint bitrate; + gint samplerate; + gint channels; +} PlaylistEventInfoChange; + /* XXX: there has to be a better way than polling here! */ /* also: where should this function go? should it stay here? --mf0102 */ static gboolean @@ -68,10 +72,7 @@ gchar *text = (gchar *) hook_data; ui_skinned_textbox_set_text(mainwin_info, text); -#if 0 - playlistwin_update_list(playlist_get_active()); -#endif - g_free(text); + playlistwin_update_list(aud_playlist_get_active()); } static void @@ -97,36 +98,17 @@ b = 0; mainwin_set_volume_slider(v); -#if 0 equalizerwin_set_volume_slider(v); -#endif mainwin_set_balance_slider(b); -#if 0 equalizerwin_set_balance_slider(b); -#endif -} - -static void -ui_main_evlistener_playback_initiate(gpointer hook_data, gpointer user_data) -{ -#if 0 - playback_initiate(); -#endif } static void ui_main_evlistener_playback_begin(gpointer hook_data, gpointer user_data) { - PlaylistEntry *entry = (PlaylistEntry*)hook_data; g_return_if_fail(entry != NULL); -#if 0 - equalizerwin_load_auto_preset(entry->filename); - input_set_eq(cfg.equalizer_active, cfg.equalizer_preamp, - cfg.equalizer_bands); - output_set_eq(cfg.equalizer_active, cfg.equalizer_preamp, - cfg.equalizer_bands); -#endif + ui_vis_clear_data(mainwin_vis); ui_svis_clear_data(mainwin_svis); mainwin_disable_seekbar(); @@ -201,22 +183,17 @@ ui_main_evlistener_playlist_end_reached(gpointer hook_data, gpointer user_data) { mainwin_clear_song_info(); -#if 0 - if (cfg.stopaftersong) + + if (aud_cfg->stopaftersong) mainwin_set_stopaftersong(FALSE); -#endif } static void ui_main_evlistener_playlist_info_change(gpointer hook_data, gpointer user_data) { -#if 0 PlaylistEventInfoChange *msg = (PlaylistEventInfoChange *) hook_data; mainwin_set_song_info(msg->bitrate, msg->samplerate, msg->channels); - - g_free(msg); -#endif } static void @@ -236,64 +213,8 @@ static void ui_main_evlistener_equalizerwin_show(gpointer hook_data, gpointer user_data) { -#if 0 gboolean *show = (gboolean*)hook_data; equalizerwin_show(*show); -#endif -} - -static void -ui_main_evlistener_prefswin_show(gpointer hook_data, gpointer user_data) -{ -#if 0 - gboolean *show = (gboolean*)hook_data; - if (*show == TRUE) - show_prefs_window(); - else - hide_prefs_window(); -#endif -} - -static void -ui_main_evlistener_aboutwin_show(gpointer hook_data, gpointer user_data) -{ -#if 0 - gboolean *show = (gboolean*)hook_data; - if (*show == TRUE) - show_about_window(); - else - hide_about_window(); -#endif -} - - -static void -ui_main_evlistener_ui_jump_to_track_show(gpointer hook_data, gpointer user_data) -{ -#if 0 - gboolean *show = (gboolean*)hook_data; - if (*show == TRUE) - ui_jump_to_track(); - else - ui_jump_to_track_hide(); -#endif -} - -static void -ui_main_evlistener_filebrowser_show(gpointer hook_data, gpointer user_data) -{ -#if 0 - gboolean *play_button = (gboolean*)hook_data; - run_filebrowser(*play_button); -#endif -} - -static void -ui_main_evlistener_filebrowser_hide(gpointer hook_data, gpointer user_data) -{ -#if 0 - hide_filebrowser(); -#endif } static void @@ -324,31 +245,56 @@ void ui_main_evlistener_init(void) { -#if 0 aud_hook_associate("title change", ui_main_evlistener_title_change, NULL); aud_hook_associate("hide seekbar", ui_main_evlistener_hide_seekbar, NULL); aud_hook_associate("volume set", ui_main_evlistener_volume_change, NULL); - aud_hook_associate("playback initiate", ui_main_evlistener_playback_initiate, NULL); -#endif aud_hook_associate("playback begin", ui_main_evlistener_playback_begin, NULL); aud_hook_associate("playback stop", ui_main_evlistener_playback_stop, NULL); aud_hook_associate("playback pause", ui_main_evlistener_playback_pause, NULL); aud_hook_associate("playback unpause", ui_main_evlistener_playback_unpause, NULL); aud_hook_associate("playback seek", ui_main_evlistener_playback_seek, NULL); -#if 0 aud_hook_associate("playback play file", ui_main_evlistener_playback_play_file, NULL); aud_hook_associate("playlist end reached", ui_main_evlistener_playlist_end_reached, NULL); aud_hook_associate("playlist info change", ui_main_evlistener_playlist_info_change, NULL); aud_hook_associate("mainwin set always on top", ui_main_evlistener_mainwin_set_always_on_top, NULL); aud_hook_associate("mainwin show", ui_main_evlistener_mainwin_show, NULL); aud_hook_associate("equalizerwin show", ui_main_evlistener_equalizerwin_show, NULL); - aud_hook_associate("prefswin show", ui_main_evlistener_prefswin_show, NULL); - aud_hook_associate("aboutwin show", ui_main_evlistener_aboutwin_show, NULL); - aud_hook_associate("ui jump to track show", ui_main_evlistener_ui_jump_to_track_show, NULL); - aud_hook_associate("filebrowser show", ui_main_evlistener_filebrowser_show, NULL); - aud_hook_associate("filebrowser hide", ui_main_evlistener_filebrowser_hide, NULL); -#endif aud_hook_associate("visualization timeout", ui_main_evlistener_visualization_timeout, NULL); aud_hook_associate("config save", ui_main_evlistener_config_save, NULL); + + aud_hook_associate("playback audio error", (void *) mainwin_stop_pushed, NULL); + aud_hook_associate("playback audio error", (void *) run_no_output_device_dialog, NULL); + + aud_hook_associate("playback seek", (HookFunction) mainwin_update_song_info, NULL); } +void +ui_main_evlistener_dissociate(void) +{ + aud_hook_dissociate("title change", ui_main_evlistener_title_change); + aud_hook_dissociate("hide seekbar", ui_main_evlistener_hide_seekbar); + aud_hook_dissociate("volume set", ui_main_evlistener_volume_change); + aud_hook_dissociate("playback begin", ui_main_evlistener_playback_begin); + aud_hook_dissociate("playback stop", ui_main_evlistener_playback_stop); + aud_hook_dissociate("playback pause", ui_main_evlistener_playback_pause); + aud_hook_dissociate("playback unpause", ui_main_evlistener_playback_unpause); + aud_hook_dissociate("playback seek", ui_main_evlistener_playback_seek); + aud_hook_dissociate("playback play file", ui_main_evlistener_playback_play_file); + aud_hook_dissociate("playlist end reached", ui_main_evlistener_playlist_end_reached); + aud_hook_dissociate("playlist info change", ui_main_evlistener_playlist_info_change); + aud_hook_dissociate("mainwin set always on top", ui_main_evlistener_mainwin_set_always_on_top); + aud_hook_dissociate("mainwin show", ui_main_evlistener_mainwin_show); + aud_hook_dissociate("equalizerwin show", ui_main_evlistener_equalizerwin_show); +#if 0 + aud_hook_dissociate("prefswin show", ui_main_evlistener_prefswin_show); + aud_hook_dissociate("aboutwin show", ui_main_evlistener_aboutwin_show); + aud_hook_dissociate("ui jump to track show", ui_main_evlistener_ui_jump_to_track_show); +#endif + aud_hook_dissociate("visualization timeout", ui_main_evlistener_visualization_timeout); + aud_hook_dissociate("config save", ui_main_evlistener_config_save); + + aud_hook_dissociate("playback audio error", (void *) mainwin_stop_pushed); + aud_hook_dissociate("playback audio error", (void *) run_no_output_device_dialog); + + aud_hook_dissociate("playback seek", (HookFunction) mainwin_update_song_info); +}
--- a/src/skins/ui_main_evlisteners.h Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_main_evlisteners.h Sun May 25 21:29:48 2008 +0300 @@ -24,5 +24,6 @@ #define AUDACIOUS_UI_MAIN_EVLISTENERS_H void ui_main_evlistener_init(void); +void ui_main_evlistener_dissociate(void); #endif /* AUDACIOUS_UI_MAIN_EVLISTENERS_H */
--- a/src/skins/ui_manager.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_manager.c Sun May 25 21:29:48 2008 +0300 @@ -202,7 +202,7 @@ { "anafoff", NULL, N_("Analyzer Falloff") }, { "peafoff", NULL, N_("Peaks Falloff") } }; -#if 0 + static GtkActionEntry action_entries_playlist[] = { { "playlist", NULL, N_("Playlist") }, @@ -376,7 +376,7 @@ N_("Sorts the list by playlist entry."), G_CALLBACK(action_playlist_sort_selected_by_playlist_entry) }, }; -#endif + static GtkActionEntry action_entries_others[] = { { "dummy", NULL, "dummy" }, @@ -559,17 +559,17 @@ gtk_action_group_add_actions( action_group_playback , action_entries_playback , G_N_ELEMENTS(action_entries_playback) , NULL ); -#if 0 + action_group_playlist = ui_manager_new_action_group("action_playlist"); gtk_action_group_add_actions( action_group_playlist , action_entries_playlist , G_N_ELEMENTS(action_entries_playlist) , NULL ); -#endif + action_group_visualization = ui_manager_new_action_group("action_visualization"); gtk_action_group_add_actions( action_group_visualization , action_entries_visualization , G_N_ELEMENTS(action_entries_visualization) , NULL ); -#if 0 + action_group_view = ui_manager_new_action_group("action_view"); gtk_action_group_add_actions( action_group_view , action_entries_view , @@ -599,7 +599,7 @@ gtk_action_group_add_actions( action_group_playlist_sort, action_entries_playlist_sort, G_N_ELEMENTS(action_entries_playlist_sort), NULL ); -#endif + action_group_equalizer = ui_manager_new_action_group("action_equalizer"); gtk_action_group_add_actions( action_group_equalizer, action_entries_equalizer,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_playlist.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,1940 @@ +/* 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +/* #define AUD_DEBUG 1 */ + +#include "ui_playlist.h" + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> +#include <string.h> + +#include "platform/smartinclude.h" + +#include <unistd.h> +#include <errno.h> + +#include "actions-playlist.h" +#include "dnd.h" +#if 0 +#include "input.h" +#include "main.h" +#include "playback.h" +#include "playlist.h" +#include "playlist_container.h" +#include "strings.h" +#endif +#include "ui_dock.h" +#include "ui_equalizer.h" +#include "ui_main.h" +#include "ui_manager.h" +#include "ui_playlist_evlisteners.h" +#if 0 +#include "ui_playlist_manager.h" +#endif +#include "util.h" + +#include "ui_skinned_window.h" +#include "ui_skinned_button.h" +#include "ui_skinned_textbox.h" +#include "ui_skinned_playlist_slider.h" +#include "ui_skinned_playlist.h" + +#include "icons-stock.h" +#include "images/audacious_playlist.xpm" + +GtkWidget *playlistwin; + +static GMutex *resize_mutex = NULL; + +static GtkWidget *playlistwin_list = NULL; +static GtkWidget *playlistwin_shade, *playlistwin_close; + +static gboolean playlistwin_hint_flag = FALSE; + +static GtkWidget *playlistwin_slider; +static GtkWidget *playlistwin_time_min, *playlistwin_time_sec; +static GtkWidget *playlistwin_info, *playlistwin_sinfo; +static GtkWidget *playlistwin_srew, *playlistwin_splay; +static GtkWidget *playlistwin_spause, *playlistwin_sstop; +static GtkWidget *playlistwin_sfwd, *playlistwin_seject; +static GtkWidget *playlistwin_sscroll_up, *playlistwin_sscroll_down; + +static void playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, + gpointer other_cbt); +static gboolean playlistwin_select_search_kp_cb(GtkWidget *entry, + GdkEventKey *event, + gpointer searchdlg_win); + +static gboolean playlistwin_resizing = FALSE; +static gint playlistwin_resize_x, playlistwin_resize_y; + +gboolean +playlistwin_is_shaded(void) +{ + return config.playlist_shaded; +} + +gint +playlistwin_get_width(void) +{ + config.playlist_width /= PLAYLISTWIN_WIDTH_SNAP; + config.playlist_width *= PLAYLISTWIN_WIDTH_SNAP; + return config.playlist_width; +} + +gint +playlistwin_get_height_unshaded(void) +{ + config.playlist_height /= PLAYLISTWIN_HEIGHT_SNAP; + config.playlist_height *= PLAYLISTWIN_HEIGHT_SNAP; + return config.playlist_height; +} + +gint +playlistwin_get_height_shaded(void) +{ + return PLAYLISTWIN_SHADED_HEIGHT; +} + +gint +playlistwin_get_height(void) +{ + if (playlistwin_is_shaded()) + return playlistwin_get_height_shaded(); + else + return playlistwin_get_height_unshaded(); +} + +static void +playlistwin_update_info(Playlist *playlist) +{ + g_return_if_fail(playlist != NULL); + + gchar *text, *sel_text, *tot_text; + gulong selection, total; + gboolean selection_more, total_more; + + aud_playlist_get_total_time(playlist, &total, &selection, &total_more, &selection_more); + + if (selection > 0 || (selection == 0 && !selection_more)) { + if (selection > 3600) + sel_text = + g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", selection / 3600, + (selection / 60) % 60, selection % 60, + (selection_more ? "+" : "")); + else + sel_text = + g_strdup_printf("%lu:%-2.2lu%s", selection / 60, + selection % 60, (selection_more ? "+" : "")); + } + else + sel_text = g_strdup("?"); + if (total > 0 || (total == 0 && !total_more)) { + if (total > 3600) + tot_text = + g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", total / 3600, + (total / 60) % 60, total % 60, + total_more ? "+" : ""); + else + tot_text = + g_strdup_printf("%lu:%-2.2lu%s", total / 60, total % 60, + total_more ? "+" : ""); + } + else + tot_text = g_strdup("?"); + text = g_strconcat(sel_text, "/", tot_text, NULL); + ui_skinned_textbox_set_text(playlistwin_info, text ? text : ""); + g_free(text); + g_free(tot_text); + g_free(sel_text); +} + +static void +playlistwin_update_sinfo(Playlist *playlist) +{ + g_return_if_fail(playlist != NULL); + + gchar *posstr, *timestr, *title, *info; + gint pos, time; + + pos = aud_playlist_get_position(playlist); + title = aud_playlist_get_songtitle(playlist, pos); + + if (!title) { + ui_skinned_textbox_set_text(playlistwin_sinfo, ""); + return; + } + + aud_convert_title_text(title); + + time = aud_playlist_get_songtime(playlist, pos); + + if (config.show_numbers_in_pl) + posstr = g_strdup_printf("%d. ", pos + 1); + else + posstr = g_strdup(""); + + if (time != -1) { + timestr = g_strdup_printf(" (%d:%-2.2d)", time / 60000, + (time / 1000) % 60); + } + else + timestr = g_strdup(""); + + info = g_strdup_printf("%s%s%s", posstr, title, timestr); + + g_free(posstr); + g_free(title); + g_free(timestr); + + ui_skinned_textbox_set_text(playlistwin_sinfo, info ? info : ""); + g_free(info); +} + +gboolean +playlistwin_item_visible(gint index) +{ + g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE); + + if (index >= UI_SKINNED_PLAYLIST(playlistwin_list)->first && + index < (UI_SKINNED_PLAYLIST(playlistwin_list)->first + UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible) ) { + return TRUE; + } + return FALSE; +} + +gint +playlistwin_list_get_visible_count(void) +{ + g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1); + + return UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible; +} + +gint +playlistwin_list_get_first(void) +{ + g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1); + + return UI_SKINNED_PLAYLIST(playlistwin_list)->first; +} + +gint +playlistwin_get_toprow(void) +{ + g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1); + + return (UI_SKINNED_PLAYLIST(playlistwin_list)->first); +} + +void +playlistwin_set_toprow(gint toprow) +{ + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) + UI_SKINNED_PLAYLIST(playlistwin_list)->first = toprow; +#if 0 + g_cond_signal(cond_scan); +#endif + playlistwin_update_list(aud_playlist_get_active()); +} + +void +playlistwin_update_list(Playlist *playlist) +{ + /* this can happen early on. just bail gracefully. */ + g_return_if_fail(playlistwin_list); + + playlistwin_update_info(playlist); + playlistwin_update_sinfo(playlist); + gtk_widget_queue_draw(playlistwin_list); + gtk_widget_queue_draw(playlistwin_slider); +} + +static void +playlistwin_set_geometry_hints(gboolean shaded) +{ + GdkGeometry geometry; + GdkWindowHints mask; + + geometry.min_width = PLAYLISTWIN_MIN_WIDTH; + geometry.max_width = G_MAXUINT16; + + geometry.width_inc = PLAYLISTWIN_WIDTH_SNAP; + geometry.height_inc = PLAYLISTWIN_HEIGHT_SNAP; + + if (shaded) { + geometry.min_height = PLAYLISTWIN_SHADED_HEIGHT; + geometry.max_height = PLAYLISTWIN_SHADED_HEIGHT; + geometry.base_height = PLAYLISTWIN_SHADED_HEIGHT; + } + else { + geometry.min_height = PLAYLISTWIN_MIN_HEIGHT; + geometry.max_height = G_MAXUINT16; + } + + mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_RESIZE_INC; + + gtk_window_set_geometry_hints(GTK_WINDOW(playlistwin), + playlistwin, &geometry, mask); +} + +void +playlistwin_set_sinfo_font(gchar *font) +{ + gchar *tmp = NULL, *tmp2 = NULL; + + g_return_if_fail(font); + AUDDBG("Attempt to set font \"%s\"\n", font); + + tmp = g_strdup(font); + g_return_if_fail(tmp); + + *strrchr(tmp, ' ') = '\0'; + tmp2 = g_strdup_printf("%s 8", tmp); + g_return_if_fail(tmp2); + + ui_skinned_textbox_set_xfont(playlistwin_sinfo, !config.mainwin_use_bitmapfont, tmp2); + + g_free(tmp); + g_free(tmp2); +} + +void +playlistwin_set_sinfo_scroll(gboolean scroll) +{ + if(playlistwin_is_shaded()) + ui_skinned_textbox_set_scroll(playlistwin_sinfo, config.autoscroll); + else + ui_skinned_textbox_set_scroll(playlistwin_sinfo, FALSE); +} + +void +playlistwin_set_shade(gboolean shaded) +{ + config.playlist_shaded = shaded; + + if (shaded) { + playlistwin_set_sinfo_font(config.playlist_font); + playlistwin_set_sinfo_scroll(config.autoscroll); + gtk_widget_show(playlistwin_sinfo); + ui_skinned_set_push_button_data(playlistwin_shade, 128, 45, 150, 42); + ui_skinned_set_push_button_data(playlistwin_close, 138, 45, -1, -1); + } + else { + gtk_widget_hide(playlistwin_sinfo); + playlistwin_set_sinfo_scroll(FALSE); + ui_skinned_set_push_button_data(playlistwin_shade, 157, 3, 62, 42); + ui_skinned_set_push_button_data(playlistwin_close, 167, 3, -1, -1); + } + + dock_shade(get_dock_window_list(), GTK_WINDOW(playlistwin), + playlistwin_get_height()); + + playlistwin_set_geometry_hints(config.playlist_shaded); + + gtk_window_resize(GTK_WINDOW(playlistwin), + playlistwin_get_width(), + playlistwin_get_height()); +} + +static void +playlistwin_set_shade_menu(gboolean shaded) +{ + GtkAction *action = gtk_action_group_get_action( + toggleaction_group_others , "roll up playlist editor" ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded ); + + playlistwin_set_shade(shaded); + playlistwin_update_list(aud_playlist_get_active()); +} + +void +playlistwin_shade_toggle(void) +{ + playlistwin_set_shade_menu(!config.playlist_shaded); +} + +static gboolean +playlistwin_release(GtkWidget * widget, + GdkEventButton * event, + gpointer callback_data) +{ + playlistwin_resizing = FALSE; + return FALSE; +} + +void +playlistwin_scroll(gint num) +{ + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) + UI_SKINNED_PLAYLIST(playlistwin_list)->first += num; + playlistwin_update_list(aud_playlist_get_active()); +} + +void +playlistwin_scroll_up_pushed(void) +{ + playlistwin_scroll(-3); +} + +void +playlistwin_scroll_down_pushed(void) +{ + playlistwin_scroll(3); +} + +static void +playlistwin_select_all(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_select_all(playlist, TRUE); + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) { + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = 0; + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = 0; + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_max = aud_playlist_get_length(playlist) - 1; + } + playlistwin_update_list(playlist); +} + +static void +playlistwin_select_none(void) +{ + aud_playlist_select_all(aud_playlist_get_active(), FALSE); + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) { + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1; + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1; + } + playlistwin_update_list(aud_playlist_get_active()); +} + +static void +playlistwin_select_search(void) +{ + Playlist *playlist = aud_playlist_get_active(); + GtkWidget *searchdlg_win, *searchdlg_table; + GtkWidget *searchdlg_hbox, *searchdlg_logo, *searchdlg_helptext; + GtkWidget *searchdlg_entry_title, *searchdlg_label_title; + GtkWidget *searchdlg_entry_album, *searchdlg_label_album; + GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name; + GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer; + GtkWidget *searchdlg_checkbt_clearprevsel; + GtkWidget *searchdlg_checkbt_newplaylist; + GtkWidget *searchdlg_checkbt_autoenqueue; + gint result; + + /* create dialog */ + searchdlg_win = gtk_dialog_new_with_buttons( + _("Search entries in active playlist") , GTK_WINDOW(mainwin) , + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT , + GTK_STOCK_CANCEL , GTK_RESPONSE_REJECT , GTK_STOCK_OK , GTK_RESPONSE_ACCEPT , NULL ); + gtk_window_set_position(GTK_WINDOW(searchdlg_win), GTK_WIN_POS_CENTER); + + /* help text and logo */ + searchdlg_hbox = gtk_hbox_new( FALSE , 4 ); + searchdlg_logo = gtk_image_new_from_stock( GTK_STOCK_FIND , GTK_ICON_SIZE_DIALOG ); + searchdlg_helptext = gtk_label_new( _("Select entries in playlist by filling one or more " + "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how " + "regular expressions work, simply insert a literal portion of what you're searching for.") ); + gtk_label_set_line_wrap( GTK_LABEL(searchdlg_helptext) , TRUE ); + gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_logo , FALSE , FALSE , 0 ); + gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_helptext , FALSE , FALSE , 0 ); + + /* title */ + searchdlg_label_title = gtk_label_new( _("Title: ") ); + searchdlg_entry_title = gtk_entry_new(); + gtk_misc_set_alignment( GTK_MISC(searchdlg_label_title) , 0 , 0.5 ); + g_signal_connect( G_OBJECT(searchdlg_entry_title) , "key-press-event" , + G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win ); + + /* album */ + searchdlg_label_album= gtk_label_new( _("Album: ") ); + searchdlg_entry_album= gtk_entry_new(); + gtk_misc_set_alignment( GTK_MISC(searchdlg_label_album) , 0 , 0.5 ); + g_signal_connect( G_OBJECT(searchdlg_entry_album) , "key-press-event" , + G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win ); + + /* artist */ + searchdlg_label_performer = gtk_label_new( _("Artist: ") ); + searchdlg_entry_performer = gtk_entry_new(); + gtk_misc_set_alignment( GTK_MISC(searchdlg_label_performer) , 0 , 0.5 ); + g_signal_connect( G_OBJECT(searchdlg_entry_performer) , "key-press-event" , + G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win ); + + /* file name */ + searchdlg_label_file_name = gtk_label_new( _("Filename: ") ); + searchdlg_entry_file_name = gtk_entry_new(); + gtk_misc_set_alignment( GTK_MISC(searchdlg_label_file_name) , 0 , 0.5 ); + g_signal_connect( G_OBJECT(searchdlg_entry_file_name) , "key-press-event" , + G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win ); + + /* some options that control behaviour */ + searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label( + _("Clear previous selection before searching") ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE ); + searchdlg_checkbt_autoenqueue = gtk_check_button_new_with_label( + _("Automatically toggle queue for matching entries") ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue) , FALSE ); + searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label( + _("Create a new playlist with matching entries") ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE ); + g_signal_connect( G_OBJECT(searchdlg_checkbt_autoenqueue) , "clicked" , + G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_newplaylist ); + g_signal_connect( G_OBJECT(searchdlg_checkbt_newplaylist) , "clicked" , + G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_autoenqueue ); + + /* place fields in searchdlg_table */ + searchdlg_table = gtk_table_new( 8 , 2 , FALSE ); + gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 0 , 8 ); + gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 4 , 8 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_hbox , + 0 , 2 , 0 , 1 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_title , + 0 , 1 , 1 , 2 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_title , + 1 , 2 , 1 , 2 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_album, + 0 , 1 , 2 , 3 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_album, + 1 , 2 , 2 , 3 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_performer , + 0 , 1 , 3 , 4 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_performer , + 1 , 2 , 3 , 4 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_file_name , + 0 , 1 , 4 , 5 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_file_name , + 1 , 2 , 4 , 5 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_clearprevsel , + 0 , 2 , 5 , 6 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_autoenqueue , + 0 , 2 , 6 , 7 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 ); + gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_newplaylist , + 0 , 2 , 7 , 8 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 ); + + gtk_container_set_border_width( GTK_CONTAINER(searchdlg_table) , 5 ); + gtk_container_add( GTK_CONTAINER(GTK_DIALOG(searchdlg_win)->vbox) , searchdlg_table ); + gtk_widget_show_all( searchdlg_win ); + result = gtk_dialog_run( GTK_DIALOG(searchdlg_win) ); + switch(result) + { + case GTK_RESPONSE_ACCEPT: + { + gint matched_entries_num = 0; + /* create a TitleInput tuple with user search data */ + Tuple *tuple = aud_tuple_new(); + gchar *searchdata = NULL; + + searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) ); + AUDDBG("title=\"%s\"\n", searchdata); + aud_tuple_associate_string(tuple, FIELD_TITLE, NULL, searchdata); + + searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) ); + AUDDBG("album=\"%s\"\n", searchdata); + aud_tuple_associate_string(tuple, FIELD_ALBUM, NULL, searchdata); + + searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) ); + AUDDBG("performer=\"%s\"\n", searchdata); + aud_tuple_associate_string(tuple, FIELD_ARTIST, NULL, searchdata); + + searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) ); + AUDDBG("filename=\"%s\"\n", searchdata); + aud_tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, searchdata); + + /* check if previous selection should be cleared before searching */ + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE ) + playlistwin_select_none(); + /* now send this tuple to the real search function */ + matched_entries_num = aud_playlist_select_search( playlist , tuple , 0 ); + /* we do not need the tuple and its data anymore */ + mowgli_object_unref(tuple); + playlistwin_update_list(aud_playlist_get_active()); + /* check if a new playlist should be created after searching */ + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE ) + aud_playlist_new_from_selected(); + /* check if matched entries should be queued */ + else if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue)) == TRUE ) + aud_playlist_queue(aud_playlist_get_active()); + break; + } + default: + break; + } + /* done here :) */ + gtk_widget_destroy( searchdlg_win ); +} + +static void +playlistwin_inverse_selection(void) +{ + aud_playlist_select_invert_all(aud_playlist_get_active()); + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) { + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1; + UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1; + } + playlistwin_update_list(aud_playlist_get_active()); +} + +static void +playlistwin_resize(gint width, gint height) +{ + gint tx, ty; + gint dx, dy; + + g_return_if_fail(width > 0 && height > 0); + + tx = (width - PLAYLISTWIN_MIN_WIDTH) / PLAYLISTWIN_WIDTH_SNAP; + tx = (tx * PLAYLISTWIN_WIDTH_SNAP) + PLAYLISTWIN_MIN_WIDTH; + if (tx < PLAYLISTWIN_MIN_WIDTH) + tx = PLAYLISTWIN_MIN_WIDTH; + + if (!config.playlist_shaded) + { + ty = (height - PLAYLISTWIN_MIN_HEIGHT) / PLAYLISTWIN_HEIGHT_SNAP; + ty = (ty * PLAYLISTWIN_HEIGHT_SNAP) + PLAYLISTWIN_MIN_HEIGHT; + if (ty < PLAYLISTWIN_MIN_HEIGHT) + ty = PLAYLISTWIN_MIN_HEIGHT; + } + else + ty = config.playlist_height; + + if (tx == config.playlist_width && ty == config.playlist_height) + return; + + /* difference between previous size and new size */ + dx = tx - config.playlist_width; + dy = ty - config.playlist_height; + + config.playlist_width = width = tx; + config.playlist_height = height = ty; + + g_mutex_lock(resize_mutex); + ui_skinned_playlist_resize_relative(playlistwin_list, dx, dy); + + ui_skinned_playlist_slider_move_relative(playlistwin_slider, dx); + ui_skinned_playlist_slider_resize_relative(playlistwin_slider, dy); + + playlistwin_update_sinfo(aud_playlist_get_active()); + + ui_skinned_button_move_relative(playlistwin_shade, dx, 0); + ui_skinned_button_move_relative(playlistwin_close, dx, 0); + ui_skinned_textbox_move_relative(playlistwin_time_min, dx, dy); + ui_skinned_textbox_move_relative(playlistwin_time_sec, dx, dy); + ui_skinned_textbox_move_relative(playlistwin_info, dx, dy); + ui_skinned_button_move_relative(playlistwin_srew, dx, dy); + ui_skinned_button_move_relative(playlistwin_splay, dx, dy); + ui_skinned_button_move_relative(playlistwin_spause, dx, dy); + ui_skinned_button_move_relative(playlistwin_sstop, dx, dy); + ui_skinned_button_move_relative(playlistwin_sfwd, dx, dy); + ui_skinned_button_move_relative(playlistwin_seject, dx, dy); + ui_skinned_button_move_relative(playlistwin_sscroll_up, dx, dy); + ui_skinned_button_move_relative(playlistwin_sscroll_down, dx, dy); + + gtk_widget_set_size_request(playlistwin_sinfo, playlistwin_get_width() - 35, + aud_active_skin->properties.textbox_bitmap_font_height); + GList *iter; + for (iter = GTK_FIXED (SKINNED_WINDOW(playlistwin)->fixed)->children; iter; iter = g_list_next (iter)) { + GtkFixedChild *child_data = (GtkFixedChild *) iter->data; + GtkWidget *child = child_data->widget; + g_signal_emit_by_name(child, "redraw"); + } + g_mutex_unlock(resize_mutex); +} + +static void +playlistwin_motion(GtkWidget * widget, + GdkEventMotion * event, + gpointer callback_data) +{ + GdkEvent *gevent; + + /* + * GDK2's resize is broken and doesn't really play nice, so we have + * to do all of this stuff by hand. + */ + if (playlistwin_resizing == TRUE) + { + if (event->x + playlistwin_resize_x != playlistwin_get_width() || + event->y + playlistwin_resize_y != playlistwin_get_height()) + { + playlistwin_resize(event->x + playlistwin_resize_x, + event->y + playlistwin_resize_y); + gdk_window_resize(playlistwin->window, + config.playlist_width, playlistwin_get_height()); + gdk_flush(); + } + } + else if (dock_is_moving(GTK_WINDOW(playlistwin))) + dock_move_motion(GTK_WINDOW(playlistwin), event); + + while ((gevent = gdk_event_get()) != NULL) gdk_event_free(gevent); +} + +static void +playlistwin_show_filebrowser(void) +{ + action_playlist_add_files(); +} + +static void +playlistwin_fileinfo(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + /* Show the first selected file, or the current file if nothing is + * selected */ + GList *list = aud_playlist_get_selected(playlist); + if (list) { + aud_playlist_fileinfo(playlist, GPOINTER_TO_INT(list->data)); + g_list_free(list); + } + else + aud_playlist_fileinfo_current(playlist); +} + +static void +show_playlist_save_error(GtkWindow *parent, + const gchar *filename) +{ + GtkWidget *dialog; + + g_return_if_fail(GTK_IS_WINDOW(parent)); + g_return_if_fail(filename); + + dialog = gtk_message_dialog_new(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Error writing playlist \"%s\": %s"), + filename, strerror(errno)); + + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */ + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +static gboolean +show_playlist_overwrite_prompt(GtkWindow * parent, + const gchar * filename) +{ + GtkWidget *dialog; + gint result; + + g_return_val_if_fail(GTK_IS_WINDOW(parent), FALSE); + g_return_val_if_fail(filename != NULL, FALSE); + + dialog = gtk_message_dialog_new(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("%s already exist. Continue?"), + filename); + + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */ + result = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + return (result == GTK_RESPONSE_YES); +} + +static void +show_playlist_save_format_error(GtkWindow * parent, + const gchar * filename) +{ + const gchar *markup = + N_("<b><big>Unable to save playlist.</big></b>\n\n" + "Unknown file type for '%s'.\n"); + + GtkWidget *dialog; + + g_return_if_fail(GTK_IS_WINDOW(parent)); + g_return_if_fail(filename != NULL); + + dialog = + gtk_message_dialog_new_with_markup(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _(markup), + filename); + + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */ + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +static void +playlistwin_save_playlist(const gchar * filename) +{ + PlaylistContainer *plc; + gchar *ext = strrchr(filename, '.') + 1; + + plc = aud_playlist_container_find(ext); + if (plc == NULL) { + show_playlist_save_format_error(GTK_WINDOW(playlistwin), filename); + return; + } + + aud_str_replace_in(&aud_cfg->playlist_path, g_path_get_dirname(filename)); + + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + if (!show_playlist_overwrite_prompt(GTK_WINDOW(playlistwin), filename)) + return; + + if (!aud_playlist_save(aud_playlist_get_active(), filename)) + show_playlist_save_error(GTK_WINDOW(playlistwin), filename); +} + +static void +playlistwin_load_playlist(const gchar * filename) +{ + const gchar *title; + Playlist *playlist = aud_playlist_get_active(); + + g_return_if_fail(filename != NULL); + + aud_str_replace_in(&aud_cfg->playlist_path, g_path_get_dirname(filename)); + + aud_playlist_clear(playlist); + mainwin_clear_song_info(); + + aud_playlist_load(playlist, filename); + title = aud_playlist_get_current_name(playlist); + if(!title || !title[0]) + aud_playlist_set_current_name(playlist, filename); +} + +static gchar * +playlist_file_selection_load(const gchar * title, + const gchar * default_filename) +{ + GtkWidget *dialog; + gchar *filename; + + g_return_val_if_fail(title != NULL, NULL); + + dialog = make_filebrowser(title, FALSE); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), aud_cfg->playlist_path); + if (default_filename) + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename); + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */ + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + else + filename = NULL; + + gtk_widget_destroy(dialog); + return filename; +} + +static void +on_static_toggle(GtkToggleButton *button, gpointer data) +{ + Playlist *playlist = aud_playlist_get_active(); + + playlist->attribute = + gtk_toggle_button_get_active(button) ? + playlist->attribute | PLAYLIST_STATIC : + playlist->attribute & ~PLAYLIST_STATIC; +} + +static void +on_relative_toggle(GtkToggleButton *button, gpointer data) +{ + Playlist *playlist = aud_playlist_get_active(); + + playlist->attribute = + gtk_toggle_button_get_active(button) ? + playlist->attribute | PLAYLIST_USE_RELATIVE : + playlist->attribute & ~PLAYLIST_USE_RELATIVE; +} + +static gchar * +playlist_file_selection_save(const gchar * title, + const gchar * default_filename) +{ + GtkWidget *dialog; + gchar *filename; + GtkWidget *hbox; + GtkWidget *toggle, *toggle2; + + g_return_val_if_fail(title != NULL, NULL); + + dialog = make_filebrowser(title, TRUE); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), aud_cfg->playlist_path); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename); + + hbox = gtk_hbox_new(FALSE, 5); + + /* static playlist */ + toggle = gtk_check_button_new_with_label(_("Save as Static Playlist")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), + (aud_playlist_get_active()->attribute & PLAYLIST_STATIC) ? TRUE : FALSE); + g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(on_static_toggle), dialog); + gtk_box_pack_start(GTK_BOX(hbox), toggle, FALSE, FALSE, 0); + + /* use relative path */ + toggle2 = gtk_check_button_new_with_label(_("Use Relative Path")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle2), + (aud_playlist_get_active()->attribute & PLAYLIST_USE_RELATIVE) ? TRUE : FALSE); + g_signal_connect(G_OBJECT(toggle2), "toggled", G_CALLBACK(on_relative_toggle), dialog); + gtk_box_pack_start(GTK_BOX(hbox), toggle2, FALSE, FALSE, 0); + + gtk_widget_show_all(hbox); + gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), hbox); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + else + filename = NULL; + + gtk_widget_destroy(dialog); + return filename; +} + +void +playlistwin_select_playlist_to_load(const gchar * default_filename) +{ + gchar *filename = + playlist_file_selection_load(_("Load Playlist"), default_filename); + + if (filename) { + playlistwin_load_playlist(filename); + g_free(filename); + } +} + +static void +playlistwin_select_playlist_to_save(const gchar * default_filename) +{ + gchar *dot = NULL, *basename = NULL; + gchar *filename = + playlist_file_selection_save(_("Save Playlist"), default_filename); + + if (filename) { + /* Default extension */ + basename = g_path_get_basename(filename); + dot = strrchr(basename, '.'); + if( dot == NULL || dot == basename) { + gchar *oldname = filename; +#ifdef HAVE_XSPF_PLAYLIST + filename = g_strconcat(oldname, ".xspf", NULL); +#else + filename = g_strconcat(oldname, ".m3u", NULL); +#endif + g_free(oldname); + } + g_free(basename); + + playlistwin_save_playlist(filename); + g_free(filename); + } +} + +#define REGION_L(x1,x2,y1,y2) \ + (event->x >= (x1) && event->x < (x2) && \ + event->y >= config.playlist_height - (y1) && \ + event->y < config.playlist_height - (y2)) + +#define REGION_R(x1,x2,y1,y2) \ + (event->x >= playlistwin_get_width() - (x1) && \ + event->x < playlistwin_get_width() - (x2) && \ + event->y >= config.playlist_height - (y1) && \ + event->y < config.playlist_height - (y2)) + +static void +playlistwin_scrolled(GtkWidget * widget, + GdkEventScroll * event, + gpointer callback_data) +{ + if (event->direction == GDK_SCROLL_DOWN) + playlistwin_scroll(config.scroll_pl_by); + + if (event->direction == GDK_SCROLL_UP) + playlistwin_scroll(-config.scroll_pl_by); +#if 0 + g_cond_signal(cond_scan); +#endif +} + +static gboolean +playlistwin_press(GtkWidget * widget, + GdkEventButton * event, + gpointer callback_data) +{ + gint xpos, ypos; + GtkRequisition req; + + gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos); + + if (event->button == 1 && !config.show_wm_decorations && + ((!config.playlist_shaded && + event->x > playlistwin_get_width() - 20 && + event->y > config.playlist_height - 20) || + (config.playlist_shaded && + event->x >= playlistwin_get_width() - 31 && + event->x < playlistwin_get_width() - 22))) { + + if (event->type != GDK_2BUTTON_PRESS && + event->type != GDK_3BUTTON_PRESS) { + playlistwin_resizing = TRUE; + playlistwin_resize_x = config.playlist_width - event->x; + playlistwin_resize_y = config.playlist_height - event->y; + } + } + else if (event->button == 1 && REGION_L(12, 37, 29, 11)) { + /* ADD button menu */ + gtk_widget_size_request(playlistwin_pladd_menu, &req); + ui_manager_popup_menu_show(GTK_MENU(playlistwin_pladd_menu), + xpos + 12, + (ypos + playlistwin_get_height()) - 8 - req.height, + event->button, + event->time); + } + else if (event->button == 1 && REGION_L(41, 66, 29, 11)) { + /* SUB button menu */ + gtk_widget_size_request(playlistwin_pldel_menu, &req); + ui_manager_popup_menu_show(GTK_MENU(playlistwin_pldel_menu), + xpos + 40, + (ypos + playlistwin_get_height()) - 8 - req.height, + event->button, + event->time); + } + else if (event->button == 1 && REGION_L(70, 95, 29, 11)) { + /* SEL button menu */ + gtk_widget_size_request(playlistwin_plsel_menu, &req); + ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsel_menu), + xpos + 68, + (ypos + playlistwin_get_height()) - 8 - req.height, + event->button, + event->time); + } + else if (event->button == 1 && REGION_L(99, 124, 29, 11)) { + /* MISC button menu */ + gtk_widget_size_request(playlistwin_plsort_menu, &req); + ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsort_menu), + xpos + 100, + (ypos + playlistwin_get_height()) - 8 - req.height, + event->button, + event->time); + } + else if (event->button == 1 && REGION_R(46, 23, 29, 11)) { + /* LIST button menu */ + gtk_widget_size_request(playlistwin_pllist_menu, &req); + ui_manager_popup_menu_show(GTK_MENU(playlistwin_pllist_menu), + xpos + playlistwin_get_width() - req.width - 12, + (ypos + playlistwin_get_height()) - 8 - req.height, + event->button, + event->time); + } + else if (event->button == 1 && event->type == GDK_BUTTON_PRESS && + (config.easy_move || event->y < 14)) + { + return FALSE; + } + else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS + && event->y < 14) { + /* double click on title bar */ + playlistwin_shade_toggle(); + if (dock_is_moving(GTK_WINDOW(playlistwin))) + dock_move_release(GTK_WINDOW(playlistwin)); + return TRUE; + } + else if (event->button == 3) { + /* + * Pop up the main menu a few pixels down to avoid + * anything to be selected initially. + */ + ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root, + event->y_root + 2, 3, event->time); + } + + return TRUE; +} + +static gboolean +playlistwin_delete(GtkWidget * w, gpointer data) +{ + playlistwin_hide(); + return TRUE; +} + +static gboolean +playlistwin_keypress_up_down_handler(UiSkinnedPlaylist * pl, + gboolean up, guint state) +{ + Playlist *playlist = aud_playlist_get_active(); + if ((!(pl->prev_selected || pl->first) && up) || + ((pl->prev_selected >= aud_playlist_get_length(playlist) - 1) && !up)) + return FALSE; + + if ((state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK)) + return FALSE; + if (!(state & GDK_MOD1_MASK)) + aud_playlist_select_all(playlist, FALSE); + + if (pl->prev_selected == -1 || + (!playlistwin_item_visible(pl->prev_selected) && + !(state & GDK_SHIFT_MASK && pl->prev_min != -1))) { + pl->prev_selected = pl->first; + } + else if (state & GDK_SHIFT_MASK) { + if (pl->prev_min == -1) { + pl->prev_max = pl->prev_selected; + pl->prev_min = pl->prev_selected; + } + pl->prev_max += (up ? -1 : 1); + pl->prev_max = + CLAMP(pl->prev_max, 0, aud_playlist_get_length(playlist) - 1); + + pl->first = MIN(pl->first, pl->prev_max); + pl->first = MAX(pl->first, pl->prev_max - + pl->num_visible + 1); + aud_playlist_select_range(playlist, pl->prev_min, pl->prev_max, TRUE); + return TRUE; + } + else if (state & GDK_MOD1_MASK) { + if (up) + ui_skinned_playlist_move_up(pl); + else + ui_skinned_playlist_move_down(pl); + if (pl->prev_min < pl->first) + pl->first = pl->prev_min; + else if (pl->prev_max >= (pl->first + pl->num_visible)) + pl->first = pl->prev_max - pl->num_visible + 1; + return TRUE; + } + else if (up) + pl->prev_selected--; + else + pl->prev_selected++; + + pl->prev_selected = + CLAMP(pl->prev_selected, 0, aud_playlist_get_length(playlist) - 1); + + if (pl->prev_selected < pl->first) + pl->first--; + else if (pl->prev_selected >= (pl->first + pl->num_visible)) + pl->first++; + + aud_playlist_select_range(playlist, pl->prev_selected, pl->prev_selected, TRUE); + pl->prev_min = -1; + + return TRUE; +} + +/* FIXME: Handle the keys through menu */ + +static gboolean +playlistwin_keypress(GtkWidget * w, GdkEventKey * event, gpointer data) +{ + g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE); + Playlist *playlist = aud_playlist_get_active(); + + guint keyval; + gboolean refresh = FALSE; + guint cur_pos; + + if (config.playlist_shaded) + return FALSE; + + switch (keyval = event->keyval) { + case GDK_KP_Up: + case GDK_KP_Down: + case GDK_Up: + case GDK_Down: + refresh = playlistwin_keypress_up_down_handler(UI_SKINNED_PLAYLIST(playlistwin_list), + keyval == GDK_Up + || keyval == GDK_KP_Up, + event->state); + break; + case GDK_Page_Up: + playlistwin_scroll(-UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible); + refresh = TRUE; + break; + case GDK_Page_Down: + playlistwin_scroll(UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible); + refresh = TRUE; + break; + case GDK_Home: + UI_SKINNED_PLAYLIST(playlistwin_list)->first = 0; + refresh = TRUE; + break; + case GDK_End: + UI_SKINNED_PLAYLIST(playlistwin_list)->first = + aud_playlist_get_length(playlist) - UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible; + refresh = TRUE; + break; + case GDK_Return: + if (UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected > -1 + && playlistwin_item_visible(UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected)) { + aud_playlist_set_position(playlist, UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected); + if (!audacious_drct_get_playing()) + audacious_drct_initiate(); + } + refresh = TRUE; + break; + case GDK_3: + if (event->state & GDK_CONTROL_MASK) + playlistwin_fileinfo(); + break; + case GDK_Delete: + if (event->state & GDK_CONTROL_MASK) + aud_playlist_delete(playlist, TRUE); + else + aud_playlist_delete(playlist, FALSE); + break; + case GDK_Insert: + if (event->state & GDK_MOD1_MASK) + mainwin_show_add_url_window(); + else + playlistwin_show_filebrowser(); + break; + case GDK_Left: + case GDK_KP_Left: + case GDK_KP_7: + if (aud_playlist_get_current_length(playlist) != -1) + audacious_drct_seek(CLAMP + (audacious_drct_get_time() - 5000, 0, + aud_playlist_get_current_length(playlist))); + break; + case GDK_Right: + case GDK_KP_Right: + case GDK_KP_9: + if (aud_playlist_get_current_length(playlist) != -1) + audacious_drct_seek(CLAMP + (audacious_drct_get_time() + 5000, 0, + aud_playlist_get_current_length(playlist))); + break; + case GDK_KP_4: + aud_playlist_prev(playlist); + break; + case GDK_KP_6: + aud_playlist_next(playlist); + break; + + case GDK_Escape: + mainwin_minimize_cb(); + break; + case GDK_Tab: + if (event->state & GDK_CONTROL_MASK) { + if (config.player_visible) + gtk_window_present(GTK_WINDOW(mainwin)); + else if (config.equalizer_visible) + gtk_window_present(GTK_WINDOW(equalizerwin)); + } + break; + case GDK_space: + cur_pos=aud_playlist_get_position(playlist); + UI_SKINNED_PLAYLIST(playlistwin_list)->first = + cur_pos - (UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible >> 1); + refresh = TRUE; + break; + default: + return FALSE; + } +#if 0 + if (refresh) { + g_cond_signal(cond_scan); + playlistwin_update_list(aud_playlist_get_active()); + } +#endif + return TRUE; +} + +void +playlistwin_hide_timer(void) +{ + ui_skinned_textbox_set_text(playlistwin_time_min, " "); + ui_skinned_textbox_set_text(playlistwin_time_sec, " "); +} + +void +playlistwin_set_time(gint time, gint length, TimerMode mode) +{ + gchar *text, sign; + + if (mode == TIMER_REMAINING && length != -1) { + time = length - time; + sign = '-'; + } + else + sign = ' '; + + time /= 1000; + + if (time < 0) + time = 0; + if (time > 99 * 60) + time /= 60; + + text = g_strdup_printf("%c%-2.2d", sign, time / 60); + ui_skinned_textbox_set_text(playlistwin_time_min, text); + g_free(text); + + text = g_strdup_printf("%-2.2d", time % 60); + ui_skinned_textbox_set_text(playlistwin_time_sec, text); + g_free(text); +} + +static void +playlistwin_drag_motion(GtkWidget * widget, + GdkDragContext * context, + gint x, gint y, + GtkSelectionData * selection_data, + guint info, guint time, gpointer user_data) +{ + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) { + UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = TRUE; + UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_x = x; + UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_y = y; + } + playlistwin_update_list(aud_playlist_get_active()); + playlistwin_hint_flag = TRUE; +} + +static void +playlistwin_drag_end(GtkWidget * widget, + GdkDragContext * context, gpointer user_data) +{ + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) + UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = FALSE; + playlistwin_hint_flag = FALSE; + playlistwin_update_list(aud_playlist_get_active()); +} + +static void +playlistwin_drag_data_received(GtkWidget * widget, + GdkDragContext * context, + gint x, gint y, + GtkSelectionData * + selection_data, guint info, + guint time, gpointer user_data) +{ + gint pos; + Playlist *playlist = aud_playlist_get_active(); + + g_return_if_fail(selection_data); + + if (!selection_data->data) { + g_message("Received no DND data!"); + return; + } + if (UI_SKINNED_IS_PLAYLIST(playlistwin_list) && + (x < playlistwin_get_width() - 20 || y < config.playlist_height - 38)) { + pos = y / UI_SKINNED_PLAYLIST(playlistwin_list)->fheight + UI_SKINNED_PLAYLIST(playlistwin_list)->first; + + pos = MIN(pos, aud_playlist_get_length(playlist)); + aud_playlist_ins_url(playlist, (gchar *) selection_data->data, pos); + } + else + aud_playlist_add_url(playlist, (gchar *) selection_data->data); +} + +static void +local_playlist_prev(void) +{ + aud_playlist_prev(aud_playlist_get_active()); +} + +static void +local_playlist_next(void) +{ + aud_playlist_next(aud_playlist_get_active()); +} + +static void +playlistwin_create_widgets(void) +{ + /* This function creates the custom widgets used by the playlist editor */ + + /* text box for displaying song title in shaded mode */ + playlistwin_sinfo = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, + 4, 4, playlistwin_get_width() - 35, TRUE, SKIN_TEXT); + + playlistwin_set_sinfo_font(config.playlist_font); + + playlistwin_shade = ui_skinned_button_new(); + /* shade/unshade window push button */ + if (config.playlist_shaded) + ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 21, 3, + 9, 9, 128, 45, 150, 42, SKIN_PLEDIT); + else + ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 21, 3, + 9, 9, 157, 3, 62, 42, SKIN_PLEDIT); + + g_signal_connect(playlistwin_shade, "clicked", playlistwin_shade_toggle, NULL ); + + /* close window push button */ + playlistwin_close = ui_skinned_button_new(); + ui_skinned_push_button_setup(playlistwin_close, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 11, 3, 9, 9, + config.playlist_shaded ? 138 : 167, + config.playlist_shaded ? 45 : 3, 52, 42, SKIN_PLEDIT); + + g_signal_connect(playlistwin_close, "clicked", playlistwin_hide, NULL ); + + /* playlist list box */ + playlistwin_list = ui_skinned_playlist_new(SKINNED_WINDOW(playlistwin)->fixed, 12, 20, + playlistwin_get_width() - 31, + config.playlist_height - 58); + ui_skinned_playlist_set_font(config.playlist_font); + + /* playlist list box slider */ + playlistwin_slider = ui_skinned_playlist_slider_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_get_width() - 15, + 20, config.playlist_height - 58); + + /* track time (minute) */ + playlistwin_time_min = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 82, + config.playlist_height - 15, 15, FALSE, SKIN_TEXT); + g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); + + /* track time (second) */ + playlistwin_time_sec = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 64, + config.playlist_height - 15, 10, FALSE, SKIN_TEXT); + g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); + + /* playlist information (current track length / total track length) */ + playlistwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 143, + config.playlist_height - 28, 90, FALSE, SKIN_TEXT); + + /* mini play control buttons at right bottom corner */ + + /* rewind button */ + playlistwin_srew = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_srew, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 144, + config.playlist_height - 16, 8, 7); + g_signal_connect(playlistwin_srew, "clicked", local_playlist_prev, NULL); + + /* play button */ + playlistwin_splay = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_splay, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 138, + config.playlist_height - 16, 10, 7); + g_signal_connect(playlistwin_splay, "clicked", mainwin_play_pushed, NULL); + + /* pause button */ + playlistwin_spause = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_spause, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 128, + config.playlist_height - 16, 10, 7); + g_signal_connect(playlistwin_spause, "clicked", audacious_drct_pause, NULL); + + /* stop button */ + playlistwin_sstop = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_sstop, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 118, + config.playlist_height - 16, 9, 7); + g_signal_connect(playlistwin_sstop, "clicked", mainwin_stop_pushed, NULL); + + /* forward button */ + playlistwin_sfwd = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_sfwd, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 109, + config.playlist_height - 16, 8, 7); + g_signal_connect(playlistwin_sfwd, "clicked", local_playlist_next, NULL); + + /* eject button */ + playlistwin_seject = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_seject, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 100, + config.playlist_height - 16, 9, 7); + g_signal_connect(playlistwin_seject, "clicked", mainwin_eject_pushed, NULL); + + playlistwin_sscroll_up = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_sscroll_up, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 14, + config.playlist_height - 35, 8, 5); + g_signal_connect(playlistwin_sscroll_up, "clicked", playlistwin_scroll_up_pushed, NULL); + + playlistwin_sscroll_down = ui_skinned_button_new(); + ui_skinned_small_button_setup(playlistwin_sscroll_down, SKINNED_WINDOW(playlistwin)->fixed, + playlistwin_get_width() - 14, + config.playlist_height - 30, 8, 5); + g_signal_connect(playlistwin_sscroll_down, "clicked", playlistwin_scroll_down_pushed, NULL); + + ui_playlist_evlistener_init(); +} + +static void +selection_received(GtkWidget * widget, + GtkSelectionData * selection_data, gpointer data) +{ + if (selection_data->type == GDK_SELECTION_TYPE_STRING && + selection_data->length > 0) + aud_playlist_add_url(aud_playlist_get_active(), (gchar *) selection_data->data); +} + +static void +playlistwin_create_window(void) +{ + GdkPixbuf *icon; + + playlistwin = ui_skinned_window_new("playlist"); + gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor")); + gtk_window_set_role(GTK_WINDOW(playlistwin), "playlist"); + gtk_window_set_default_size(GTK_WINDOW(playlistwin), + playlistwin_get_width(), + playlistwin_get_height()); + gtk_window_set_resizable(GTK_WINDOW(playlistwin), TRUE); + playlistwin_set_geometry_hints(config.playlist_shaded); + + gtk_window_set_transient_for(GTK_WINDOW(playlistwin), + GTK_WINDOW(mainwin)); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE); + + icon = gdk_pixbuf_new_from_xpm_data((const gchar **) audacious_playlist_icon); + gtk_window_set_icon(GTK_WINDOW(playlistwin), icon); + g_object_unref(icon); + + if (config.playlist_x != -1 && config.save_window_position) + gtk_window_move(GTK_WINDOW(playlistwin), + config.playlist_x, config.playlist_y); + + gtk_widget_add_events(playlistwin, GDK_POINTER_MOTION_MASK | + GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK); + gtk_widget_realize(playlistwin); + + g_signal_connect(playlistwin, "delete_event", + G_CALLBACK(playlistwin_delete), NULL); + g_signal_connect(playlistwin, "button_press_event", + G_CALLBACK(playlistwin_press), NULL); + g_signal_connect(playlistwin, "button_release_event", + G_CALLBACK(playlistwin_release), NULL); + g_signal_connect(playlistwin, "scroll_event", + G_CALLBACK(playlistwin_scrolled), NULL); + g_signal_connect(playlistwin, "motion_notify_event", + G_CALLBACK(playlistwin_motion), NULL); + + aud_drag_dest_set(playlistwin); + + /* DnD stuff */ + g_signal_connect(playlistwin, "drag-leave", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-data-delete", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-end", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-drop", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-data-received", + G_CALLBACK(playlistwin_drag_data_received), NULL); + g_signal_connect(playlistwin, "drag-motion", + G_CALLBACK(playlistwin_drag_motion), NULL); + + g_signal_connect(playlistwin, "key_press_event", + G_CALLBACK(playlistwin_keypress), NULL); + g_signal_connect(playlistwin, "selection_received", + G_CALLBACK(selection_received), NULL); +} + +void +playlistwin_create(void) +{ + resize_mutex = g_mutex_new(); + playlistwin_create_window(); + + playlistwin_create_widgets(); + playlistwin_update_info(aud_playlist_get_active()); + + gtk_window_add_accel_group(GTK_WINDOW(playlistwin), ui_manager_get_accel_group()); +} + + +void +playlistwin_show(void) +{ + gtk_window_move(GTK_WINDOW(playlistwin), config.playlist_x, config.playlist_y); + GtkAction *action = gtk_action_group_get_action( + toggleaction_group_others , "show playlist editor" ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE ); + + config.playlist_visible = TRUE; + UI_SKINNED_BUTTON(mainwin_pl)->inside = TRUE; + gtk_widget_queue_draw(mainwin_pl); + + playlistwin_set_toprow(0); + aud_playlist_check_pos_current(aud_playlist_get_active()); + + gtk_widget_show_all(playlistwin); + if (!config.playlist_shaded) + gtk_widget_hide(playlistwin_sinfo); + gtk_window_present(GTK_WINDOW(playlistwin)); +} + +void +playlistwin_hide(void) +{ + GtkAction *action = gtk_action_group_get_action( + toggleaction_group_others , "show playlist editor" ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , FALSE ); + + gtk_widget_hide(playlistwin); + config.playlist_visible = FALSE; + UI_SKINNED_BUTTON(mainwin_pl)->inside = FALSE; + gtk_widget_queue_draw(mainwin_pl); + + if ( config.player_visible ) + { + gtk_window_present(GTK_WINDOW(mainwin)); + gtk_widget_grab_focus(mainwin); + } +} + +void action_playlist_track_info(void) +{ + playlistwin_fileinfo(); +} + +void action_queue_toggle(void) +{ + aud_playlist_queue(aud_playlist_get_active()); +} + +void action_playlist_sort_by_playlist_entry(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_PLAYLIST); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_track_number(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_TRACK); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_title(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_TITLE); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_artist(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_ARTIST); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_full_path(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_PATH); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_date(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_DATE); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_by_filename(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort(playlist, PLAYLIST_SORT_FILENAME); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_playlist_entry(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_PLAYLIST); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_track_number(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_TRACK); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_title(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_TITLE); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_artist(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_ARTIST); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_full_path(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_PATH); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_date(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_DATE); + playlistwin_update_list(playlist); +} + +void action_playlist_sort_selected_by_filename(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_sort_selected(playlist, PLAYLIST_SORT_FILENAME); + playlistwin_update_list(playlist); +} + +void action_playlist_randomize_list(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_random(playlist); + playlistwin_update_list(playlist); +} + +void action_playlist_reverse_list(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_reverse(playlist); + playlistwin_update_list(playlist); +} + +void +action_playlist_clear_queue(void) +{ + aud_playlist_clear_queue(aud_playlist_get_active()); +} + +void +action_playlist_remove_unavailable(void) +{ + aud_playlist_remove_dead_files(aud_playlist_get_active()); +} + +void +action_playlist_remove_dupes_by_title(void) +{ + aud_playlist_remove_duplicates(aud_playlist_get_active(), PLAYLIST_DUPS_TITLE); +} + +void +action_playlist_remove_dupes_by_filename(void) +{ + aud_playlist_remove_duplicates(aud_playlist_get_active(), PLAYLIST_DUPS_FILENAME); +} + +void +action_playlist_remove_dupes_by_full_path(void) +{ + aud_playlist_remove_duplicates(aud_playlist_get_active(), PLAYLIST_DUPS_PATH); +} + +void +action_playlist_remove_all(void) +{ + aud_playlist_clear(aud_playlist_get_active()); + + /* XXX -- should this really be coupled here? -nenolod */ + mainwin_clear_song_info(); +} + +void +action_playlist_remove_selected(void) +{ + aud_playlist_delete(aud_playlist_get_active(), FALSE); +} + +void +action_playlist_remove_unselected(void) +{ + aud_playlist_delete(aud_playlist_get_active(), TRUE); +} + +void +action_playlist_add_files(void) +{ + gboolean button = FALSE; /* FALSE = NO_PLAY_BUTTON */ + aud_hook_call("filebrowser show", &button); +} + +void +action_playlist_add_url(void) +{ + mainwin_show_add_url_window(); +} + +void +action_playlist_new( void ) +{ + Playlist *new_pl = aud_playlist_new(); + aud_playlist_add_playlist(new_pl); + aud_playlist_select_playlist(new_pl); +} + +void +action_playlist_prev( void ) +{ + aud_playlist_select_prev(); +} + +void +action_playlist_next( void ) +{ + aud_playlist_select_next(); +} + +void +action_playlist_delete( void ) +{ + aud_playlist_remove_playlist( aud_playlist_get_active() ); +} + +void +action_playlist_save_list(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + playlistwin_select_playlist_to_save(aud_playlist_get_current_name(playlist)); +} + +void +action_playlist_save_default_list(void) +{ +#if 0 + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_save(playlist, aud_paths[BMP_PATH_PLAYLIST_FILE]); +#endif +} + +void +action_playlist_load_list(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + playlistwin_select_playlist_to_load(aud_playlist_get_current_name(playlist)); +} + +void +action_playlist_refresh_list(void) +{ + Playlist *playlist = aud_playlist_get_active(); + + aud_playlist_read_info_selection(playlist); + playlistwin_update_list(playlist); +} + +void +action_open_list_manager(void) +{ +#if 0 + playlist_manager_ui_show(); +#endif +} + +void +action_playlist_search_and_select(void) +{ + playlistwin_select_search(); +} + +void +action_playlist_invert_selection(void) +{ + playlistwin_inverse_selection(); +} + +void +action_playlist_select_none(void) +{ + playlistwin_select_none(); +} + +void +action_playlist_select_all(void) +{ + playlistwin_select_all(); +} + + +static void +playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, gpointer other_cbt) +{ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(called_cbt)) == TRUE) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_cbt), FALSE); + return; +} + +static gboolean +playlistwin_select_search_kp_cb(GtkWidget *entry, GdkEventKey *event, + gpointer searchdlg_win) +{ + switch (event->keyval) + { + case GDK_Return: + if (gtk_im_context_filter_keypress (GTK_ENTRY (entry)->im_context, event)) { + GTK_ENTRY (entry)->need_im_reset = TRUE; + return TRUE; + } else { + gtk_dialog_response(GTK_DIALOG(searchdlg_win), GTK_RESPONSE_ACCEPT); + return TRUE; + } + default: + return FALSE; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_playlist.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,81 @@ +/* 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; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_UI_PLAYLIST_H +#define AUDACIOUS_UI_PLAYLIST_H + +#include <glib.h> + +#include "ui_main.h" +#include <audacious/plugin.h> +#include "skins_cfg.h" + +#define PLAYLISTWIN_FRAME_TOP_HEIGHT 20 +#define PLAYLISTWIN_FRAME_BOTTOM_HEIGHT 38 +#define PLAYLISTWIN_FRAME_LEFT_WIDTH 12 +#define PLAYLISTWIN_FRAME_RIGHT_WIDTH 19 + +#define PLAYLISTWIN_MIN_WIDTH MAINWIN_WIDTH +#define PLAYLISTWIN_MIN_HEIGHT MAINWIN_HEIGHT +#define PLAYLISTWIN_WIDTH_SNAP 25 +#define PLAYLISTWIN_HEIGHT_SNAP 29 +#define PLAYLISTWIN_SHADED_HEIGHT MAINWIN_SHADED_HEIGHT +#define PLAYLISTWIN_WIDTH config.playlist_width +#define PLAYLISTWIN_HEIGHT \ + (config.playlist_shaded ? PLAYLISTWIN_SHADED_HEIGHT : config.playlist_height) + +#define PLAYLISTWIN_DEFAULT_WIDTH 275 +#define PLAYLISTWIN_DEFAULT_HEIGHT 232 +#define PLAYLISTWIN_DEFAULT_POS_X 295 +#define PLAYLISTWIN_DEFAULT_POS_Y 20 + +#define PLAYLISTWIN_DEFAULT_FONT "Sans Bold 8" + +gboolean playlistwin_is_shaded(void); +gint playlistwin_get_width(void); +gint playlistwin_get_height(void); +void playlistwin_update_list(Playlist *playlist); +gboolean playlistwin_item_visible(gint index); +gint playlistwin_get_toprow(void); +void playlistwin_set_toprow(gint top); +void playlistwin_set_shade_menu_cb(gboolean shaded); +void playlistwin_set_shade(gboolean shaded); +void playlistwin_shade_toggle(void); +void playlistwin_create(void); +void playlistwin_hide_timer(void); +void playlistwin_set_time(gint time, gint length, TimerMode mode); +void playlistwin_show(void); +void playlistwin_hide(void); +void playlistwin_scroll(gint num); +void playlistwin_scroll_up_pushed(void); +void playlistwin_scroll_down_pushed(void); +void playlistwin_select_playlist_to_load(const gchar * default_filename); +void playlistwin_set_sinfo_font(gchar *font); +void playlistwin_set_sinfo_scroll(gboolean scroll); +gint playlistwin_list_get_visible_count(void); +gint playlistwin_list_get_first(void); + +extern GtkWidget *playlistwin; + +extern gboolean playlistwin_focus; + +#endif /* AUDACIOUS_UI_PLAYLIST_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_playlist_evlisteners.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,64 @@ +/* + * Audacious + * Copyright (c) 2006-2007 Audacious development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#include "ui_playlist_evlisteners.h" + +#include <glib.h> +#if 0 +#include "hook.h" +#include "playlist.h" +#endif +#include "ui_playlist.h" +#if 0 +#include "ui_playlist_manager.h" +#endif +static void +ui_playlist_evlistener_playlist_update(gpointer hook_data, gpointer user_data) +{ + Playlist *playlist = (Playlist *) hook_data; + if (playlist != NULL) + playlistwin_update_list(playlist); +#if 0 + playlist_manager_update(); +#endif +} + +static void +ui_playlist_evlistener_playlistwin_show(gpointer hook_data, gpointer user_data) +{ + gboolean *show = (gboolean*)hook_data; + if (*show == TRUE) + playlistwin_show(); + else + playlistwin_hide(); +} + +void ui_playlist_evlistener_init(void) +{ + aud_hook_associate("playlist update", ui_playlist_evlistener_playlist_update, NULL); + aud_hook_associate("playlistwin show", ui_playlist_evlistener_playlistwin_show, NULL); +} + +void ui_playlist_evlistener_dissociate(void) +{ + aud_hook_dissociate("playlist update", ui_playlist_evlistener_playlist_update); + aud_hook_dissociate("playlistwin show", ui_playlist_evlistener_playlistwin_show); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_playlist_evlisteners.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,27 @@ +/* + * Audacious + * Copyright (c) 2006-2007 Audacious development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H +#define AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H + +void ui_playlist_evlistener_init(void); +void ui_playlist_evlistener_dissociate(void); + +#endif /* AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H */
--- a/src/skins/ui_skin.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_skin.c Sun May 25 21:29:48 2008 +0300 @@ -42,8 +42,8 @@ #include "util.h" #include "ui_main.h" #include "ui_equalizer.h" +#include "ui_playlist.h" #if 0 -#include "ui_playlist.h" #include "ui_skinselector.h" #endif #include "debug.h" @@ -184,11 +184,10 @@ ui_skinned_window_draw_all(mainwin); ui_skinned_window_draw_all(equalizerwin); -#if 0 ui_skinned_window_draw_all(playlistwin); - playlistwin_update_list(playlist_get_active()); -#endif + playlistwin_update_list(aud_playlist_get_active()); + SkinPixmap *pixmap; pixmap = &aud_active_skin->pixmaps[SKIN_POSBAR]; /* last 59 pixels of SKIN_POSBAR are knobs (normal and selected) */ @@ -407,7 +406,7 @@ pm = &skin->pixmaps[id]; GdkPixbuf *pix = gdk_pixbuf_new_from_file(filename, NULL); - pm->pixbuf = audacious_create_colorized_pixbuf(pix, config.colorize_r, aud_cfg->colorize_g, aud_cfg->colorize_b); + pm->pixbuf = audacious_create_colorized_pixbuf(pix, config.colorize_r, config.colorize_g, config.colorize_b); g_object_unref(pix); pm->width = gdk_pixbuf_get_width(pm->pixbuf); pm->height = gdk_pixbuf_get_height(pm->pixbuf); @@ -535,9 +534,7 @@ { mainwin_create(); equalizerwin_create(); -#if 0 playlistwin_create(); -#endif } if (!aud_active_skin_load(path)) { @@ -1749,7 +1746,7 @@ pixmap = skin_get_pixmap(skin, pixmap_id); g_return_if_fail(pixmap != NULL); g_return_if_fail(pixmap->pixbuf != NULL); -#if 0 + /* perhaps we should use transparency or resize widget? */ if (xsrc+width > pixmap->width || ysrc+height > pixmap->height) { if (widget) { @@ -1798,7 +1795,7 @@ } else return; } -#endif + width = MIN(width, pixmap->width - xsrc); height = MIN(height, pixmap->height - ysrc); gdk_pixbuf_copy_area(pixmap->pixbuf, xsrc, ysrc, width, height, @@ -2056,8 +2053,8 @@ g_return_if_fail(obj != NULL); if (scale) { - GdkPixbuf *image = gdk_pixbuf_scale_simple(obj, width * config.scale_factor, height* aud_cfg->scale_factor, GDK_INTERP_NEAREST); - gdk_draw_pixbuf(widget->window, NULL, image, 0, 0, 0, 0, width * config.scale_factor , height * aud_cfg->scale_factor, GDK_RGB_DITHER_NONE, 0, 0); + GdkPixbuf *image = gdk_pixbuf_scale_simple(obj, width * config.scale_factor, height* config.scale_factor, GDK_INTERP_NEAREST); + gdk_draw_pixbuf(widget->window, NULL, image, 0, 0, 0, 0, width * config.scale_factor , height * config.scale_factor, GDK_RGB_DITHER_NONE, 0, 0); g_object_unref(image); } else { gdk_draw_pixbuf(widget->window, NULL, obj, 0, 0, 0, 0, width, height, GDK_RGB_DITHER_NONE, 0, 0);
--- a/src/skins/ui_skin.h Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_skin.h Sun May 25 21:29:48 2008 +0300 @@ -30,14 +30,8 @@ #include <gdk/gdk.h> #include <gtk/gtk.h> -#if 0 -#include "audconfig.h" - #define BMP_DEFAULT_SKIN_PATH \ DATA_DIR G_DIR_SEPARATOR_S "Skins" G_DIR_SEPARATOR_S "Default" -#else -#define BMP_DEFAULT_SKIN_PATH "/usr/local/share/audacious/Skins/Default" -#endif typedef enum { SKIN_MAIN = 0, @@ -216,6 +210,7 @@ gboolean skin_reload_forced(void); void skin_reload(Skin * skin); void skin_free(Skin * skin); +void skin_destroy(Skin * skin); GdkBitmap *skin_get_mask(Skin * skin, SkinMaskId mi); GdkColor *skin_get_color(Skin * skin, SkinColorId color_id);
--- a/src/skins/ui_skinned_equalizer_slider.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_skinned_equalizer_slider.c Sun May 25 21:29:48 2008 +0300 @@ -22,9 +22,7 @@ */ #include "ui_skin.h" -#if 0 #include "ui_equalizer.h" -#endif #include "ui_main.h" #include "skins_cfg.h" #include "ui_skinned_equalizer_slider.h" @@ -259,9 +257,7 @@ priv->position = 25; priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 ); -#if 0 equalizerwin_eq_changed(); -#endif } ui_skinned_equalizer_slider_set_mainwin_text(es); @@ -305,9 +301,7 @@ priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 ); ui_skinned_equalizer_slider_set_mainwin_text(es); -#if 0 equalizerwin_eq_changed(); -#endif gtk_widget_queue_draw(widget); } @@ -333,9 +327,7 @@ } priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 ); -#if 0 equalizerwin_eq_changed(); -#endif gtk_widget_queue_draw(widget); return TRUE; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_skinned_playlist.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,1101 @@ +/* + * Audacious - a cross-platform multimedia player + * Copyright (c) 2007 Tomasz Moń + * Copyright (c) 2008 William Pitcock + * + * Based on: + * BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +/* + * 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 "ui_skinned_playlist.h" + +#include "debug.h" +#include "ui_playlist.h" +#include "ui_manager.h" +#include "ui_skin.h" +#include "util.h" +#include "skins_cfg.h" +#include <audacious/plugin.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; + +#define UI_SKINNED_PLAYLIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_get_type(), UiSkinnedPlaylistPrivate)) +typedef struct _UiSkinnedPlaylistPrivate UiSkinnedPlaylistPrivate; + +enum { + REDRAW, + LAST_SIGNAL +}; + +struct _UiSkinnedPlaylistPrivate { + SkinPixmapId skin_index; + gint width, height; + gint resize_width, resize_height; + gint drag_pos; + gboolean dragging, auto_drag_down, auto_drag_up; + gint auto_drag_up_tag, auto_drag_down_tag; +}; + +static void ui_skinned_playlist_class_init (UiSkinnedPlaylistClass *klass); +static void ui_skinned_playlist_init (UiSkinnedPlaylist *playlist); +static void ui_skinned_playlist_destroy (GtkObject *object); +static void ui_skinned_playlist_realize (GtkWidget *widget); +static void ui_skinned_playlist_size_request (GtkWidget *widget, GtkRequisition *requisition); +static void ui_skinned_playlist_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static gboolean ui_skinned_playlist_expose (GtkWidget *widget, GdkEventExpose *event); +static gboolean ui_skinned_playlist_button_press (GtkWidget *widget, GdkEventButton *event); +static gboolean ui_skinned_playlist_button_release (GtkWidget *widget, GdkEventButton *event); +static gboolean ui_skinned_playlist_motion_notify (GtkWidget *widget, GdkEventMotion *event); +static gboolean ui_skinned_playlist_leave_notify (GtkWidget *widget, GdkEventCrossing *event); +static void ui_skinned_playlist_redraw (UiSkinnedPlaylist *playlist); +static gboolean ui_skinned_playlist_popup_show (gpointer data); +static void ui_skinned_playlist_popup_hide (GtkWidget *widget); +static void ui_skinned_playlist_popup_timer_start (GtkWidget *widget); +static void ui_skinned_playlist_popup_timer_stop (GtkWidget *widget); + +static GtkWidgetClass *parent_class = NULL; +static guint playlist_signals[LAST_SIGNAL] = { 0 }; + +GType ui_skinned_playlist_get_type() { + static GType playlist_type = 0; + if (!playlist_type) { + static const GTypeInfo playlist_info = { + sizeof (UiSkinnedPlaylistClass), + NULL, + NULL, + (GClassInitFunc) ui_skinned_playlist_class_init, + NULL, + NULL, + sizeof (UiSkinnedPlaylist), + 0, + (GInstanceInitFunc) ui_skinned_playlist_init, + }; + playlist_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylist", &playlist_info, 0); + } + + return playlist_type; +} + +static void ui_skinned_playlist_class_init(UiSkinnedPlaylistClass *klass) { + GObjectClass *gobject_class; + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + gobject_class = G_OBJECT_CLASS(klass); + object_class = (GtkObjectClass*) klass; + widget_class = (GtkWidgetClass*) klass; + parent_class = gtk_type_class (gtk_widget_get_type ()); + + object_class->destroy = ui_skinned_playlist_destroy; + + widget_class->realize = ui_skinned_playlist_realize; + widget_class->expose_event = ui_skinned_playlist_expose; + widget_class->size_request = ui_skinned_playlist_size_request; + widget_class->size_allocate = ui_skinned_playlist_size_allocate; + widget_class->button_press_event = ui_skinned_playlist_button_press; + widget_class->button_release_event = ui_skinned_playlist_button_release; + widget_class->motion_notify_event = ui_skinned_playlist_motion_notify; + widget_class->leave_notify_event = ui_skinned_playlist_leave_notify; + + klass->redraw = ui_skinned_playlist_redraw; + + playlist_signals[REDRAW] = + g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (UiSkinnedPlaylistClass, redraw), NULL, NULL, + gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); + + g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistPrivate)); +} + +static void ui_skinned_playlist_init(UiSkinnedPlaylist *playlist) { + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist); + playlist->pressed = FALSE; + priv->resize_width = 0; + priv->resize_height = 0; + playlist->prev_selected = -1; + playlist->prev_min = -1; + playlist->prev_max = -1; + + g_object_set_data(G_OBJECT(playlist), "timer_id", GINT_TO_POINTER(0)); + g_object_set_data(G_OBJECT(playlist), "timer_active", GINT_TO_POINTER(0)); + + GtkWidget *popup = audacious_fileinfopopup_create(); + g_object_set_data(G_OBJECT(playlist), "popup", popup); + g_object_set_data(G_OBJECT(playlist), "popup_active", GINT_TO_POINTER(0)); + g_object_set_data(G_OBJECT(playlist), "popup_position", GINT_TO_POINTER(-1)); +} + +GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h) { + + UiSkinnedPlaylist *hs = g_object_new (ui_skinned_playlist_get_type (), NULL); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(hs); + + hs->x = x; + hs->y = y; + priv->width = w; + priv->height = h; + priv->skin_index = SKIN_PLEDIT; + + gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y); + gtk_widget_set_double_buffered(GTK_WIDGET(hs), TRUE); + + return GTK_WIDGET(hs); +} + +static void ui_skinned_playlist_destroy(GtkObject *object) { + UiSkinnedPlaylist *playlist; + + g_return_if_fail (object != NULL); + g_return_if_fail (UI_SKINNED_IS_PLAYLIST (object)); + + playlist = UI_SKINNED_PLAYLIST (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void ui_skinned_playlist_realize(GtkWidget *widget) { + UiSkinnedPlaylist *playlist; + GdkWindowAttr attributes; + gint attributes_mask; + + g_return_if_fail (widget != NULL); + g_return_if_fail (UI_SKINNED_IS_PLAYLIST(widget)); + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + playlist = UI_SKINNED_PLAYLIST(widget); + + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.event_mask = gtk_widget_get_events(widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK; + attributes.visual = gtk_widget_get_visual(widget); + attributes.colormap = gtk_widget_get_colormap(widget); + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask); + + widget->style = gtk_style_attach(widget->style, widget->window); + gdk_window_set_user_data(widget->window, widget); +} + +static void ui_skinned_playlist_size_request(GtkWidget *widget, GtkRequisition *requisition) { + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget); + + requisition->width = priv->width; + requisition->height = priv->height; +} + +static void ui_skinned_playlist_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { + UiSkinnedPlaylist *playlist = UI_SKINNED_PLAYLIST (widget); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist); + + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height); + + playlist->x = widget->allocation.x; + playlist->y = widget->allocation.y; + + if (priv->height != widget->allocation.height || priv->width != widget->allocation.width) { + priv->width = priv->width + priv->resize_width; + priv->height = priv->height + priv->resize_height; + priv->resize_width = 0; + priv->resize_height = 0; + gtk_widget_queue_draw(widget); + } +} + +static gboolean ui_skinned_playlist_auto_drag_down_func(gpointer data) { + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data); + + if (priv->auto_drag_down) { + ui_skinned_playlist_move_down(pl); + pl->first++; + playlistwin_update_list(aud_playlist_get_active()); + return TRUE; + } + return FALSE; +} + +static gboolean ui_skinned_playlist_auto_drag_up_func(gpointer data) { + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data); + + if (priv->auto_drag_up) { + ui_skinned_playlist_move_up(pl); + pl->first--; + playlistwin_update_list(aud_playlist_get_active()); + return TRUE; + + } + return FALSE; +} + +void ui_skinned_playlist_move_up(UiSkinnedPlaylist * pl) { + GList *list; + Playlist *playlist = aud_playlist_get_active(); + + if (!playlist) + return; + + PLAYLIST_LOCK(playlist); + if ((list = playlist->entries) == NULL) { + PLAYLIST_UNLOCK(playlist); + return; + } + if (PLAYLIST_ENTRY(list->data)->selected) { + /* We are at the top */ + PLAYLIST_UNLOCK(playlist); + return; + } + while (list) { + if (PLAYLIST_ENTRY(list->data)->selected) + glist_moveup(list); + list = g_list_next(list); + } + PLAYLIST_INCR_SERIAL(playlist); + PLAYLIST_UNLOCK(playlist); + if (pl->prev_selected != -1) + pl->prev_selected--; + if (pl->prev_min != -1) + pl->prev_min--; + if (pl->prev_max != -1) + pl->prev_max--; +} + +void ui_skinned_playlist_move_down(UiSkinnedPlaylist * pl) { + GList *list; + Playlist *playlist = aud_playlist_get_active(); + + if (!playlist) + return; + + PLAYLIST_LOCK(playlist); + + if (!(list = g_list_last(playlist->entries))) { + PLAYLIST_UNLOCK(playlist); + return; + } + + if (PLAYLIST_ENTRY(list->data)->selected) { + /* We are at the bottom */ + PLAYLIST_UNLOCK(playlist); + return; + } + + while (list) { + if (PLAYLIST_ENTRY(list->data)->selected) + glist_movedown(list); + list = g_list_previous(list); + } + + PLAYLIST_INCR_SERIAL(playlist); + PLAYLIST_UNLOCK(playlist); + + if (pl->prev_selected != -1) + pl->prev_selected++; + if (pl->prev_min != -1) + pl->prev_min++; + if (pl->prev_max != -1) + pl->prev_max++; +} + +static void +playlist_list_draw_string(cairo_t *cr, UiSkinnedPlaylist *pl, + PangoFontDescription * font, + gint line, + gint width, + const gchar * text, + guint ppos) +{ + guint plist_length_int; + Playlist *playlist = aud_playlist_get_active(); + PangoLayout *layout; + + REQUIRE_LOCK(playlist->mutex); + + cairo_new_path(cr); + + if (config.show_numbers_in_pl) { + gchar *pos_string = g_strdup_printf(config.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos); + plist_length_int = + gint_count_digits(aud_playlist_get_length(playlist)) + !config.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); + + cairo_move_to(cr, (width_approx_digits * + (-1 + plist_length_int - strlen(pos_string))) + + (width_approx_digits / 4), (line - 1) * pl->fheight + + ascent + abs(descent)); + pango_cairo_show_layout(cr, layout); + + g_free(pos_string); + g_object_unref(layout); + + if (!config.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); + + cairo_move_to(cr, padding + (width_approx_letters / 4), + (line - 1) * pl->fheight + + ascent + abs(descent)); + pango_cairo_show_layout(cr, layout); + + g_object_unref(layout); +} + +static gboolean ui_skinned_playlist_expose(GtkWidget *widget, GdkEventExpose *event) { + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(pl); + g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE); + + Playlist *playlist = aud_playlist_get_active(); + PlaylistEntry *entry; + GList *list; + 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; + gboolean in_selection = FALSE; + + gchar tail[100]; + gchar queuepos[255]; + gchar length[40]; + + gchar **frags; + gchar *frag0; + + gint plw_w, plw_h; + + cairo_t *cr; + gint yc; + gint pos; + gdouble rounding_offset; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + cr = gdk_cairo_create(widget->window); + + width = priv->width; + height = priv->height; + + plw_w = playlistwin_get_width(); + plw_h = playlistwin_get_height(); + + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMALBG)); + + cairo_rectangle(cr, 0, 0, width, height); + cairo_paint(cr); + + if (!playlist_list_font) { + g_critical("Couldn't open playlist font"); + return FALSE; + } + + pl->fheight = (ascent + abs(descent)); + pl->num_visible = height / pl->fheight; + + rounding_offset = pl->fheight / 3; + + max_first = aud_playlist_get_length(playlist) - pl->num_visible; + max_first = MAX(max_first, 0); + + pl->first = CLAMP(pl->first, 0, max_first); + + PLAYLIST_LOCK(playlist); + list = playlist->entries; + list = g_list_nth(list, 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->first; + list && i < pl->first + pl->num_visible; + list = g_list_next(list), i++) { + 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->entries; + list = g_list_nth(list, pl->first); + + for (i = pl->first; + list && i < pl->first + pl->num_visible; + list = g_list_next(list), i++) { + entry = list->data; + + if (entry->selected && !in_selection) { + yc = ((i - pl->first) * pl->fheight); + + cairo_new_path(cr); + + cairo_move_to(cr, 0, yc + (rounding_offset * 2)); + cairo_curve_to(cr, 0, yc + rounding_offset, 0, yc + 0.5, 0 + rounding_offset, yc + 0.5); + + cairo_line_to(cr, 0 + width - (rounding_offset * 2), yc + 0.5); + cairo_curve_to(cr, 0 + width - rounding_offset, yc + 0.5, + 0 + width, yc + 0.5, 0 + width, yc + rounding_offset); + + in_selection = TRUE; + } + + if ((!entry->selected || + (i == pl->first + pl->num_visible - 1) || !g_list_next(list)) + && in_selection) { + + if (!entry->selected) + yc = (((i - 1) - pl->first) * pl->fheight); + else /* last visible item */ + yc = ((i - pl->first) * pl->fheight); + + cairo_line_to(cr, 0 + width, yc + pl->fheight - (rounding_offset * 2)); + cairo_curve_to (cr, 0 + width, yc + pl->fheight - rounding_offset, + 0 + width, yc + pl->fheight - 0.5, + 0 + width-rounding_offset, yc + pl->fheight - 0.5); + + cairo_line_to (cr, 0 + (rounding_offset * 2), yc + pl->fheight - 0.5); + cairo_curve_to (cr, 0 + rounding_offset, yc + pl->fheight - 0.5, + 0, yc + pl->fheight - 0.5, + 0, yc + pl->fheight - rounding_offset); + + cairo_close_path (cr); + + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_SELECTEDBG)); + + cairo_fill(cr); + + in_selection = FALSE; + } + } + + list = playlist->entries; + list = g_list_nth(list, pl->first); + + /* now draw the text */ + for (i = pl->first; + list && i < pl->first + pl->num_visible; + list = g_list_next(list), i++) { + entry = list->data; + + /* 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 *realfn = g_filename_from_uri(entry->filename, NULL, NULL); + gchar *basename = g_path_get_basename(realfn ? realfn : entry->filename); + title = aud_filename_to_utf8(basename); + g_free(basename); g_free(realfn); + } + else + title = aud_str_to_utf8(entry->title); + + title = aud_convert_title_text(title); + + pos = aud_playlist_get_queue_position(playlist, 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) - 1); + 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 == aud_playlist_get_position_nolock(playlist)) + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT)); + else + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL)); + + playlist_list_draw_string(cr, pl, playlist_list_font, + i - pl->first, tail_width, title, + i + 1); + + x = width - width_approx_digits * 2; + y = ((i - pl->first) - 1) * 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); + + cairo_new_path(cr); + cairo_move_to(cr, x - (0.5 * width_approx_digits), y + abs(descent)); + pango_cairo_show_layout(cr, 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); + + cairo_move_to(cr, x - (0.75 * width_approx_digits), y + abs(descent)); + pango_cairo_show_layout(cr, layout); + g_object_unref(layout); + + g_free(frag0); + g_strfreev(frags); + } + + if (pos != -1) { + if (tpadding_dwidth > 0) + queue_tailpadding = tpadding_dwidth + 1; + else + queue_tailpadding = -0.75; + + cairo_rectangle(cr, + 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->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); + + cairo_move_to(cr, + x - + ((queue_tailpadding + + strlen(queuepos)) * width_approx_digits) + + (width_approx_digits / 4), + y + abs(descent)); + pango_cairo_show_layout(cr, layout); + + g_object_unref(layout); + } + + cairo_stroke(cr); + + 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->drag_motion) { + guint pos, plength, lpadding; + + if (config.show_numbers_in_pl) { + lpadding = gint_count_digits(aud_playlist_get_length(playlist)) + 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 = aud_playlist_get_length(playlist); + + x = pl->drag_motion_x; + y = pl->drag_motion_y; + + if ((x > pl->x) && !(x > priv->width)) { + + if ((y > pl->y) + && !(y > (priv->height + pl->y))) { + + pos = (y / pl->fheight) + + pl->first; + + if (pos > (plength)) { + pos = plength; + } + + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT)); + + cairo_new_path(cr); + + cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight)); + cairo_rel_line_to(cr, priv->width - 1, 0); + + cairo_set_line_width(cr, 1); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + cairo_stroke(cr); + } + + } + + /* 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 < pl->y) || (y > priv->height + pl->y)) { + if ((y >= 0) || (y <= (priv->height + pl->y))) { + pos = plength; + + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT)); + + cairo_new_path(cr); + + cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight)); + cairo_rel_line_to(cr, priv->width - 1, 0); + + cairo_set_line_width(cr, 1); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + cairo_stroke(cr); + } + } + } + + gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL)); + cairo_set_line_width(cr, 1); + cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); + + if (config.show_numbers_in_pl) + { + padding_plength = aud_playlist_get_length(playlist); + + if (padding_plength == 0) { + padding_dwidth = 0; + } + else { + padding_dwidth = gint_count_digits(aud_playlist_get_length(playlist)); + } + + 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 (config.show_separator_in_pl) { + cairo_new_path(cr); + + cairo_move_to(cr, padding, 0); + cairo_rel_line_to(cr, 0, priv->height - 1); + + cairo_stroke(cr); + } + } + + if (tpadding_dwidth != 0) + { + tpadding = (tpadding_dwidth * width_approx_digits) + (width_approx_digits * 1.5); + + if (has_slant) + tpadding += width_approx_digits_half; + + if (config.show_separator_in_pl) { + cairo_new_path(cr); + + cairo_move_to(cr, priv->width - tpadding, 0); + cairo_rel_line_to(cr, 0, priv->height - 1); + + cairo_stroke(cr); + } + } + + PLAYLIST_UNLOCK(playlist); + + cairo_destroy(cr); + + return FALSE; +} + +gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y) { + gint iy, length; + gint ret; + Playlist *playlist = aud_playlist_get_active(); + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget); + + if (!pl->fheight) + return -1; + + if ((length = aud_playlist_get_length(playlist)) == 0) + return -1; + iy = y; + + ret = (iy / pl->fheight) + pl->first; + + if (ret > length - 1) + ret = -1; + + return ret; +} + +static gboolean ui_skinned_playlist_button_press(GtkWidget *widget, GdkEventButton *event) { + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget); + + gint nr; + Playlist *playlist = aud_playlist_get_active(); + + nr = ui_skinned_playlist_get_position(widget, event->x, event->y); + if (nr == -1) + return FALSE; + + if (event->button == 3) { + ui_manager_popup_menu_show(GTK_MENU(playlistwin_popup_menu), + event->x_root, event->y_root + 5, + event->button, event->time); + GList* selection = aud_playlist_get_selected(playlist); + if (g_list_find(selection, GINT_TO_POINTER(nr)) == NULL) { + aud_playlist_select_all(playlist, FALSE); + aud_playlist_select_range(playlist, nr, nr, TRUE); + } + } else if (event->button == 1) { + if (!(event->state & GDK_CONTROL_MASK)) + aud_playlist_select_all(playlist, FALSE); + + if ((event->state & GDK_MOD1_MASK)) + aud_playlist_queue_position(playlist, nr); + + if (event->state & GDK_SHIFT_MASK && pl->prev_selected != -1) { + aud_playlist_select_range(playlist, pl->prev_selected, nr, TRUE); + pl->prev_min = pl->prev_selected; + pl->prev_max = nr; + priv->drag_pos = nr - pl->first; + } + else { + if (aud_playlist_select_invert(playlist, nr)) { + if (event->state & GDK_CONTROL_MASK) { + if (pl->prev_min == -1) { + pl->prev_min = pl->prev_selected; + pl->prev_max = pl->prev_selected; + } + if (nr < pl->prev_min) + pl->prev_min = nr; + else if (nr > pl->prev_max) + pl->prev_max = nr; + } + else + pl->prev_min = -1; + pl->prev_selected = nr; + priv->drag_pos = nr - pl->first; + } + } + if (event->type == GDK_2BUTTON_PRESS) { + /* + * Ungrab the pointer to prevent us from + * hanging on to it during the sometimes slow + * audacious_drct_initiate(). + */ + gdk_pointer_ungrab(GDK_CURRENT_TIME); + aud_playlist_set_position(playlist, nr); + if (!audacious_drct_get_playing()) + audacious_drct_initiate(); + } + + priv->dragging = TRUE; + } + playlistwin_update_list(playlist); + ui_skinned_playlist_popup_hide(widget); + ui_skinned_playlist_popup_timer_stop(widget); + + return TRUE; +} + +static gboolean ui_skinned_playlist_button_release(GtkWidget *widget, GdkEventButton *event) { + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget); + + priv->dragging = FALSE; + priv->auto_drag_down = FALSE; + priv->auto_drag_up = FALSE; + gtk_widget_queue_draw(widget); + + ui_skinned_playlist_popup_hide(widget); + ui_skinned_playlist_popup_timer_stop(widget); + return TRUE; +} + +static gboolean ui_skinned_playlist_motion_notify(GtkWidget *widget, GdkEventMotion *event) { + UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(widget); + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget); + + gint nr, y, off, i; + if (priv->dragging) { + y = event->y; + nr = (y / pl->fheight); + if (nr < 0) { + nr = 0; + if (!priv->auto_drag_up) { + priv->auto_drag_up = TRUE; + priv->auto_drag_up_tag = + g_timeout_add(100, ui_skinned_playlist_auto_drag_up_func, pl); + } + } + else if (priv->auto_drag_up) + priv->auto_drag_up = FALSE; + + if (nr >= pl->num_visible) { + nr = pl->num_visible - 1; + if (!priv->auto_drag_down) { + priv->auto_drag_down = TRUE; + priv->auto_drag_down_tag = + g_timeout_add(100, ui_skinned_playlist_auto_drag_down_func, pl); + } + } + else if (priv->auto_drag_down) + priv->auto_drag_down = FALSE; + + off = nr - priv->drag_pos; + if (off) { + for (i = 0; i < abs(off); i++) { + if (off < 0) + ui_skinned_playlist_move_up(pl); + else + ui_skinned_playlist_move_down(pl); + + } + playlistwin_update_list(aud_playlist_get_active()); + } + priv->drag_pos = nr; + } else if (config.show_filepopup_for_tuple) { + gint pos = ui_skinned_playlist_get_position(widget, event->x, event->y); + gint cur_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position")); + if (pos != cur_pos) { + g_object_set_data(G_OBJECT(widget), "popup_position", GINT_TO_POINTER(pos)); + ui_skinned_playlist_popup_hide(widget); + ui_skinned_playlist_popup_timer_stop(widget); + if (pos != -1) + ui_skinned_playlist_popup_timer_start(widget); + } + } + + return TRUE; +} + +static gboolean ui_skinned_playlist_leave_notify(GtkWidget *widget, GdkEventCrossing *event) { + ui_skinned_playlist_popup_hide(widget); + ui_skinned_playlist_popup_timer_stop(widget); + + return FALSE; +} + +static void ui_skinned_playlist_redraw(UiSkinnedPlaylist *playlist) { + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist); + + if (priv->resize_height || priv->resize_width) + gtk_widget_set_size_request(GTK_WIDGET(playlist), priv->width+priv->resize_width, priv->height+priv->resize_height); + + gtk_widget_queue_draw(GTK_WIDGET(playlist)); +} + +void ui_skinned_playlist_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); +} + +void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h) { + UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget); + priv->resize_width += w; + priv->resize_height += h; +} + +static gboolean ui_skinned_playlist_popup_show(gpointer data) { + GtkWidget *widget = data; + gint pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position")); + + if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1 && pos != -1) { + Tuple *tuple; + Playlist *pl_active = aud_playlist_get_active(); + GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup"); + + tuple = aud_playlist_get_tuple(pl_active, pos); + if ((tuple == NULL) || (aud_tuple_get_int(tuple, FIELD_LENGTH, NULL) < 1)) { + gchar *title = aud_playlist_get_songtitle(pl_active, pos); + audacious_fileinfopopup_show_from_title(popup, title); + g_free(title); + } else { + audacious_fileinfopopup_show_from_tuple(popup , tuple); + } + g_object_set_data(G_OBJECT(widget), "popup_active" , GINT_TO_POINTER(1)); + } + + ui_skinned_playlist_popup_timer_stop(widget); + return FALSE; +} + +static void ui_skinned_playlist_popup_hide(GtkWidget *widget) { + if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_active")) == 1) { + GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup"); + g_object_set_data(G_OBJECT(widget), "popup_active", GINT_TO_POINTER(0)); + audacious_fileinfopopup_hide(popup, NULL); + } +} + +static void ui_skinned_playlist_popup_timer_start(GtkWidget *widget) { + gint timer_id = g_timeout_add(config.filepopup_delay*100, ui_skinned_playlist_popup_show, widget); + g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(timer_id)); + g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(1)); +} + +static void ui_skinned_playlist_popup_timer_stop(GtkWidget *widget) { + if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1) + g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_id"))); + + g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(0)); + g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(0)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_skinned_playlist.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,77 @@ +/* + * Audacious - a cross-platform multimedia player + * Copyright (c) 2007 Tomasz Moń + * + * Based on: + * BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_H +#define AUDACIOUS_UI_SKINNED_PLAYLIST_H + +#include <gtk/gtk.h> + +#include <cairo.h> +#include <pango/pangocairo.h> + +#include "ui_skin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UI_SKINNED_PLAYLIST(obj) GTK_CHECK_CAST (obj, ui_skinned_playlist_get_type (), UiSkinnedPlaylist) +#define UI_SKINNED_PLAYLIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_get_type (), UiSkinnedPlaylistClass) +#define UI_SKINNED_IS_PLAYLIST(obj) GTK_CHECK_TYPE (obj, ui_skinned_playlist_get_type ()) + +typedef struct _UiSkinnedPlaylist UiSkinnedPlaylist; +typedef struct _UiSkinnedPlaylistClass UiSkinnedPlaylistClass; + +struct _UiSkinnedPlaylist { + GtkWidget widget; + gboolean pressed; + gint x, y; + gint first; + gint num_visible; + gint prev_selected, prev_min, prev_max; + gboolean drag_motion; + gint drag_motion_x, drag_motion_y; + gint fheight; +}; + +struct _UiSkinnedPlaylistClass { + GtkWidgetClass parent_class; + void (* redraw) (UiSkinnedPlaylist *playlist); +}; + +GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h); +GtkType ui_skinned_playlist_get_type(void); +void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h); +void ui_skinned_playlist_set_font(const gchar * font); +void ui_skinned_playlist_move_up(UiSkinnedPlaylist *pl); +void ui_skinned_playlist_move_down(UiSkinnedPlaylist *pl); +gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y); + +#ifdef __cplusplus +} +#endif + +#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_skinned_playlist_slider.c Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,337 @@ +/* + * Audacious - a cross-platform multimedia player + * Copyright (c) 2007 Tomasz Moń + * + * Based on: + * BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#include "ui_skin.h" +#include "ui_skinned_playlist_slider.h" +#include "ui_playlist.h" + +#define UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_slider_get_type(), UiSkinnedPlaylistSliderPrivate)) +typedef struct _UiSkinnedPlaylistSliderPrivate UiSkinnedPlaylistSliderPrivate; + +enum { + REDRAW, + LAST_SIGNAL +}; + +struct _UiSkinnedPlaylistSliderPrivate { + SkinPixmapId skin_index; + gint width, height; + + gint resize_height; + gint move_x; + gint prev_y; + gint drag_y; +}; + +static void ui_skinned_playlist_slider_class_init (UiSkinnedPlaylistSliderClass *klass); +static void ui_skinned_playlist_slider_init (UiSkinnedPlaylistSlider *playlist_slider); +static void ui_skinned_playlist_slider_destroy (GtkObject *object); +static void ui_skinned_playlist_slider_realize (GtkWidget *widget); +static void ui_skinned_playlist_slider_size_request (GtkWidget *widget, GtkRequisition *requisition); +static void ui_skinned_playlist_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static gboolean ui_skinned_playlist_slider_expose (GtkWidget *widget, GdkEventExpose *event); +static void ui_skinned_playlist_slider_set_position (GtkWidget *widget, gint y); +static gboolean ui_skinned_playlist_slider_button_press (GtkWidget *widget, GdkEventButton *event); +static gboolean ui_skinned_playlist_slider_button_release (GtkWidget *widget, GdkEventButton *event); +static gboolean ui_skinned_playlist_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event); +static void ui_skinned_playlist_slider_redraw (UiSkinnedPlaylistSlider *playlist_slider); + +static GtkWidgetClass *parent_class = NULL; +static guint playlist_slider_signals[LAST_SIGNAL] = { 0 }; + +GType ui_skinned_playlist_slider_get_type() { + static GType playlist_slider_type = 0; + if (!playlist_slider_type) { + static const GTypeInfo playlist_slider_info = { + sizeof (UiSkinnedPlaylistSliderClass), + NULL, + NULL, + (GClassInitFunc) ui_skinned_playlist_slider_class_init, + NULL, + NULL, + sizeof (UiSkinnedPlaylistSlider), + 0, + (GInstanceInitFunc) ui_skinned_playlist_slider_init, + }; + playlist_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylistSlider", &playlist_slider_info, 0); + } + + return playlist_slider_type; +} + +static void ui_skinned_playlist_slider_class_init(UiSkinnedPlaylistSliderClass *klass) { + GObjectClass *gobject_class; + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + gobject_class = G_OBJECT_CLASS(klass); + object_class = (GtkObjectClass*) klass; + widget_class = (GtkWidgetClass*) klass; + parent_class = gtk_type_class (gtk_widget_get_type ()); + + object_class->destroy = ui_skinned_playlist_slider_destroy; + + widget_class->realize = ui_skinned_playlist_slider_realize; + widget_class->expose_event = ui_skinned_playlist_slider_expose; + widget_class->size_request = ui_skinned_playlist_slider_size_request; + widget_class->size_allocate = ui_skinned_playlist_slider_size_allocate; + widget_class->button_press_event = ui_skinned_playlist_slider_button_press; + widget_class->button_release_event = ui_skinned_playlist_slider_button_release; + widget_class->motion_notify_event = ui_skinned_playlist_slider_motion_notify; + + klass->redraw = ui_skinned_playlist_slider_redraw; + + playlist_slider_signals[REDRAW] = + g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (UiSkinnedPlaylistSliderClass, redraw), NULL, NULL, + gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); + + g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistSliderPrivate)); +} + +static void ui_skinned_playlist_slider_init(UiSkinnedPlaylistSlider *playlist_slider) { + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider); + playlist_slider->pressed = FALSE; + priv->resize_height = 0; + priv->move_x = 0; + priv->drag_y = 0; + priv->prev_y = 0; +} + +GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h) { + + UiSkinnedPlaylistSlider *hs = g_object_new (ui_skinned_playlist_slider_get_type (), NULL); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(hs); + + hs->x = x; + hs->y = y; + priv->width = 8; + priv->height = h; + priv->skin_index = SKIN_PLEDIT; + + gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y); + + return GTK_WIDGET(hs); +} + +static void ui_skinned_playlist_slider_destroy(GtkObject *object) { + UiSkinnedPlaylistSlider *playlist_slider; + + g_return_if_fail (object != NULL); + g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (object)); + + playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void ui_skinned_playlist_slider_realize(GtkWidget *widget) { + UiSkinnedPlaylistSlider *playlist_slider; + GdkWindowAttr attributes; + gint attributes_mask; + + g_return_if_fail (widget != NULL); + g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER(widget)); + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + playlist_slider = UI_SKINNED_PLAYLIST_SLIDER(widget); + + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.event_mask = gtk_widget_get_events(widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK; + attributes.visual = gtk_widget_get_visual(widget); + attributes.colormap = gtk_widget_get_colormap(widget); + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask); + + widget->style = gtk_style_attach(widget->style, widget->window); + gdk_window_set_user_data(widget->window, widget); +} + +static void ui_skinned_playlist_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) { + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + + requisition->width = priv->width; + requisition->height = priv->height; +} + +static void ui_skinned_playlist_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { + UiSkinnedPlaylistSlider *playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (widget); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider); + + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height); + + if (playlist_slider->x + priv->move_x == widget->allocation.x) + priv->move_x = 0; + playlist_slider->x = widget->allocation.x; + playlist_slider->y = widget->allocation.y; + + if (priv->height != widget->allocation.height) { + priv->height = priv->height + priv->resize_height; + priv->resize_height = 0; + gtk_widget_queue_draw(widget); + } +} + +static gboolean ui_skinned_playlist_slider_expose(GtkWidget *widget, GdkEventExpose *event) { + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(ps); + g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE); + + GdkPixbuf *obj = NULL; + obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height); + + gint num_visible; + num_visible = playlistwin_list_get_visible_count(); + + + Playlist *playlist = aud_playlist_get_active(); + + gint y; + if (aud_playlist_get_length(playlist) > num_visible) + y = (playlistwin_list_get_first() * (priv->height - 19)) / + (aud_playlist_get_length(playlist) - num_visible); + else + y = 0; + + if (y < 0) y=0; + if (y > priv->height - 19) y = priv->height - 19; + + priv->prev_y = y; + + /* FIXME: uses aud_active_skin->pixmaps directly and may need calibration */ + /* drawing background */ + gint c; + for (c = 0; c < priv->height / 29; c++) { + gdk_pixbuf_copy_area(aud_active_skin->pixmaps[SKIN_PLEDIT].pixbuf, + 36, 42, priv->width, 29, obj, 0, c*29); + } + + /* drawing knob */ + skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, ps->pressed ? 61 : 52, 53, 0, y, priv->width, 18); + + ui_skinned_widget_draw(widget, obj, priv->width, priv->height, FALSE); + + g_object_unref(obj); + + return FALSE; +} + +static void ui_skinned_playlist_slider_set_position(GtkWidget *widget, gint y) { + gint pos; + Playlist *playlist = aud_playlist_get_active(); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + + y = CLAMP(y, 0, priv->height - 19); + + pos = (y * (aud_playlist_get_length(playlist) - playlistwin_list_get_visible_count())) / (priv->height - 19); + playlistwin_set_toprow(pos); + + gtk_widget_queue_draw(widget); +} + +static gboolean ui_skinned_playlist_slider_button_press(GtkWidget *widget, GdkEventButton *event) { + UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + + if (event->button != 1 && event->button != 2) + return TRUE; + + gint y = event->y; + if (event->type == GDK_BUTTON_PRESS) { + ps->pressed = TRUE; + if ((y >= priv->prev_y && y < priv->prev_y + 18)) { + priv->drag_y = y - priv->prev_y; + } else if (event->button == 2) { + ui_skinned_playlist_slider_set_position(widget, y); + priv->drag_y = 0; + } else { + gint n = playlistwin_list_get_visible_count() / 2; + if (y < priv->prev_y) + n *= -1; + playlistwin_scroll(n); + } + gtk_widget_queue_draw(widget); + } + return TRUE; +} + +static gboolean ui_skinned_playlist_slider_button_release(GtkWidget *widget, GdkEventButton *event) { + UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget); + + if (event->button == 1 || event->button == 2) { + ps->pressed = FALSE; + gtk_widget_queue_draw(widget); + } + return TRUE; +} + +static gboolean ui_skinned_playlist_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) { + UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget); + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + + if (ps->pressed) { + gint y = event->y - priv->drag_y; + ui_skinned_playlist_slider_set_position(widget, y); + } + return TRUE; +} + +static void ui_skinned_playlist_slider_redraw(UiSkinnedPlaylistSlider *playlist_slider) { + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider); + + if (priv->resize_height) + gtk_widget_set_size_request(GTK_WIDGET(playlist_slider), priv->width, priv->height+priv->resize_height); + if (priv->move_x) + gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(playlist_slider))), GTK_WIDGET(playlist_slider), + playlist_slider->x+priv->move_x, playlist_slider->y); + + gtk_widget_queue_draw(GTK_WIDGET(playlist_slider)); +} + +void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x) { + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + priv->move_x += x; +} + +void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h) { + UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget); + priv->resize_height += h; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/skins/ui_skinned_playlist_slider.h Sun May 25 21:29:48 2008 +0300 @@ -0,0 +1,63 @@ +/* + * Audacious - a cross-platform multimedia player + * Copyright (c) 2007 Tomasz Moń + * + * Based on: + * BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H +#define AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H + +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define UI_SKINNED_PLAYLIST_SLIDER(obj) GTK_CHECK_CAST (obj, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSlider) +#define UI_SKINNED_PLAYLIST_SLIDER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSliderClass) +#define UI_SKINNED_IS_PLAYLIST_SLIDER(obj) GTK_CHECK_TYPE (obj, ui_skinned_playlist_slider_get_type ()) + +typedef struct _UiSkinnedPlaylistSlider UiSkinnedPlaylistSlider; +typedef struct _UiSkinnedPlaylistSliderClass UiSkinnedPlaylistSliderClass; + +struct _UiSkinnedPlaylistSlider { + GtkWidget widget; + gboolean pressed; + gint x, y; +}; + +struct _UiSkinnedPlaylistSliderClass { + GtkWidgetClass parent_class; + void (* redraw) (UiSkinnedPlaylistSlider *playlist_slider); +}; + +GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h); +GtkType ui_skinned_playlist_slider_get_type(void); +void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x); +void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h); + +#ifdef __cplusplus +} +#endif + +#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H */
--- a/src/skins/ui_skinned_textbox.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_skinned_textbox.c Sun May 25 21:29:48 2008 +0300 @@ -707,6 +707,8 @@ void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll) { g_return_if_fail(widget != NULL); + g_return_if_fail(UI_SKINNED_IS_TEXTBOX(widget)); + UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget); UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
--- a/src/skins/ui_skinned_window.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_skinned_window.c Sun May 25 21:29:48 2008 +0300 @@ -18,20 +18,20 @@ * Audacious or using our public API to be a derived work. */ -#include "platform/smartinclude.h" -#include "ui_skin.h" -#include "skins_cfg.h" - #include <gtk/gtkmain.h> #include <glib-object.h> #include <glib/gmacros.h> #include <gtk/gtkmarshal.h> #include <gtk/gtkwindow.h> #include <string.h> - #include <audacious/plugin.h> +#include "platform/smartinclude.h" +#include "ui_skin.h" +#include "skins_cfg.h" #include "ui_dock.h" #include "ui_skinned_window.h" +#include "ui_main.h" +#include "ui_playlist.h" static void ui_skinned_window_class_init(SkinnedWindowClass *klass); static void ui_skinned_window_init(GtkWidget *widget); @@ -134,10 +134,8 @@ height = 116 * (config.scaled ? config.scale_factor : 1) ; break; case WINDOW_PLAYLIST: -#if 0 width = playlistwin_get_width(); height = config.playlist_height; -#endif break; default: return FALSE; @@ -275,10 +273,9 @@ } void ui_skinned_window_draw_all(GtkWidget *widget) { -#if 0 if (SKINNED_WINDOW(widget)->type == WINDOW_MAIN) mainwin_refresh_hints(); -#endif + gtk_widget_queue_draw(widget); GList *iter; for (iter = GTK_FIXED (SKINNED_WINDOW(widget)->fixed)->children; iter; iter = g_list_next (iter)) {
--- a/src/skins/ui_svis.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_svis.c Sun May 25 21:29:48 2008 +0300 @@ -353,7 +353,7 @@ } else { /*svis scaling, this needs some work, since a lot of stuff is hardcoded --majeru*/ - memset(rgb_data, 0, SVIS_WIDTH * config.scale_factor * SVIS_HEIGHT * aud_cfg->scale_factor); + memset(rgb_data, 0, SVIS_WIDTH * config.scale_factor * SVIS_HEIGHT * config.scale_factor); if (config.vis_type == VIS_ANALYZER && !audacious_drct_get_paused() && audacious_drct_get_playing()){ for(y=0; y < SVIS_HEIGHT; y++){ if (config.analyzer_type == ANALYZER_BARS){ @@ -452,7 +452,7 @@ GtkWidget *widget = GTK_WIDGET (svis); svis->scaled = !svis->scaled; - gtk_widget_set_size_request(widget, svis->width* config.scale_factor, svis->height * aud_cfg->scale_factor); + gtk_widget_set_size_request(widget, svis->width* config.scale_factor, svis->height * config.scale_factor); gtk_widget_queue_draw(widget); }
--- a/src/skins/ui_vis.c Sun May 25 21:29:07 2008 +0300 +++ b/src/skins/ui_vis.c Sun May 25 21:29:48 2008 +0300 @@ -278,7 +278,7 @@ cmap = gdk_rgb_cmap_new(colors, 24); if (!vis->scaled) { - if(config.vis_type == VIS_VOICEPRINT /*&& aud_cfg->voiceprint_mode != VOICEPRINT_NORMAL*/){ + if(config.vis_type == VIS_VOICEPRINT /*&& config.voiceprint_mode != VOICEPRINT_NORMAL*/){ memset(rgb_data, 0, 76 * 16 * 3); } else{ @@ -291,7 +291,7 @@ } } else{ - if(config.vis_type == VIS_VOICEPRINT /*&& aud_cfg->voiceprint_mode != VOICEPRINT_NORMAL*/){ + if(config.vis_type == VIS_VOICEPRINT /*&& config.voiceprint_mode != VOICEPRINT_NORMAL*/){ memset(rgb_data, 0, 3 * 4 * 16 * 76); } else{ @@ -333,7 +333,7 @@ } } else{ - ptr = rgb_data + ((16 - h) * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + ((16 - h) * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * config.scale_factor); switch (config.analyzer_mode) { case ANALYZER_NORMAL: for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * config.scale_factor)) { @@ -376,7 +376,7 @@ rgb_data[(16 - h) * 76 + x] = 23; } else{ - ptr = rgb_data + (16 - h) * (guint)(76 * 4 * config.scale_factor) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + (16 - h) * (guint)(76 * 4 * config.scale_factor) + (guint)(x * config.scale_factor); *ptr = 23; *(ptr + 1) = 23; *(ptr + (guint)(76 * config.scale_factor)) = 23; @@ -450,7 +450,7 @@ rgb_data[x * 3 + y * 76*3+n] = voice_c[n]; } else{ - ptr = rgb_data + (guint)(x * 3 * config.scale_factor) + (guint) (y * 76 * 3 * aud_cfg->scale_factor); + ptr = rgb_data + (guint)(x * 3 * config.scale_factor) + (guint) (y * 76 * 3 * config.scale_factor); for(n=0;n<3;n++) { *(ptr + n) = voice_c[n]; @@ -472,7 +472,7 @@ ptr = rgb_data + ((14 - h) * 76) + x; *ptr = vis_scope_colors[h + 1]; }else{ - ptr = rgb_data + ((14 - h) * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + ((14 - h) * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * config.scale_factor); *ptr = vis_scope_colors[h + 1]; *(ptr + 1) = vis_scope_colors[h + 1]; *(ptr + (guint)(76 * config.scale_factor)) = vis_scope_colors[h + 1]; @@ -494,7 +494,7 @@ *ptr = vis_scope_colors[y - 2]; } else{ - ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * config.scale_factor); for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * config.scale_factor)) { *ptr = vis_scope_colors[y - 2]; *(ptr + 1) = vis_scope_colors[y - 2]; @@ -509,7 +509,7 @@ ptr = rgb_data + (h * 76) + x; *ptr = vis_scope_colors[h + 1]; }else{ - ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * config.scale_factor); *ptr = vis_scope_colors[h + 1]; *(ptr + 1) = vis_scope_colors[h + 1]; *(ptr + (guint)(76 * config.scale_factor)) = vis_scope_colors[h + 1]; @@ -531,7 +531,7 @@ for (y = h; y <= h2; y++, ptr += 76) *ptr = c; }else{ - ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * aud_cfg->scale_factor); + ptr = rgb_data + (h * (guint)(76 * 4 * config.scale_factor)) + (guint)(x * config.scale_factor); for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * config.scale_factor)) { *ptr = c; *(ptr + 1) = c; @@ -546,7 +546,7 @@ GdkPixmap *obj = NULL; GdkGC *gc; - obj = gdk_pixmap_new(NULL, vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1), gdk_rgb_get_visual()->depth); + obj = gdk_pixmap_new(NULL, vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? config.scale_factor : 1), gdk_rgb_get_visual()->depth); gc = gdk_gc_new(obj); if (!vis->scaled) { @@ -574,7 +574,7 @@ } gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0, - vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1)); + vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? config.scale_factor : 1)); g_object_unref(obj); g_object_unref(gc); gdk_rgb_cmap_free(cmap); @@ -585,7 +585,7 @@ GtkWidget *widget = GTK_WIDGET (vis); vis->scaled = !vis->scaled; - gtk_widget_set_size_request(widget, vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1)); + gtk_widget_set_size_request(widget, vis->width*(vis->scaled ? config.scale_factor : 1), vis->height*(vis->scaled ? config.scale_factor : 1)); gtk_widget_queue_draw(GTK_WIDGET(vis)); }