diff options
| author | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-03-16 15:34:34 +0000 |
|---|---|---|
| committer | Jorg Schuler <jcsjcs@users.sourceforge.net> | 2006-03-16 15:34:34 +0000 |
| commit | d3bab54a791fbc5b7835e069dcada96fb6c82efe (patch) | |
| tree | c5a18421b35013c3fcd1ac5dbe72daa649a30b2b /src/itdb_device.c | |
| parent | 435acf166a4aeda13d14ce7818fa33f2b7855b4f (diff) | |
| download | libgpod-d3bab54a791fbc5b7835e069dcada96fb6c82efe.tar.gz libgpod-d3bab54a791fbc5b7835e069dcada96fb6c82efe.tar.xz libgpod-d3bab54a791fbc5b7835e069dcada96fb6c82efe.zip | |
* itdb_device.[ch]: rewrote ipod-device.c, removed all hal-code,
removed all code irrelevant to writing the iTunesDB and
ArtworkDB.
* autodetect iControl directory now also works for ArtworkDB.
* db-artwork-parser.c (ipod_db_get_artwork_db_path): create
Artwork directory if not already present.
* itdb.h: Itdb_iTunesDB: moved mountpoint and musicdirs into
private Itdb_Device. Use itdb_set_mountpoint() and
itdb_get_mountpoint() to access the mountpoint.
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1220 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'src/itdb_device.c')
| -rw-r--r-- | src/itdb_device.c | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/src/itdb_device.c b/src/itdb_device.c new file mode 100644 index 0000000..c0fe191 --- /dev/null +++ b/src/itdb_device.c @@ -0,0 +1,431 @@ +/* Time-stamp: <2006-03-17 00:02:22 jcs> +| +| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net> +| Part of the gtkpod project. +| +| URL: http://www.gtkpod.org/ +| URL: http://gtkpod.sourceforge.net/ +| +| Part of this code is based on ipod-device.c from the libipoddevice +| project (http://64.14.94.162/index.php/Libipoddevice). +| +| The code contained in this file is free software; you can redistribute +| it and/or modify it under the terms of the GNU Lesser General Public +| License as published by the Free Software Foundation; either version +| 2.1 of the License, or (at your option) any later version. +| +| This file 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 +| Lesser General Public License for more details. +| +| You should have received a copy of the GNU Lesser General Public +| License along with this code; if not, write to the Free Software +| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +| USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +| $Id$ +*/ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "itdb_device.h" + +#define GB 1024 + +static const Itdb_IpodModel ipod_model_table [] = { + /* Handle idiots who hose their iPod file system, or + lucky people with iPods we don't yet know about*/ + {"Invalid", 0, MODEL_TYPE_INVALID, UNKNOWN_GENERATION}, + {"Unknown", 0, MODEL_TYPE_UNKNOWN, UNKNOWN_GENERATION}, + + /* First Generation */ + {"8513", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, + {"8541", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, + {"8697", 5 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, + {"8709", 10 * GB, MODEL_TYPE_REGULAR, FIRST_GENERATION}, + + /* Second Generation */ + {"8737", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, + {"8740", 10 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, + {"8738", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, + {"8741", 20 * GB, MODEL_TYPE_REGULAR, SECOND_GENERATION}, + + /* Third Generation */ + {"8976", 10 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + {"8946", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + {"9460", 15 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + {"9244", 20 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + {"8948", 30 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + {"9245", 40 * GB, MODEL_TYPE_REGULAR, THIRD_GENERATION}, + + + /* Fourth Generation */ + {"9282", 20 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, + {"9787", 25 * GB, MODEL_TYPE_REGULAR_U2, FOURTH_GENERATION}, + {"9268", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, + {"A079", 20 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + {"A127", 20 * GB, MODEL_TYPE_COLOR_U2, FOURTH_GENERATION}, + {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + + /* First Generation Mini */ + {"9160", 4 * GB, MODEL_TYPE_MINI, FIRST_GENERATION}, + {"9436", 4 * GB, MODEL_TYPE_MINI_BLUE, FIRST_GENERATION}, + {"9435", 4 * GB, MODEL_TYPE_MINI_PINK, FIRST_GENERATION}, + {"9434", 4 * GB, MODEL_TYPE_MINI_GREEN, FIRST_GENERATION}, + {"9437", 4 * GB, MODEL_TYPE_MINI_GOLD, FIRST_GENERATION}, + + /* Second Generation Mini */ + {"9800", 4 * GB, MODEL_TYPE_MINI, SECOND_GENERATION}, + {"9802", 4 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION}, + {"9804", 4 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION}, + {"9806", 4 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION}, + {"9801", 6 * GB, MODEL_TYPE_MINI, SECOND_GENERATION}, + {"9803", 6 * GB, MODEL_TYPE_MINI_BLUE, SECOND_GENERATION}, + {"9805", 6 * GB, MODEL_TYPE_MINI_PINK, SECOND_GENERATION}, + {"9807", 6 * GB, MODEL_TYPE_MINI_GREEN, SECOND_GENERATION}, + + /* Photo / Fourth Generation */ + {"9829", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + {"9585", 40 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + {"9586", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + {"9830", 60 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + + /* Shuffle / Fourth Generation */ + {"9724", GB / 2, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION}, + {"9725", GB, MODEL_TYPE_SHUFFLE, FOURTH_GENERATION}, + + /* Nano / Fifth Generation */ + {"A350", GB * 1, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, + {"A352", GB * 1, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, + {"A004", GB * 2, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, + {"A099", GB * 2, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, + {"A005", GB * 4, MODEL_TYPE_NANO_WHITE, FIFTH_GENERATION}, + {"A107", GB * 4, MODEL_TYPE_NANO_BLACK, FIFTH_GENERATION}, + + /* Video / Fifth Generation */ + {"A002", GB * 30, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION}, + {"A146", GB * 30, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION}, + {"A003", GB * 60, MODEL_TYPE_VIDEO_WHITE, FIFTH_GENERATION}, + {"A147", GB * 60, MODEL_TYPE_VIDEO_BLACK, FIFTH_GENERATION}, + + /* HP iPods, need contributions for this table */ + {"E436", 40 * GB, MODEL_TYPE_REGULAR, FOURTH_GENERATION}, + {"S492", 30 * GB, MODEL_TYPE_COLOR, FOURTH_GENERATION}, + + {NULL, 0, 0, 0} +}; + +#if 0 +static const gchar *ipod_model_name_table [] = { + "Invalid", + "Unknown", + "Color", + "Color U2", + "Grayscale", + "Grayscale U2", + "Mini (Silver)", + "Mini (Blue)", + "Mini (Pink)", + "Mini (Green)", + "Mini (Gold)", + "Shuffle", + "Nano (White)", + "Nano (Black)", + "Video (White)", + "Video (Black)", + NULL +}; +#endif + +static const Itdb_ArtworkFormat ipod_color_artwork_info[] = { + {IPOD_COVER_SMALL, 56, 56, 1017}, + {IPOD_COVER_LARGE, 140, 140, 1016}, + {IPOD_PHOTO_SMALL, 42, 30, 1009}, + {IPOD_PHOTO_LARGE, 130, 88, 1015}, + {IPOD_PHOTO_FULL_SCREEN, 220, 176, 1013}, + {IPOD_PHOTO_TV_SCREEN, 720, 480, 1019}, + {-1, -1, -1, -1} +}; + +static const Itdb_ArtworkFormat ipod_nano_artwork_info[] = { + {IPOD_COVER_SMALL, 42, 42, 1031}, + {IPOD_COVER_LARGE, 100, 100, 1027}, + {IPOD_PHOTO_LARGE, 42, 37, 1032}, + {IPOD_PHOTO_FULL_SCREEN, 176, 132, 1023}, + {-1, -1, -1, -1} +}; + +static const Itdb_ArtworkFormat ipod_video_artwork_info[] = { + {IPOD_COVER_SMALL, 100, 100, 1028}, + {IPOD_COVER_LARGE, 200, 200, 1029}, + {IPOD_PHOTO_SMALL, 50, 41, 1036}, + {IPOD_PHOTO_LARGE, 130, 88, 1015}, + {IPOD_PHOTO_FULL_SCREEN, 320, 240, 1024}, + {IPOD_PHOTO_TV_SCREEN, 720, 480, 1019}, + {-1, -1, -1, -1} +}; + +/* This will be indexed using a value from the MODEL_TYPE enum */ +static const Itdb_ArtworkFormat *ipod_artwork_info_table[] = { + NULL, /* Invalid */ + NULL, /* Unknown */ + ipod_color_artwork_info, /* Color */ + ipod_color_artwork_info, /* Color U2 */ + NULL, /* Grayscale */ + NULL, /* Grayscale U2 */ + NULL, /* Mini (Silver) */ + NULL, /* Mini (Blue) */ + NULL, /* Mini (Pink) */ + NULL, /* Mini (Green) */ + NULL, /* Mini (Gold) */ + NULL, /* Shuffle */ + ipod_nano_artwork_info, /* Nano (White) */ + ipod_nano_artwork_info, /* Nano (Black) */ + ipod_video_artwork_info, /* Video (White) */ + ipod_video_artwork_info /* Video (Black) */ +}; + + +/* Reset or create the SysInfo hash table */ +static void itdb_device_reset_sysinfo (Itdb_Device *device) +{ + if (device->sysinfo) + g_hash_table_destroy (device->sysinfo); + device->sysinfo = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); +} + + +/* Create new Itdb_Device structure */ +Itdb_Device *itdb_device_new () +{ + Itdb_Device *dev; + + dev = g_new0 (Itdb_Device, 1); + itdb_device_reset_sysinfo (dev); + return dev; +} + +/* Free memory used by @device */ +void itdb_device_free (Itdb_Device *device) +{ + if (device) + { + g_free (device->mountpoint); + if (device->sysinfo) + g_hash_table_destroy (device->sysinfo); + g_free (device); + } +} + + +/* Set mountpoint and read SysInfo file */ +void itdb_device_set_mountpoint (Itdb_Device *device, const gchar *mp) +{ + g_return_if_fail (device); + + g_free (device->mountpoint); + device->mountpoint = g_strdup (mp); + if (mp) + itdb_device_read_sysinfo (device); +} + + +/* Read SysInfo file and store information in device->sysinfo for + * later use. + * + * Return value: TRUE if file could be read, FALSE otherwise */ +gboolean itdb_device_read_sysinfo (Itdb_Device *device) +{ + const gchar *p_sysinfo[] = {"SysInfo", NULL}; + gchar *dev_path, *sysinfo_path; + FILE *fd; + gboolean result = FALSE; + gchar buf[1024]; + + g_return_val_if_fail (device, FALSE); + g_return_val_if_fail (device->mountpoint, FALSE); + + itdb_device_reset_sysinfo (device); + + g_return_val_if_fail (device->sysinfo, FALSE); + + dev_path = itdb_get_device_dir (device->mountpoint); + + if (!dev_path) return FALSE; + + sysinfo_path = itdb_resolve_path (dev_path, p_sysinfo); + + if (sysinfo_path) + { + fd = fopen (sysinfo_path, "r"); + if (fd) + { + result = TRUE; + while(fgets(buf, sizeof(buf), fd)) + { + gchar *ptr; + gint len = strlen (buf); + /* suppress newline at end of line */ + if ((len>0) && (buf[len-1]==0x0a)) + { + buf[len-1] = 0; + --len; + } + ptr = strchr (buf, ':'); + if (ptr && (ptr!=buf)) + { + gchar *key, *value; + *ptr = 0; + ++ptr; + key = g_strdup (buf); + g_strstrip (ptr); + value = g_strdup (ptr); + g_hash_table_insert (device->sysinfo, key, value); + } + } + fclose (fd); + } + g_free (sysinfo_path); + } + g_free (dev_path); + return result; +} + + +/* Retrieve specified field from the SysInfo file. + * + * Return value: g_free() after use + */ +gchar *itdb_device_get_sysinfo (Itdb_Device *device, const gchar *field) +{ + g_return_val_if_fail (device, NULL); + g_return_val_if_fail (device->sysinfo, NULL); + g_return_val_if_fail (field, NULL); + + return g_strdup (g_hash_table_lookup (device->sysinfo, field)); +} + + +/* Return Itdb_IpodModel entry for this iPod */ +G_GNUC_INTERNAL const Itdb_IpodModel * +itdb_device_get_ipod_model (Itdb_Device *device) +{ + gint i; + gchar *model_num, *p; + + model_num = itdb_device_get_sysinfo (device, "ModelNumStr"); + + if (!model_num) + return &ipod_model_table[0]; + + p = model_num; + + if(isalpha(model_num[0])) + p++; + + for(i=2; ipod_model_table[i].model_number != NULL; i++) + { + if(g_strncasecmp(p, ipod_model_table[i].model_number, 4) == 0) + { + g_free(model_num); + return &ipod_model_table[i]; + } + } + g_free(model_num); + return &ipod_model_table[1]; +} + + +/* Return supported artwork formats supported by this iPod */ +G_GNUC_INTERNAL const Itdb_ArtworkFormat * +itdb_device_get_artwork_formats (Itdb_Device *device) +{ + const Itdb_IpodModel *model; + + g_return_val_if_fail (device, NULL); + + model = itdb_device_get_ipod_model (device); + + g_return_val_if_fail (model, NULL); + + return ipod_artwork_info_table[model->model_type]; +} + + +/* Determine the number of F.. directories in iPod_Control/Music. + + If device->musicdirs is already set, simply return the previously + determined number. Otherwise count the directories first and set + itdb->musicdirs. */ +G_GNUC_INTERNAL gint +itdb_device_musicdirs_number (Itdb_Device *device) +{ + gchar *dir_filename = NULL; + gint dir_num; + + g_return_val_if_fail (device, 0); + + if (device->musicdirs <= 0) + { + gchar *music_dir = itdb_get_music_dir (device->mountpoint); + if (!music_dir) return 0; + /* count number of dirs */ + for (dir_num=0; ;++dir_num) + { + gchar dir_num_str[5]; + + g_snprintf (dir_num_str, 5, "F%02d", dir_num); + + dir_filename = itdb_get_path (music_dir, dir_num_str); + + if (!dir_filename) break; + g_free (dir_filename); + } + device->musicdirs = dir_num; + g_free (music_dir); + } + return device->musicdirs; +} + + +/* Attempt to guess the endianess used by this iPod. + * + * It will overwrite the previous setting. + * + */ + +G_GNUC_INTERNAL void +itdb_device_autodetect_endianess (Itdb_Device *device) +{ + g_return_if_fail (device); + + /* endianess_set will be set to FALSE. This field is only set to + TRUE when importing an iTunesDB. */ + device->endianess_set = FALSE; + /* default: non-reversed */ + device->endianess_reversed = FALSE; + + if (device->mountpoint) + { + gchar *control_dir = itdb_get_control_dir (device->mountpoint); + + if (control_dir) + { + gchar *cd_l = g_ascii_strdown (control_dir, -1); + if (strstr (cd_l, "itunes/itunes_control") == + (cd_l + strlen (cd_l) - strlen ("itunes/itunes_control"))) + { + device->endianess_reversed = TRUE; + } + g_free (cd_l); + g_free (control_dir); + } + } +} |
