From b73b77f43a7dcb9d6f28806bf2c3cba0fc6f7aa2 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Mon, 12 Jul 2010 14:02:57 +0200 Subject: Add support for new iconstate format and displaying folder icons --- src/sbmgr.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 121 insertions(+), 22 deletions(-) (limited to 'src/sbmgr.c') diff --git a/src/sbmgr.c b/src/sbmgr.c index 2a3502c..ec6d707 100644 --- a/src/sbmgr.c +++ b/src/sbmgr.c @@ -23,6 +23,7 @@ * USA */ +#include #include #include #include @@ -62,7 +63,7 @@ void sbmgr_load(const char *uuid, device_info_cb_t info_cb, finished_cb_t finish g_thread_create((GThreadFunc)gui_pages_load_cb, (gpointer)uuid, FALSE, NULL); } -static gboolean iconstate_changed(plist_t current_state, plist_t new_state) +static gboolean iconstate_changed_v1(plist_t current_state, plist_t new_state) { if (!current_state || !new_state) { return FALSE; @@ -124,44 +125,142 @@ static gboolean iconstate_changed(plist_t current_state, plist_t new_state) return FALSE; } -void sbmgr_save(const char *uuid) +static gboolean iconstate_changed_v2(plist_t current_state, plist_t new_state) { - plist_t iconstate = gui_get_iconstate(); - if (iconstate) { - GError *error = NULL; - sbservices_client_t sbc; + if (!current_state || !new_state) { + return FALSE; + } - sbc = device_sbs_new(uuid, NULL, &error); + /* compare new state with last saved state */ + uint32_t cur_cnt = plist_array_get_size(current_state); + uint32_t new_cnt = plist_array_get_size(new_state); + debug_printf("%s: old %d, new %d\n", __func__, cur_cnt, new_cnt); + if (cur_cnt != new_cnt) { + /* number of pages has changed! */ + debug_printf("%s: number of pages changed!\n", __func__); + return TRUE; + } - if (error) { - g_printerr("%s", error->message); - g_error_free(error); - error = NULL; + /* now dig deeper */ + uint32_t i; + for (i = 0; i < new_cnt; i++) { + plist_t cur_pp = plist_array_get_item(current_state, i); + plist_t new_pp = plist_array_get_item(new_state, i); + if (plist_get_node_type(plist_array_get_item(new_pp, 0)) == PLIST_ARRAY) { + new_pp = plist_array_get_item(new_pp, 0); + } + if (plist_get_node_type(plist_array_get_item(cur_pp, 0)) == PLIST_ARRAY) { + cur_pp = plist_array_get_item(cur_pp, 0); } - if (sbc) { - plist_t current_state = NULL; - device_sbs_get_iconstate(sbc, ¤t_state, &error); + uint32_t cur_item_cnt = plist_array_get_size(cur_pp); + uint32_t new_item_cnt = plist_array_get_size(new_pp); + if (cur_item_cnt != new_item_cnt) { + fprintf(stderr, "%s: number of items on page %d changed: old %d, new %d\n", __func__, i, cur_item_cnt, new_item_cnt); + return TRUE; + } + uint32_t k; + for (k = 0; k < cur_item_cnt; k++) { + plist_t cur_node = plist_array_get_item(cur_pp, k); + plist_t new_node = plist_array_get_item(new_pp, k); + if (plist_get_node_type(cur_node) == PLIST_DICT) { + /* ok, compare the displayIdentifier */ + plist_t cur_di = plist_dict_get_item(cur_node, "displayIdentifier"); + plist_t new_di = plist_dict_get_item(new_node, "displayIdentifier"); + if (!cur_di && !new_di) { + cur_di = plist_dict_get_item(cur_node, "displayName"); + new_di = plist_dict_get_item(new_node, "displayName"); + if (plist_compare_node_value(cur_di, new_di) == FALSE) { + debug_printf("%s: page %d folder item %d displayName changed!\n", __func__, i, k); + return TRUE; + } + cur_di = plist_dict_get_item(cur_di, "iconLists"); + new_di = plist_dict_get_item(new_di, "iconLists"); + cur_di = plist_array_get_item(cur_di, 0); + new_di = plist_array_get_item(new_di, 0); + if (plist_array_get_size(cur_di) != plist_array_get_size(new_di)) { + debug_printf("%s: page %d folder item %d subitem count changed!\n", __func__, i, k); + return TRUE; + } + uint32_t j; + for (j = 0; j < plist_array_get_size(cur_di); j++) { + plist_t cur_si = plist_array_get_item(cur_di, j); + plist_t new_si = plist_array_get_item(new_di, j); + if (plist_compare_node_value(cur_si, new_si) == FALSE) { + debug_printf("%s: page %d folder item %d subitem %d changed!\n", __func__, i, k, j); + return TRUE; + } + } + } else if ((!cur_di && new_di) || (cur_di && !new_di)) { + debug_printf("%s: page %d item %d changed!\n", __func__, i, k); + return TRUE; + } else { + if (plist_compare_node_value(cur_di, new_di) == FALSE) { + debug_printf("%s: page %d item %d changed!\n", __func__, i, k); + return TRUE; + } + } + } + } + } + + /* no change found */ + debug_printf("%s: no change!\n", __func__); + return FALSE; +} + +static gboolean iconstate_changed(plist_t current_state, plist_t new_state, const char *format_version) +{ + if (format_version && (strcmp(format_version, "2") == 0)) { + return iconstate_changed_v2(current_state, new_state); + } else { + return iconstate_changed_v1(current_state, new_state); + } +} + +void sbmgr_save(const char *uuid) +{ + GError *error = NULL; + sbservices_client_t sbc; + uint32_t osversion = 0; + + sbc = device_sbs_new(uuid, &osversion, &error); + + if (error) { + g_printerr("%s", error->message); + g_error_free(error); + error = NULL; + } + + if (sbc) { + plist_t current_state = NULL; + const char *fmt_version = NULL; + if (osversion >= 0x04000000) { + fmt_version = "2"; + } + plist_t iconstate = gui_get_iconstate(fmt_version); + if (iconstate) { + device_sbs_get_iconstate(sbc, ¤t_state, fmt_version, &error); if (error) { g_printerr("%s", error->message); g_error_free(error); error = NULL; } - if (iconstate_changed(current_state, iconstate) == TRUE) { + if (iconstate_changed(current_state, iconstate, fmt_version) == TRUE) { device_sbs_set_iconstate(sbc, iconstate, &error); } if (current_state) { plist_free(current_state); } - device_sbs_free(sbc); + plist_free(iconstate); } - plist_free(iconstate); + device_sbs_free(sbc); + } - if (error) { - g_printerr("%s", error->message); - g_error_free(error); - error = NULL; - } + if (error) { + g_printerr("%s", error->message); + g_error_free(error); + error = NULL; } } -- cgit v1.1-32-gdbae