Drop the Shost structure and store everything the Tree Model (list store) Also includes some minor cleanups/unification diff -X dontdiff -urNp tunesbrowser-0.1.7-pre2/daap.c tunesbrowser-dsd/daap.c --- tunesbrowser-0.1.7-pre2/daap.c 2004-11-22 11:36:55.000000000 +0000 +++ tunesbrowser-dsd/daap.c 2004-12-11 03:43:33.819720352 +0000 @@ -38,26 +38,7 @@ #include "lists.h" #include "tunesbrowser.h" -typedef struct hostTAG Shost; -struct hostTAG -{ - DAAP_SClientHost *daap_host; - DAAP_ClientHost_Database *databases; - int nDatabases; - char *sharename; - - int marked; /* used to test if its still in the enum callback */ - - int cached; - int cached_DBID; - - Shost *prev; - Shost *next; -}; - -Shost *tunesHosts = NULL; - -Shost *curHost = NULL; +DAAP_SClientHost *curHost; int curDBID = 0; static int curSongID = 0; @@ -154,18 +135,6 @@ static void free_artists() } /* drawing */ -static void draw_source() -{ - Shost *cur = tunesHosts; - sourcelist_clear(); - - while (cur) - { - sourcelist_append(cur, cur->sharename); - cur = cur->next; - } -} - static void draw_artist() { artist *cur = artisthead; @@ -223,58 +192,43 @@ static void draw_album() } /* database */ -static void updateDatabases(Shost *host) +static gint updateDatabases(DAAP_SClientHost *host, + DAAP_ClientHost_Database **destdatabases) { - int size; - size = DAAP_ClientHost_GetDatabases(host->daap_host, - NULL, NULL, 0); + int size, num_databases; + DAAP_ClientHost_Database *databases; + size = DAAP_ClientHost_GetDatabases(host, NULL, NULL, 0); - if (host->databases) free(host->databases); - host->databases = malloc(size); - DAAP_ClientHost_GetDatabases(host->daap_host, - host->databases, - &(host->nDatabases), + databases = g_malloc(size); + DAAP_ClientHost_GetDatabases(host, + databases, + &num_databases, size); + sourcelist_set_databases_by_host(host, databases, num_databases); + if (destdatabases) + *destdatabases = databases; + return num_databases; } int addDAAPEnumCB(DAAP_SClient *client, DAAP_SClientHost *host, void *ctx) { - Shost *newhost; - Shost *cur, *prev = NULL; + gchar *buf; + int size; - /* Check if the host is already in our list */ - cur = tunesHosts; - while (cur) + /* Check if the host is already in our list, and mark it if it is */ + if (!sourcelist_mark_by_host(host, TRUE)) { - if (cur->daap_host == host) - { - cur->marked = 1; - return 1; - } - prev = cur; - cur = cur->next; + /* If not, add it to the end of the list */ + DAAP_ClientHost_AddRef(host); + sourcelist_append(host, NULL); } - /* If not, add it to the end of the list */ - newhost = malloc(sizeof(Shost)); - - DAAP_ClientHost_AddRef(host); - - newhost->prev = prev; - newhost->next = NULL; - newhost->daap_host = host; - newhost->sharename = NULL; - - newhost->databases = NULL; - newhost->nDatabases = 0; - - newhost->marked = 1; - - newhost->cached = 0; - newhost->cached_DBID = 0; - - if (prev) prev->next = newhost; - else tunesHosts = newhost; + /* Set/update the share name */ + size = DAAP_ClientHost_GetSharename(host, NULL, 0); + buf = g_malloc(size); + DAAP_ClientHost_GetSharename(host, buf, size); + sourcelist_set_sharename_by_host(host, buf); + g_free(buf); return 1; } @@ -287,46 +241,25 @@ void init_daap() void init_daap_sources() { /* FIXME should discover */ - Shost *curhost; + GList *torelease; - for (curhost = tunesHosts; curhost != NULL; curhost = curhost->next) - curhost->marked = 0; + /* Unmark all sources */ + sourcelist_mark_all(FALSE); + /* Mark all active sources and add new */ DAAP_Client_EnumerateHosts(clientInst, addDAAPEnumCB, NULL); - curhost = tunesHosts; - while (curhost) - { - Shost *next = curhost->next; - if (curhost->marked == 0) - { /* remove it */ - if (curhost->prev) curhost->prev->next = next; - else tunesHosts = next; - if (next) next->prev = curhost->prev; - DAAP_ClientHost_Release(curhost->daap_host); - free(curhost); - } - curhost = next; - } - - for (curhost = tunesHosts; curhost != NULL; curhost = curhost->next) + /* Remove all unmarked hosts as they must be inactive */ + torelease = sourcelist_get_marked_host_list(FALSE, TRUE); // get where marked=false and delete those rows + while (torelease) { - char *buf; - int size; - - if (curhost->sharename) - continue; - - size = DAAP_ClientHost_GetSharename(curhost->daap_host, - NULL, 0); - buf = malloc(size); - size = DAAP_ClientHost_GetSharename(curhost->daap_host, - buf, size); - curhost->sharename = buf; + DAAP_ClientHost_Release((DAAP_SClientHost*) torelease->data); + if (!g_list_next(torelease)) + break; + torelease = g_list_next(torelease); } - - draw_source(); + g_list_free(torelease); } void finalize_daap_sources() @@ -482,17 +415,16 @@ static int compare_songitems(const void } /* gets the song list, adds them to the database, and sorts them */ -static void getSongItems(Shost *host, int id) +static void getSongItems(DAAP_SClientHost *host, int id) { int i; int size; - if (currentSongItems) free(currentSongItems); + g_free(currentSongItems); - size = DAAP_ClientHost_GetDatabaseItems(host->daap_host, id, - NULL, NULL, 0); - currentSongItems = (DAAP_ClientHost_DatabaseItem*)malloc(size); - DAAP_ClientHost_GetDatabaseItems(host->daap_host, id, + size = DAAP_ClientHost_GetDatabaseItems(host, id, NULL, NULL, 0); + currentSongItems = (DAAP_ClientHost_DatabaseItem*)g_malloc(size); + DAAP_ClientHost_GetDatabaseItems(host, id, currentSongItems, ¤tSongItemCount, size); @@ -554,63 +486,58 @@ static void draw_songs() void addref_visible_host_cache() { if (!curHost) return; - curHost->cached++; - curHost->cached_DBID = curDBID; + sourcelist_set_cached_by_host(curHost, curDBID); } void release_visible_host_cache() { if (!curHost) return; - if (--(curHost->cached)) - curHost->cached_DBID = 0; /* safety */ + sourcelist_set_cached_by_host(curHost, 0); } -void set_daap_host(Shost *host) +void set_daap_host(DAAP_SClientHost *host) { - int id; + gint id, numdatabases; + DAAP_ClientHost_Database *databases; - if (curHost && !curHost->cached) + if (curHost && !sourcelist_get_cached_by_host(host)) { - DAAP_ClientHost_Disconnect(curHost->daap_host); - DAAP_ClientHost_Release(curHost->daap_host); - sourcelist_set_source_connect_state((void*)curHost, 0); + DAAP_ClientHost_Disconnect(host); + DAAP_ClientHost_Release(host); + sourcelist_set_source_connect_state_by_host(curHost, FALSE); } curHost = host; - if (curHost->cached) + if ((id = sourcelist_get_cached_by_host(host))) { - curDBID = curHost->cached_DBID; + curDBID = id; return; } - DAAP_ClientHost_AddRef(curHost->daap_host); - DAAP_ClientHost_Connect(curHost->daap_host); + DAAP_ClientHost_AddRef(host); + DAAP_ClientHost_Connect(host); - sourcelist_set_source_connect_state((void*)host, 1); + sourcelist_set_source_connect_state_by_host(host, TRUE); - updateDatabases(curHost); - id = curHost->databases[0].id; + numdatabases = updateDatabases(curHost, &databases); + + curDBID = databases[0].id; - if (curHost->nDatabases > 1) + if (numdatabases > 1) { int i; printf("not really sure what to do with multiple databases " "(never seen it myself). The following databases will " "be invisible\n"); - for (i = 1; i < curHost->nDatabases; i++) - { - printf("invisible database: '%s'\n", - curHost->databases[i].name); - } + for (i = 1; i < numdatabases; i++) + g_print("invisible database: '%s'\n", databases[i].name); } - - curDBID = id; } -void set_daap_sources(void *host) +void set_daap_sources(DAAP_SClientHost *host) { - set_daap_host((Shost*)host); + set_daap_host(host); artistalbumview_start(); @@ -682,7 +609,7 @@ static void force_stop_before_play() /* this should then call cb_eos in gstreamer which should do * the rest */ - DAAP_ClientHost_AsyncStop(curHost->daap_host); + DAAP_ClientHost_AsyncStop(curHost); /* cb_eos will do this, once the pipe is closed. audioplayer_stop();*/ @@ -707,7 +634,7 @@ void play_daap_song(int id) pipe(pipefds); - if (DAAP_ClientHost_AsyncGetAudioFile(curHost->daap_host, + if (DAAP_ClientHost_AsyncGetAudioFile(curHost, curDBID, id, currentSongItems[songindex].songformat, pipefds[1])) diff -X dontdiff -urNp tunesbrowser-0.1.7-pre2/lists.h tunesbrowser-dsd/lists.h --- tunesbrowser-0.1.7-pre2/lists.h 2004-11-01 23:47:29.000000000 +0000 +++ tunesbrowser-dsd/lists.h 2004-12-11 03:27:30.257204120 +0000 @@ -26,11 +26,26 @@ #ifndef __LISTS_H #define __LISTS_H +#include /* libopendaap */ /* sourcelist */ int sourcelist_init(GladeXML *xml); -int sourcelist_append(void *host, char *name); +int sourcelist_append(DAAP_SClientHost *host, gchar *name); int sourcelist_clear(); +gboolean sourcelist_set_source_connect_state_by_host(DAAP_SClientHost *host, + gboolean connected); +void sourcelist_mark_all(gboolean mark); +gboolean sourcelist_host_is_present(DAAP_SClientHost *host); +gboolean sourcelist_mark_by_host(DAAP_SClientHost *host, gboolean mark); +GList *sourcelist_get_marked_host_list(gboolean mark, gboolean delete); +gboolean sourcelist_remove_by_host(DAAP_SClientHost *host); +gboolean sourcelist_set_sharename_by_host(DAAP_SClientHost *host, gchar *sharename); +gboolean sourcelist_set_databases_by_host(DAAP_SClientHost *host, + DAAP_ClientHost_Database *databases, + int num_databases); +gboolean sourcelist_set_cached_by_host(DAAP_SClientHost *host, + int dbid); +gint sourcelist_get_cached_by_host(DAAP_SClientHost *host); /* artistlist */ int artistlist_init(GladeXML *xml); diff -X dontdiff -urNp tunesbrowser-0.1.7-pre2/sourcelist.c tunesbrowser-dsd/sourcelist.c --- tunesbrowser-0.1.7-pre2/sourcelist.c 2004-11-22 06:58:07.000000000 +0000 +++ tunesbrowser-dsd/sourcelist.c 2004-12-11 03:42:20.848813616 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include /* libopendaap */ #include "lists.h" #include "tunesbrowser.h" @@ -42,10 +43,14 @@ static GdkPixbuf *party_shuffle_image; enum { - IMAGE_COLUMN, - SOURCE_COLUMN, - HOST_COLUMN, - SOURCE_N_COLUMNS + SOURCE_IMAGE, + SOURCE_SHARENAME, + SOURCE_HOST, + SOURCE_DB, + SOURCE_DB_COUNT, + SOURCE_MARKED, + SOURCE_CACHED_DB_ID, + SOURCE_NUM_COLUMNS }; #define XSTR(s) STR(s) @@ -66,9 +71,9 @@ static void add_party_shuffle() gtk_list_store_append(sourcelist, &iter); gtk_list_store_set(sourcelist, &iter, - IMAGE_COLUMN, party_shuffle_image, - SOURCE_COLUMN, "Party Shuffle", - HOST_COLUMN, NULL, + SOURCE_IMAGE, party_shuffle_image, + SOURCE_SHARENAME, "Party Shuffle", + SOURCE_HOST, NULL, -1); } @@ -80,10 +85,15 @@ int sourcelist_init(GladeXML *xml) load_images(); - sourcelist = gtk_list_store_new (SOURCE_N_COLUMNS, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_POINTER); + sourcelist = gtk_list_store_new (SOURCE_NUM_COLUMNS, + GDK_TYPE_PIXBUF, // image + G_TYPE_STRING, // sharename + G_TYPE_POINTER, // host + G_TYPE_POINTER, // database + G_TYPE_INT, // db count + G_TYPE_BOOLEAN, // marked + G_TYPE_INT); // cached db id + sourcetreeview = GTK_TREE_VIEW(glade_xml_get_widget(xml, "source")); gtk_tree_view_set_model(sourcetreeview, GTK_TREE_MODEL(sourcelist)); @@ -91,14 +101,14 @@ int sourcelist_init(GladeXML *xml) renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new_with_attributes("", renderer, - "pixbuf", IMAGE_COLUMN, + "pixbuf", SOURCE_IMAGE, NULL); gtk_tree_view_append_column (sourcetreeview, column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Source", renderer, - "text", SOURCE_COLUMN, + "text", SOURCE_SHARENAME, NULL); gtk_tree_view_append_column (sourcetreeview, column); @@ -113,16 +123,20 @@ int sourcelist_init(GladeXML *xml) return 1; } -int sourcelist_append(void *host, char *name) +int sourcelist_append(DAAP_SClientHost *host, gchar *name) { GtkTreeIter iter; gtk_list_store_append(sourcelist, &iter); gtk_list_store_set(sourcelist, &iter, - IMAGE_COLUMN, remote_host_notconnected_image, - SOURCE_COLUMN, name, - HOST_COLUMN, host, + SOURCE_IMAGE, remote_host_notconnected_image, + SOURCE_SHARENAME, name, + SOURCE_HOST, host, + SOURCE_DB, NULL, + SOURCE_DB_COUNT, 0, + SOURCE_MARKED, TRUE, + SOURCE_CACHED_DB_ID, 0, -1); return 1; @@ -135,29 +149,45 @@ int sourcelist_clear() return 1; } -void sourcelist_set_source_connect_state(void *host, int connected) +static gboolean get_iter_from_host(DAAP_SClientHost *host, GtkTreeIter *dest) { GtkTreeIter iter; - if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sourcelist), - &iter)) + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sourcelist), &iter)) + return FALSE; + + do { - do + DAAP_SClientHost *curhost; + gtk_tree_model_get(GTK_TREE_MODEL(sourcelist), &iter, + SOURCE_HOST, &curhost, + -1); + if (curhost == host) { - void *iter_host = NULL; - gtk_tree_model_get(GTK_TREE_MODEL(sourcelist), &iter, - HOST_COLUMN, &iter_host, - -1); - if (iter_host == host) - { - gtk_list_store_set(sourcelist, &iter, - IMAGE_COLUMN, - connected ? remote_host_connected_image : - remote_host_notconnected_image, - -1); - } - } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(sourcelist), - &iter)); - } + if (dest) + *dest = iter; + return TRUE; + } + + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(sourcelist), &iter)); + + return FALSE; +} + +gboolean sourcelist_set_source_connect_state_by_host(DAAP_SClientHost *host, + gboolean connected) +{ + GtkTreeIter iter; + + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_list_store_set(sourcelist, &iter, + SOURCE_IMAGE, + connected ? remote_host_connected_image : + remote_host_notconnected_image, + -1); + return TRUE; } /* callback */ @@ -166,12 +196,12 @@ static void on_source_selection_changed( { GtkTreeIter iter; GtkTreeModel *model; - gpointer *host; + DAAP_SClientHost *host; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get (model, &iter, - HOST_COLUMN, &host, + SOURCE_HOST, &host, -1); if (!host) return; /* disable party shuffle for now */ @@ -180,5 +210,138 @@ static void on_source_selection_changed( } +static gboolean set_all_marked_fe(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer mark) +{ + gtk_list_store_set(GTK_LIST_STORE(model), iter, + SOURCE_MARKED, GPOINTER_TO_INT(mark), + -1); + return FALSE; +} +void sourcelist_mark_all(gboolean mark) +{ + gtk_tree_model_foreach(GTK_TREE_MODEL(sourcelist), set_all_marked_fe, GINT_TO_POINTER(mark)); +} +gboolean sourcelist_host_is_present(DAAP_SClientHost *host) +{ + return get_iter_from_host(host, NULL); +} + +gboolean sourcelist_mark_by_host(DAAP_SClientHost *host, gboolean mark) +{ + GtkTreeIter iter; + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_list_store_set(sourcelist, &iter, + SOURCE_MARKED, mark, + -1); + + return TRUE; +} + +GList *sourcelist_get_marked_host_list(gboolean mark, gboolean delete) +{ + GList *ret = NULL; + GtkTreeIter iter; + + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sourcelist), &iter)) + return NULL; + + do + { + DAAP_SClientHost *curhost; + gboolean curmark; + gtk_tree_model_get(GTK_TREE_MODEL(sourcelist), &iter, + SOURCE_HOST, &curhost, + SOURCE_MARKED, &curmark, + -1); + if (curhost && curmark == mark) + ret = g_list_append(ret, curhost); + + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(sourcelist), &iter)); + + if (delete) + g_list_foreach(ret, (GFunc) sourcelist_remove_by_host, NULL); + + return ret; + +} + +gboolean sourcelist_remove_by_host(DAAP_SClientHost *host) +{ + GtkTreeIter iter; + + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_list_store_remove(sourcelist, &iter); + return TRUE; +} + +gboolean sourcelist_set_sharename_by_host(DAAP_SClientHost *host, gchar *sharename) +{ + GtkTreeIter iter; + + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_list_store_set(sourcelist, &iter, + SOURCE_SHARENAME, sharename, + -1); + return TRUE; +} + +gboolean sourcelist_set_databases_by_host(DAAP_SClientHost *host, + DAAP_ClientHost_Database *databases, + int num_databases) +{ + GtkTreeIter iter; + DAAP_ClientHost_Database *currentdb; + + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_tree_model_get(GTK_TREE_MODEL(sourcelist), &iter, + SOURCE_DB, ¤tdb, + -1); + g_free(currentdb); + + gtk_list_store_set(sourcelist, &iter, + SOURCE_DB, databases, + SOURCE_DB_COUNT, num_databases, + -1); + + return TRUE; +} + +// set cached if dbid > 0, else set uncached +gboolean sourcelist_set_cached_by_host(DAAP_SClientHost *host, + int dbid) +{ + GtkTreeIter iter; + + if (!get_iter_from_host(host, &iter)) + return FALSE; + + gtk_list_store_set(sourcelist, &iter, + SOURCE_CACHED_DB_ID, dbid, + -1); + return TRUE; +} + +gint sourcelist_get_cached_by_host(DAAP_SClientHost *host) +{ + GtkTreeIter iter; + gint dbid; + + if (!get_iter_from_host(host, &iter)) + return 0; + + gtk_tree_model_get(GTK_TREE_MODEL(sourcelist), &iter, + SOURCE_CACHED_DB_ID, &dbid, + -1); + return dbid; +} diff -X dontdiff -urNp tunesbrowser-0.1.7-pre2/tunesbrowser.h tunesbrowser-dsd/tunesbrowser.h --- tunesbrowser-0.1.7-pre2/tunesbrowser.h 2004-10-30 14:45:40.000000000 +0100 +++ tunesbrowser-dsd/tunesbrowser.h 2004-12-11 03:38:54.358204960 +0000 @@ -28,7 +28,7 @@ void init_daap(); void init_daap_sources(); -void set_daap_sources(void *host); +void set_daap_sources(DAAP_SClientHost *host); void finalize_daap_sources(); void set_daap_artistfilter(char *name);