diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Artwork.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Artwork.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Artwork.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Artwork.cs 2010-09-30 00:44:31.000000000 +0800 @@ -26,15 +26,15 @@ namespace native { [StructLayout (LayoutKind.Sequential)] internal struct Itdb_Artwork { - public IntPtr thumbnail; - public uint id; - public ulong dbid; - public int unk028; - public uint rating; - public int unk036; - public IntPtr creation_date; - public IntPtr digitized_date; - public uint artwork_size; + public IntPtr thumbnail; + public uint id; + public ulong dbid; + public int unk028; + public uint rating; + public int unk036; + public IntPtr creation_date; + public IntPtr digitized_date; + public uint artwork_size; // Ignore the rest [DllImport ("gpod")] @@ -64,20 +64,20 @@ } public unsafe class Artwork : GPodBase { - public Thumbnail Thumbnail { get { return new Thumbnail(((Itdb_Artwork *) Native)->thumbnail); } - set { ((Itdb_Artwork *) Native)->thumbnail = HandleRef.ToIntPtr(value.Handle); } } - public uint Rating { get { return ((Itdb_Artwork *) Native)->rating / 20; } - set { ((Itdb_Artwork *) Native)->rating = (value > 5 ? 5 : value) * 20; } } - public DateTime TimeCreated { get { return Artwork.time_tToDateTime (((Itdb_Artwork *) Native)->creation_date); } - set { ((Itdb_Artwork *) Native)->creation_date = Artwork.DateTimeTotime_t(value); } } + public Thumbnail Thumbnail { get { return new Thumbnail(((Itdb_Artwork *) Native)->thumbnail); } + set { ((Itdb_Artwork *) Native)->thumbnail = HandleRef.ToIntPtr(value.Handle); } } + public uint Rating { get { return ((Itdb_Artwork *) Native)->rating / 20; } + set { ((Itdb_Artwork *) Native)->rating = (value > 5 ? 5 : value) * 20; } } + public DateTime TimeCreated { get { return Artwork.time_tToDateTime (((Itdb_Artwork *) Native)->creation_date); } + set { ((Itdb_Artwork *) Native)->creation_date = Artwork.DateTimeTotime_t(value); } } public DateTime TimeDigitized { get { return Artwork.time_tToDateTime (((Itdb_Artwork *) Native)->digitized_date); } - set { ((Itdb_Artwork *) Native)->digitized_date = Artwork.DateTimeTotime_t(value); } } - public uint Size { get { return ((Itdb_Artwork *) Native)->artwork_size; } - set { ((Itdb_Artwork *) Native)->artwork_size = value; } } + set { ((Itdb_Artwork *) Native)->digitized_date = Artwork.DateTimeTotime_t(value); } } + public uint Size { get { return ((Itdb_Artwork *) Native)->artwork_size; } + set { ((Itdb_Artwork *) Native)->artwork_size = value; } } public Artwork(IntPtr handle, bool borrowed) : base(handle, borrowed) {} public Artwork(IntPtr handle) : base(handle) {} - public Artwork() : base(Itdb_Artwork.itdb_artwork_new (), false) {} + public Artwork() : base(Itdb_Artwork.itdb_artwork_new(), false) {} public Artwork(Artwork other) : base(Itdb_Artwork.itdb_artwork_duplicate(other.Handle), false) {} protected override void Destroy() { Itdb_Artwork.itdb_artwork_free(Handle); } diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Chapter.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Chapter.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Chapter.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Chapter.cs 2010-09-30 00:44:31.000000000 +0800 @@ -24,9 +24,9 @@ namespace native { [StructLayout (LayoutKind.Sequential)] internal struct Itdb_Chapter { - public uint startpos; - public IntPtr chaptertitle; - // Ignore the rest + public uint startpos; + public IntPtr chaptertitle; + // Ignore the rest [DllImport ("gpod")] internal static extern IntPtr itdb_chapter_new(); @@ -60,4 +60,4 @@ set { var x = (Itdb_Chapter *) Native; ReplaceStringUTF8 (ref x->chaptertitle, value); } } } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/ChapterData.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/ChapterData.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/ChapterData.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/ChapterData.cs 2010-09-30 00:44:31.000000000 +0800 @@ -26,7 +26,7 @@ namespace native { internal struct Itdb_ChapterData { public IntPtr chapters; - // Ignore the rest + // Ignore the rest [DllImport ("gpod")] internal static extern IntPtr itdb_chapterdata_new(); @@ -59,6 +59,12 @@ this[index].SetBorrowed(false); // We're creating a new object here, so just deallocate the old one Itdb_ChapterData.itdb_chapterdata_add_chapter(handle, item.StartPosition, item.Title); } + + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_ChapterData *) handle.Handle)->chapters, typeof(Chapter)); + } + } } public unsafe class ChapterData : GPodBase { diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Device.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Device.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Device.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Device.cs 2010-09-30 00:44:31.000000000 +0800 @@ -71,11 +71,11 @@ /* According to teuf, SysInfo is crusty and probably not needed * public class SysInfo { HandleRef Handle; - public SysInfo(HandleRef handle) { Handle = handle; } - public bool Read() { return Itdb_Device.itdb_device_read_sysinfo(Handle); } - public string Get(string field) { return Itdb_Device.itdb_device_get_sysinfo(Handle, field); } - public void Set(string field, string val) { Itdb_Device.itdb_device_set_sysinfo(Handle, field, val); } - public bool Write() { + public SysInfo(HandleRef handle) { Handle = handle; } + public bool Read() { return Itdb_Device.itdb_device_read_sysinfo(Handle); } + public string Get(string field) { return Itdb_Device.itdb_device_get_sysinfo(Handle, field); } + public void Set(string field, string val) { Itdb_Device.itdb_device_set_sysinfo(Handle, field, val); } + public bool Write() { IntPtr gerror; bool res = Itdb_Device.itdb_device_write_sysinfo(Handle, out gerror); if (gerror != IntPtr.Zero) @@ -85,20 +85,20 @@ }*/ public unsafe class Device : GPodBase { - public bool SupportsArtwork { get { return Itdb_Device.itdb_device_supports_artwork(Handle); } } - public bool SupportsChapterImage { get { return Itdb_Device.itdb_device_supports_chapter_image(Handle); } } - public bool SupportsPhoto { get { return Itdb_Device.itdb_device_supports_photo(Handle); } } - public bool SupportsPodcast { get { return Itdb_Device.itdb_device_supports_podcast(Handle); } } - public bool SupportsVideo { get { return Itdb_Device.itdb_device_supports_video(Handle); } } - //public SysInfo SysInfo { get { return new SysInfo(Handle); } } - public IpodInfo IpodInfo { get { return IpodInfo.Find (Itdb_Device.itdb_device_get_ipod_info(Handle)); } } - public string Mountpoint { get { return PtrToStringUTF8 (((Itdb_Device *)Native)->mountpoint); } - set { Itdb_Device.itdb_device_set_mountpoint(Handle, value); } } + public bool SupportsArtwork { get { return Itdb_Device.itdb_device_supports_artwork(Handle); } } + public bool SupportsChapterImage { get { return Itdb_Device.itdb_device_supports_chapter_image(Handle); } } + public bool SupportsPhoto { get { return Itdb_Device.itdb_device_supports_photo(Handle); } } + public bool SupportsPodcast { get { return Itdb_Device.itdb_device_supports_podcast(Handle); } } + public bool SupportsVideo { get { return Itdb_Device.itdb_device_supports_video(Handle); } } + //public SysInfo SysInfo { get { return new SysInfo(Handle); } } + public IpodInfo IpodInfo { get { return IpodInfo.Find (Itdb_Device.itdb_device_get_ipod_info(Handle)); } } + public string Mountpoint { get { return PtrToStringUTF8 (((Itdb_Device *)Native)->mountpoint); } + set { Itdb_Device.itdb_device_set_mountpoint(Handle, value); } } - public Device(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public Device(IntPtr handle) : base(handle) {} - public Device() : base(Itdb_Device.itdb_device_new(), false) {} - public Device(string mountpoint) : this() { Mountpoint = mountpoint; } + public Device(IntPtr handle, bool borrowed) : base(handle, borrowed) {} + public Device(IntPtr handle) : base(handle) {} + public Device() : base(Itdb_Device.itdb_device_new(), false) {} + public Device(string mountpoint) : this() { Mountpoint = mountpoint; } protected override void Destroy() { Itdb_Device.itdb_device_free(Handle); } } } diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/GPodBase.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/GPodBase.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/GPodBase.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/GPodBase.cs 2010-09-30 00:44:31.000000000 +0800 @@ -28,27 +28,38 @@ public abstract class GPodBase : IGPodBase, IDisposable { - protected static string PtrToStringUTF8 (IntPtr ptr) + protected static string PtrToStringUTF8(IntPtr ptr) { - return GLib.Marshaller.Utf8PtrToString (ptr); + return GLib.Marshaller.Utf8PtrToString(ptr); } - protected static void ReplaceStringUTF8 (ref IntPtr ptr, string str) + protected static void ReplaceStringUTF8(ref IntPtr ptr, string str) { - GLib.Marshaller.Free (ptr); - ptr = GLib.Marshaller.StringToPtrGStrdup (str); + GLib.Marshaller.Free(ptr); + ptr = GLib.Marshaller.StringToPtrGStrdup(str); } - protected static IntPtr DateTimeTotime_t (DateTime time) { - return GLib.Marshaller.DateTimeTotime_t (time); + static DateTime local_epoch = new DateTime(1970, 1, 1, 0, 0, 0); + static int utc_offset = (int) (TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now)).TotalSeconds; + + public static IntPtr DateTimeTotime_t(DateTime time) + { + // The itunes database uses a 32bit signed value, so enforce that here to avoid + // overflow issues. We still need to represent time with an IntPtr though as + // that's what libgpod publicly exposes + return new IntPtr(((int)time.Subtract(local_epoch).TotalSeconds) - utc_offset); } - - protected static DateTime time_tToDateTime (IntPtr time_t) { - return GLib.Marshaller.time_tToDateTime (time_t); + + public static DateTime time_tToDateTime(IntPtr time_t) + { + // The itunes database uses a 32bit signed value, so enforce that here to avoid + // overflow issues. We still need to represent time with an IntPtr though as + // that's what libgpod publicly exposes + return local_epoch.AddSeconds(time_t.ToInt32() + utc_offset); } internal IntPtr Native { - get { return HandleRef.ToIntPtr (Handle); } + get { return HandleRef.ToIntPtr(Handle); } } IntPtr IGPodBase.Native { @@ -61,16 +72,16 @@ public GPodBase(IntPtr handle) : this(handle, true) {} public GPodBase(IntPtr handle, bool borrowed) { Borrowed = borrowed; - Handle = new HandleRef (this, handle); + Handle = new HandleRef(this, handle); } ~GPodBase() { if (!Borrowed) Destroy(); } public void SetBorrowed(bool borrowed) { Borrowed = borrowed; } protected abstract void Destroy(); - public void Dispose () + public void Dispose() { if (!Borrowed) - Destroy (); + Destroy(); } } } diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/GPodList.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/GPodList.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/GPodList.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/GPodList.cs 2010-09-30 00:44:31.000000000 +0800 @@ -20,48 +20,52 @@ using System; using System.Collections; using System.Collections.Generic; + using System.Linq; using System.Runtime.InteropServices; using GLib; internal abstract class GPodList : IList where T : IGPodBase { - private class GPodListEnumerator : IEnumerator { - private System.Collections.IEnumerator enumerator; - public GPodListEnumerator(System.Collections.IEnumerator enumerator) { this.enumerator = enumerator; } - public T Current { get { return (T) enumerator.Current; } } - object IEnumerator.Current { get { return enumerator.Current; } } - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } protected HandleRef handle; - protected List list; + protected abstract GLib.List List { + get; + } protected bool owner; - public GPodList(bool owner, HandleRef handle, List list) { this.handle = handle; this.list = list; this.owner = owner; } - public GPodList(HandleRef handle, List list) : this(false, handle, list) {} - public GPodList(bool owner, HandleRef handle, IntPtr listp) : this(owner, handle, new List(listp, typeof(T))) {} - public GPodList(HandleRef handle, IntPtr listp) : this(false, handle, listp) {} + public GPodList(bool owner, HandleRef handle, List list) { this.handle = handle; this.owner = owner; } + public GPodList(HandleRef handle, List list) : this(false, handle, list) {} + public GPodList(bool owner, HandleRef handle, IntPtr listp) : this(owner, handle, null) {} + public GPodList(HandleRef handle, IntPtr listp) : this(false, handle, listp) {} - public int Count { get { return list.Count; } } + public int Count { get { return List.Count; } } public bool IsReadOnly { get { return false; } } - public T this[int index] { get { return (T) list[index]; } - set { RemoveAt(index); Insert(index, value); } } + public T this[int index] { get { return (T) List[index]; } + set { RemoveAt(index); Insert(index, value); } } - public void Add(T item) { DoAdd (-1, item); if (owner) item.SetBorrowed(true); } - public void Clear() { list.Empty(); } - public void CopyTo(T[] array, int arrayIndex) { list.CopyTo(array, arrayIndex); } - public IEnumerator GetEnumerator() { return new GPodListEnumerator(list.GetEnumerator()); } + public void Add(T item) { DoAdd (-1, item); if (owner) item.SetBorrowed(true); } + public void Clear() { /* Ensure we invoke DoUnlink */ while (Count > 0) RemoveAt (0); } + public void CopyTo(T[] array, int arrayIndex) { List.CopyTo(array, arrayIndex); } + public IEnumerator GetEnumerator() { + // Make an explicit copy of the list here to avoid memory + // corruption issues. What was happening is that managed land was + // instantiating a GLib.List from the native pointer, then if an + // item was unlinked from the native list, the GList in managed + // land would now be pointing at freed memory and would randomly + // blow up or crash. We work around this by instantiating a + // GLib.List every time and copying everything out immediately. + foreach (T t in List.Cast ().ToArray ()) + yield return t; + } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Contains(T item) { - return IndexOf (item) != -1; + return IndexOf(item) != -1; } public int IndexOf(T item) { int i = 0; foreach (T t in this) { - if (object.ReferenceEquals (t, item) || t.Native == item.Native) + if (object.ReferenceEquals(t, item) || t.Native == item.Native) return i; i++; } @@ -88,4 +92,4 @@ protected abstract void DoAdd(int index, T item); protected abstract void DoUnlink(int index); } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/IpodInfo.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/IpodInfo.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/IpodInfo.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/IpodInfo.cs 2010-09-30 00:44:31.000000000 +0800 @@ -123,23 +123,22 @@ } public sealed unsafe class IpodInfo : GPodBase { - public static IpodInfo[] Table = GetTable (); + public static IpodInfo[] Table = GetTable(); static unsafe IpodInfo[] GetTable() { Itdb_IpodInfo *table = (Itdb_IpodInfo *) Itdb_IpodInfo.itdb_info_get_ipod_info_table(); - List retval = new List (); + List retval = new List(); while (true) { Itdb_IpodInfo *item = &table [retval.Count]; if (item->model_number == IntPtr.Zero) break; - retval.Add (new IpodInfo ((IntPtr)item, true)); + retval.Add(new IpodInfo((IntPtr)item, true)); } - return retval.ToArray (); + return retval.ToArray(); } - internal static IpodInfo Find (IntPtr native) - { + internal static IpodInfo Find(IntPtr native) { for (int i = 0; i < Table.Length; i++) if (Table [i].Native == native) return Table [i]; @@ -156,7 +155,7 @@ } public string GenerationString { - get { return PtrToStringUTF8 (Itdb_IpodInfo.itdb_info_get_ipod_generation_string(this.Generation)); } + get { return PtrToStringUTF8(Itdb_IpodInfo.itdb_info_get_ipod_generation_string(this.Generation)); } } public IpodModel Model { @@ -164,28 +163,17 @@ } public string ModelNumber { - get { return PtrToStringUTF8 (((Itdb_IpodInfo *) Native)->model_number); } + get { return PtrToStringUTF8(((Itdb_IpodInfo *) Native)->model_number); } } public string ModelString { - get { return PtrToStringUTF8 (Itdb_IpodInfo.itdb_info_get_ipod_model_name_string(this.Model)); } + get { return PtrToStringUTF8(Itdb_IpodInfo.itdb_info_get_ipod_model_name_string(this.Model)); } } - IpodInfo (IntPtr handle, bool borrowed) - : base (handle, borrowed) - { - - } - - IpodInfo (IntPtr handle) - : base (handle) - { - - } - - protected override void Destroy() - { + IpodInfo (IntPtr handle, bool borrowed) : base (handle, borrowed) {} + IpodInfo (IntPtr handle) : base (handle) {} + protected override void Destroy() { // No need to free anything as it's a static array in native code. } } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/ITDB.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/ITDB.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/ITDB.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/ITDB.cs 2010-09-30 00:44:31.000000000 +0800 @@ -26,28 +26,28 @@ namespace native { internal struct Itdb_iTunesDB { public IntPtr tracks; - public IntPtr playlists; - public IntPtr filename; - public IntPtr device; + public IntPtr playlists; + public IntPtr filename; + public IntPtr device; // Ignore everything else [DllImport ("gpod")] internal static extern IntPtr itdb_new(); [DllImport ("gpod")] - internal static extern string itdb_cp_get_dest_filename (IntPtr track, string mountpoint, string filename, ref IntPtr error); + internal static extern string itdb_cp_get_dest_filename(IntPtr track, string mountpoint, string filename, ref IntPtr error); [DllImport ("gpod")] - internal static extern bool itdb_cp_track_to_ipod (HandleRef track, string filename, ref IntPtr error); + internal static extern bool itdb_cp_track_to_ipod(HandleRef track, string filename, ref IntPtr error); [DllImport ("gpod")] internal static extern void itdb_free(HandleRef itdb); [DllImport ("gpod")] - internal static extern string itdb_get_control_dir (string mountpoint); + internal static extern string itdb_get_control_dir(string mountpoint); [DllImport ("gpod")] - internal static extern string itdb_get_music_dir (string mountpoint); + internal static extern string itdb_get_music_dir(string mountpoint); [DllImport ("gpod")] internal static extern IntPtr itdb_parse(string mountpoint, out IntPtr gerror); @@ -89,10 +89,10 @@ internal static extern IntPtr itdb_playlist_by_name(HandleRef itdb, string name); [DllImport ("gpod")] - internal static extern bool itdb_start_sync (IntPtr itdb); + internal static extern bool itdb_start_sync(IntPtr itdb); [DllImport ("gpod")] - internal static extern bool itdb_stop_sync (IntPtr itdb); + internal static extern bool itdb_stop_sync(IntPtr itdb); } } @@ -100,12 +100,23 @@ public ITDBTrackList(bool owner, HandleRef handle, IntPtr list) : base(owner, handle, list) {} protected override void DoAdd(int index, Track item) { Itdb_iTunesDB.itdb_track_add(this.handle, item.Handle, index); } protected override void DoUnlink(int index) { Itdb_iTunesDB.itdb_track_unlink(this[index].Handle); } + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_iTunesDB *) handle.Handle)->tracks, typeof(Track)); + } + } } internal class ITDBPlaylistList : GPodList { public ITDBPlaylistList(bool owner, HandleRef handle, IntPtr list) : base(owner, handle, list) {} protected override void DoAdd(int index, Playlist item) { Itdb_iTunesDB.itdb_playlist_add(this.handle, item.Handle, index); } protected override void DoUnlink(int index) { Itdb_iTunesDB.itdb_playlist_unlink(this[index].Handle); } + + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_iTunesDB *) handle.Handle)->playlists, typeof(Playlist)); + } + } } public unsafe class ITDB : GPodBase { @@ -117,63 +128,68 @@ return res; } - public static string GetLocalPath (Device device, Track track) - { - string ipodPath = track.IpodPath.Replace (":", "/").Substring (1); - return System.IO.Path.Combine (device.Mountpoint, ipodPath); + public static string GetLocalPath(Device device, Track track) { + string ipodPath = track.IpodPath.Replace(":", "/").Substring(1); + return System.IO.Path.Combine(device.Mountpoint, ipodPath); } - public static string GetDestFileName (Device device, string localFile) - { - // itdb_cp_get_dest_filename (HandleRef track, string mountpoint, string filename, ref IntPtr error); + public static string GetDestFileName(Device device, string localFile) { + // itdb_cp_get_dest_filename(HandleRef track, string mountpoint, string filename, ref IntPtr error); IntPtr error = IntPtr.Zero; - string result = Itdb_iTunesDB.itdb_cp_get_dest_filename (IntPtr.Zero, device.Mountpoint, localFile, ref error); + string result = Itdb_iTunesDB.itdb_cp_get_dest_filename(IntPtr.Zero, device.Mountpoint, localFile, ref error); if (error != IntPtr.Zero) - throw new GException (error); + throw new GException(error); return result; } - public static string GetControlPath (Device device) - { - return Itdb_iTunesDB.itdb_get_control_dir (device.Mountpoint); - } - - public static string GetMusicPath (Device device) - { - return Itdb_iTunesDB.itdb_get_music_dir (device.Mountpoint); - } - - public IList Tracks { get { return new ITDBTrackList(true, Handle, ((Itdb_iTunesDB *) Native)->tracks); } } - public IList Playlists { get { return new ITDBPlaylistList(true, Handle, ((Itdb_iTunesDB *) Native)->playlists); } } - public Playlist MasterPlaylist { get { return new Playlist(Itdb_iTunesDB.itdb_playlist_mpl(Handle)); } } - public Playlist PodcastsPlaylist { get { return new Playlist(Itdb_iTunesDB.itdb_playlist_podcasts(Handle)); } } - public Device Device { get { return new Device(((Itdb_iTunesDB *) Native)->device, true); } } - public uint NonTransferredTrackCount { get { return Itdb_iTunesDB.itdb_tracks_number_nontransferred(Handle); } } - public string Mountpoint { get { return PtrToStringUTF8 (Itdb_iTunesDB.itdb_get_mountpoint(Handle)); } - set { Itdb_iTunesDB.itdb_set_mountpoint(Handle, value); } } + public static string GetControlPath(Device device) { + return Itdb_iTunesDB.itdb_get_control_dir(device.Mountpoint); + } + + public static string GetMusicPath(Device device) { + return Itdb_iTunesDB.itdb_get_music_dir(device.Mountpoint); + } + + public IList Tracks { get { return new ITDBTrackList(true, Handle, ((Itdb_iTunesDB *) Native)->tracks); } } + public IList Playlists { get { return new ITDBPlaylistList(true, Handle, ((Itdb_iTunesDB *) Native)->playlists); } } + public Playlist MasterPlaylist { + get { + var pl_ptr = Itdb_iTunesDB.itdb_playlist_mpl(Handle); + return pl_ptr == IntPtr.Zero ? null : new Playlist(pl_ptr); + } + } + + public Playlist PodcastsPlaylist { + get { + var pl_ptr = Itdb_iTunesDB.itdb_playlist_podcasts(Handle); + return pl_ptr == IntPtr.Zero ? null : new Playlist(pl_ptr); + } + } + + public Device Device { get { return new Device(((Itdb_iTunesDB *) Native)->device, true); } } + public uint NonTransferredTrackCount { get { return Itdb_iTunesDB.itdb_tracks_number_nontransferred(Handle); } } + public string Mountpoint { get { return PtrToStringUTF8(Itdb_iTunesDB.itdb_get_mountpoint(Handle)); } + set { Itdb_iTunesDB.itdb_set_mountpoint(Handle, value); } } public ITDB(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public ITDB(IntPtr handle) : base(handle) {} - public ITDB() : base(Itdb_iTunesDB.itdb_new(), false) {} - public ITDB(string mountpoint) : base(itdb_parse_wrapped(mountpoint), false) {} + public ITDB(IntPtr handle) : base(handle) {} + public ITDB() : base(Itdb_iTunesDB.itdb_new(), false) {} + public ITDB(string mountpoint) : base(itdb_parse_wrapped(mountpoint), false) {} protected override void Destroy() { if (!Borrowed) Itdb_iTunesDB.itdb_free(Handle); } - public bool CopyTrackToIPod (Track track, string localPath) - { + public bool CopyTrackToIPod(Track track, string localPath) { IntPtr gerror = IntPtr.Zero; - bool result = Itdb_iTunesDB.itdb_cp_track_to_ipod (track.Handle, localPath, ref gerror); + bool result = Itdb_iTunesDB.itdb_cp_track_to_ipod(track.Handle, localPath, ref gerror); if (gerror != IntPtr.Zero) throw new GException(gerror); return result; } - public bool StartSync () - { - return Itdb_iTunesDB.itdb_start_sync (Native); + public bool StartSync() { + return Itdb_iTunesDB.itdb_start_sync(Native); } - public bool StopSync () - { - return Itdb_iTunesDB.itdb_stop_sync (Native); + public bool StopSync() { + return Itdb_iTunesDB.itdb_stop_sync(Native); } public bool Write() { @@ -192,4 +208,4 @@ return retval; } } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in libgpod-0.7.95/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in --- libgpod-0.7.94/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in 2010-09-20 21:45:04.000000000 +0800 @@ -1,4 +1,4 @@ - + diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Makefile.am libgpod-0.7.95/bindings/mono/libgpod-sharp/Makefile.am --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Makefile.am 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Makefile.am 2010-09-20 21:45:04.000000000 +0800 @@ -18,7 +18,7 @@ Thumbnail.cs \ Track.cs -dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname=\(.*\)/\1/g") +dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname='\(.*\)'/\1/g") libgpod-sharp.dll.config: $(top_srcdir)/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in sed "s/@DLNAME@/$(dlname)/g" $< >$@ diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Makefile.in libgpod-0.7.95/bindings/mono/libgpod-sharp/Makefile.in --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Makefile.in 2010-09-01 05:10:47.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Makefile.in 2010-09-30 01:09:14.000000000 +0800 @@ -301,7 +301,7 @@ Thumbnail.cs \ Track.cs -dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname=\(.*\)/\1/g") +dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname='\(.*\)'/\1/g") pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libgpod-sharp.pc EXTRAS = \ diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/PhotoAlbum.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/PhotoAlbum.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/PhotoAlbum.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/PhotoAlbum.cs 2010-09-30 00:44:31.000000000 +0800 @@ -65,33 +65,38 @@ Itdb_PhotoAlbum.itdb_photodb_photoalbum_add_photo(photodb, this.handle, item.Handle, index); } protected override void DoUnlink(int index) { Itdb_PhotoDB.itdb_photodb_photoalbum_unlink(this[index].Handle); } + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_PhotoAlbum *) handle.Handle)->members, typeof(Artwork)); + } + } } public unsafe class PhotoAlbum : GPodBase { public PhotoAlbum(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public PhotoAlbum(IntPtr handle) : base(handle) {} - public PhotoAlbum(string albumname) : base(Itdb_PhotoAlbum.itdb_photodb_photoalbum_new(albumname), false) {} - protected override void Destroy() { Itdb_PhotoAlbum.itdb_photodb_photoalbum_free(Handle); } + public PhotoAlbum(IntPtr handle) : base(handle) {} + public PhotoAlbum(string albumname) : base(Itdb_PhotoAlbum.itdb_photodb_photoalbum_new(albumname), false) {} + protected override void Destroy() { Itdb_PhotoAlbum.itdb_photodb_photoalbum_free(Handle); } - public IList Photos { get { return new PhotoAlbumArtworkList(Handle, ((Itdb_PhotoAlbum *) Native)->members); } } - public string Name { get { return PtrToStringUTF8 (((Itdb_PhotoAlbum *) Native)->name); } - set { var x = (Itdb_PhotoAlbum *) Native; ReplaceStringUTF8 (ref x->name, value); } } - public bool PlayMusic { get { return ((Itdb_PhotoAlbum *) Native)->playmusic == 1; } - set { ((Itdb_PhotoAlbum *) Native)->playmusic = (byte) (value ? 1 : 0); } } - public bool Repeat { get { return ((Itdb_PhotoAlbum *) Native)->repeat == 1; } - set { ((Itdb_PhotoAlbum *) Native)->repeat = (byte) (value ? 1 : 0); } } - public bool Random { get { return ((Itdb_PhotoAlbum *) Native)->random == 1; } - set { ((Itdb_PhotoAlbum *) Native)->random = (byte) (value ? 1 : 0); } } - public bool ShowTitles { get { return ((Itdb_PhotoAlbum *) Native)->show_titles == 1; } - set { ((Itdb_PhotoAlbum *) Native)->show_titles = (byte) (value ? 1 : 0); } } + public IList Photos { get { return new PhotoAlbumArtworkList(Handle, ((Itdb_PhotoAlbum *) Native)->members); } } + public string Name { get { return PtrToStringUTF8(((Itdb_PhotoAlbum *) Native)->name); } + set { var x = (Itdb_PhotoAlbum *) Native; ReplaceStringUTF8 (ref x->name, value); } } + public bool PlayMusic { get { return ((Itdb_PhotoAlbum *) Native)->playmusic == 1; } + set { ((Itdb_PhotoAlbum *) Native)->playmusic = (byte) (value ? 1 : 0); } } + public bool Repeat { get { return ((Itdb_PhotoAlbum *) Native)->repeat == 1; } + set { ((Itdb_PhotoAlbum *) Native)->repeat = (byte) (value ? 1 : 0); } } + public bool Random { get { return ((Itdb_PhotoAlbum *) Native)->random == 1; } + set { ((Itdb_PhotoAlbum *) Native)->random = (byte) (value ? 1 : 0); } } + public bool ShowTitles { get { return ((Itdb_PhotoAlbum *) Native)->show_titles == 1; } + set { ((Itdb_PhotoAlbum *) Native)->show_titles = (byte) (value ? 1 : 0); } } public TransitionDirection TransitionDirection { get { return (TransitionDirection) ((Itdb_PhotoAlbum *) Native)->transition_direction; } - set { ((Itdb_PhotoAlbum *) Native)->transition_direction = (byte) value; } } - public int SlideDuration { get { return ((Itdb_PhotoAlbum *) Native)->slide_duration; } - set { ((Itdb_PhotoAlbum *) Native)->slide_duration = value; } } - public int TransitionDuration { get { return ((Itdb_PhotoAlbum *) Native)->transition_duration; } - set { ((Itdb_PhotoAlbum *) Native)->transition_duration = value; } } + set { ((Itdb_PhotoAlbum *) Native)->transition_direction = (byte) value; } } + public int SlideDuration { get { return ((Itdb_PhotoAlbum *) Native)->slide_duration; } + set { ((Itdb_PhotoAlbum *) Native)->slide_duration = value; } } + public int TransitionDuration { get { return ((Itdb_PhotoAlbum *) Native)->transition_duration; } + set { ((Itdb_PhotoAlbum *) Native)->transition_duration = value; } } // TODO: Do I need to do this? - //public Track Song { get { return ((Itdb_PhotoAlbum *) Native)->transition_duration; } - // set { ((Itdb_PhotoAlbum *) Native)->transition_duration = value; } } + //public Track Song { get { return ((Itdb_PhotoAlbum *) Native)->transition_duration; } + // set { ((Itdb_PhotoAlbum *) Native)->transition_duration = value; } } } } diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/PhotoDB.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/PhotoDB.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/PhotoDB.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/PhotoDB.cs 2010-09-30 00:44:31.000000000 +0800 @@ -75,12 +75,22 @@ public PhotoDBArtworkList(bool owner, HandleRef handle, IntPtr list) : base(owner, handle, list) {} protected override void DoAdd(int index, Artwork item) { } // TODO: How do I make itdb_photodb_add_photo() fit this convention? protected override void DoUnlink(int index) { } // TODO: How do I make itdb_photodb_remove_photo() fit this convention? + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_PhotoDB *) handle.Handle)->photos, typeof(Artwork)); + } + } } internal class PhotoDBPhotoAlbumList : GPodList { public PhotoDBPhotoAlbumList(bool owner, HandleRef handle, IntPtr list) : base(owner, handle, list) {} protected override void DoAdd(int index, PhotoAlbum item) { Itdb_PhotoDB.itdb_photodb_photoalbum_add(this.handle, item.Handle, index); } protected override void DoUnlink(int index) { Itdb_PhotoDB.itdb_photodb_photoalbum_unlink(this[index].Handle); } + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_PhotoDB *) handle.Handle)->photoalbums, typeof(PhotoAlbum)); + } + } } public unsafe class PhotoDB : GPodBase { @@ -88,13 +98,13 @@ return new PhotoDB(Itdb_PhotoDB.itdb_photodb_create(mountpoint), false); } - public IList Photos { get { return new PhotoDBArtworkList(true, Handle, ((Itdb_PhotoDB *) Native)->photos); } } - public IList PhotoAlbums { get { return new PhotoDBPhotoAlbumList(true, Handle, ((Itdb_PhotoDB *) Native)->photoalbums); } } - public Device Device { get { return new Device(((Itdb_PhotoDB *) Native)->device, true); } } + public IList Photos { get { return new PhotoDBArtworkList(true, Handle, ((Itdb_PhotoDB *) Native)->photos); } } + public IList PhotoAlbums { get { return new PhotoDBPhotoAlbumList(true, Handle, ((Itdb_PhotoDB *) Native)->photoalbums); } } + public Device Device { get { return new Device(((Itdb_PhotoDB *) Native)->device, true); } } public PhotoDB(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public PhotoDB(string mountpoint) : base(itdb_photodb_parse_wrapped(mountpoint), false) {} - protected override void Destroy() { Itdb_PhotoDB.itdb_photodb_free(Handle); } + public PhotoDB(string mountpoint) : base(itdb_photodb_parse_wrapped(mountpoint), false) {} + protected override void Destroy() { Itdb_PhotoDB.itdb_photodb_free(Handle); } public bool Write() { IntPtr gerror; diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Playlist.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Playlist.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Playlist.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Playlist.cs 2010-09-30 00:44:31.000000000 +0800 @@ -25,21 +25,21 @@ namespace native { internal struct Itdb_Playlist { - public IntPtr itdb; - public IntPtr name; - public byte type; - public byte flag1; - public byte flag2; - public byte flag3; - public int num; - public IntPtr members; - public int is_spl; - public IntPtr timestamp; - public ulong id; - public PlaylistSortOrder sortorder; - public uint podcastflag; - //Itdb_SPLPref splpref; - //Itdb_SPLRules splrules; + public IntPtr itdb; + public IntPtr name; + public byte type; + public byte flag1; + public byte flag2; + public byte flag3; + public int num; + public IntPtr members; + public int is_spl; + public IntPtr timestamp; + public ulong id; + public PlaylistSortOrder sortorder; + public uint podcastflag; + //Itdb_SPLPref splpref; + //Itdb_SPLRules splrules; // Ignore the rest [DllImport ("gpod")] @@ -62,38 +62,44 @@ public enum PlaylistSortOrder { Manual = 1, //Unknown = 2, - Title = 3, - Album = 4, - Artist = 5, - Bitrate = 6, - Genre = 7, - Filetype = 8, - TimeModified = 9, - TrackNumber = 10, - Size = 11, - Time = 12, - Year = 13, - Samplerate = 14, - Comment = 15, - TimeAdded = 16, + Title = 3, + Album = 4, + Artist = 5, + Bitrate = 6, + Genre = 7, + Filetype = 8, + TimeModified = 9, + TrackNumber = 10, + Size = 11, + Time = 12, + Year = 13, + Samplerate = 14, + Comment = 15, + TimeAdded = 16, Equalizer = 17, - Composer = 18, + Composer = 18, //Unknown = 19, - PlayCount = 20, - TimePlayed = 21, - CDNumber = 22, - Rating = 23, - ReleaseDate = 24, - BPM = 25, - Grouping = 26, - Category = 27, - Description = 28 + PlayCount = 20, + TimePlayed = 21, + CDNumber = 22, + Rating = 23, + ReleaseDate = 24, + BPM = 25, + Grouping = 26, + Category = 27, + Description = 28 } internal class PlaylistTrackList : GPodList { - public PlaylistTrackList(HandleRef handle, IntPtr list) : base(handle, list) {} - protected override void DoAdd(int index, Track item) { Itdb_Playlist.itdb_playlist_add_track(this.handle, item.Handle, index); } - protected override void DoUnlink(int index) { Itdb_Playlist.itdb_playlist_remove_track(this.handle, this[index].Handle); } + public PlaylistTrackList(HandleRef handle, IntPtr list) : base(handle, list) {} + protected override void DoAdd(int index, Track item) { Itdb_Playlist.itdb_playlist_add_track(this.handle, item.Handle, index); } + protected override void DoUnlink(int index) { Itdb_Playlist.itdb_playlist_remove_track(this.handle, this[index].Handle); } + + protected unsafe override GLib.List List { + get { + return new GLib.List(((Itdb_Playlist *) handle.Handle)->members, typeof(Track)); + } + } } public unsafe class Playlist : GPodBase { @@ -106,27 +112,28 @@ } public string Name { - get { return PtrToStringUTF8 (((Itdb_Playlist *) Native)->name); } - set { var x = (Itdb_Playlist *) Native; ReplaceStringUTF8 (ref x->name, value); } + get { return PtrToStringUTF8(((Itdb_Playlist *) Native)->name); } + set { var x = (Itdb_Playlist *) Native; ReplaceStringUTF8(ref x->name, value); } } - public bool IsSmartPlaylist { get { return ((Itdb_Playlist *) Native)->is_spl != 0; } - set { ((Itdb_Playlist *) Native)->is_spl = value ? 1 : 0; } } - public DateTime TimeCreated { get { return Artwork.time_tToDateTime(((Itdb_Playlist *) Native)->timestamp); } - set { ((Itdb_Playlist *) Native)->timestamp = Artwork.DateTimeTotime_t(value); } } - public ulong ID { get { return ((Itdb_Playlist *) Native)->id; } - set { ((Itdb_Playlist *) Native)->id = value; } } - public PlaylistSortOrder SortOrder { get { return ((Itdb_Playlist *) Native)->sortorder; } - set { ((Itdb_Playlist *) Native)->sortorder = value; } } - public bool IsPodcast { get { return ((Itdb_Playlist *) Native)->podcastflag == 1; } - set { ((Itdb_Playlist *) Native)->podcastflag = (uint) (value ? 1 : 0); } } - public bool IsMaster { get { return (((Itdb_Playlist *) Native)->type & 0xff) == 1; } - set { ((Itdb_Playlist *) Native)->type = (byte) (value ? 1 : 0); } } + public bool IsSmartPlaylist { get { return ((Itdb_Playlist *) Native)->is_spl != 0; } + set { ((Itdb_Playlist *) Native)->is_spl = value ? 1 : 0; } } + public DateTime TimeCreated { get { return Artwork.time_tToDateTime(((Itdb_Playlist *) Native)->timestamp); } + set { ((Itdb_Playlist *) Native)->timestamp = Artwork.DateTimeTotime_t(value); } } + public ulong ID { get { return ((Itdb_Playlist *) Native)->id; } + set { ((Itdb_Playlist *) Native)->id = value; } } + public PlaylistSortOrder SortOrder { get { return ((Itdb_Playlist *) Native)->sortorder; } + set { ((Itdb_Playlist *) Native)->sortorder = value; } } + public bool IsPodcast { get { return ((Itdb_Playlist *) Native)->podcastflag == 1; } + set { ((Itdb_Playlist *) Native)->podcastflag = (uint) (value ? 1 : 0); } } + public bool IsMaster { get { return (((Itdb_Playlist *) Native)->type & 0xff) == 1; } + set { ((Itdb_Playlist *) Native)->type = (byte) (value ? 1 : 0); } } - public Playlist(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public Playlist(IntPtr handle) : base(handle) {} - public Playlist(Playlist other) : base(Itdb_Playlist.itdb_playlist_duplicate(other.Handle), false) {} - protected override void Destroy() { Itdb_Playlist.itdb_playlist_free(Handle); } + public Playlist(string name) : base (Itdb_Playlist.itdb_playlist_new (name, false)) {} + public Playlist(IntPtr handle, bool borrowed) : base(handle, borrowed) {} + public Playlist(IntPtr handle) : base(handle) {} + public Playlist(Playlist other) : base(Itdb_Playlist.itdb_playlist_duplicate(other.Handle), false) {} + protected override void Destroy() { Itdb_Playlist.itdb_playlist_free(Handle); } } } diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Thumbnail.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Thumbnail.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Thumbnail.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Thumbnail.cs 2010-09-30 00:44:31.000000000 +0800 @@ -42,10 +42,10 @@ } public class Thumbnail : GPodBase { - public Thumbnail(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public Thumbnail(IntPtr handle) : base(handle) {} - public Thumbnail(Thumbnail other) : this(Itdb_Thumb.itdb_thumb_duplicate(other.Handle), false) {} - protected override void Destroy() { Itdb_Thumb.itdb_thumb_free(Handle); } + public Thumbnail(IntPtr handle, bool borrowed) : base(handle, borrowed) {} + public Thumbnail(IntPtr handle) : base(handle) {} + public Thumbnail(Thumbnail other) : this(Itdb_Thumb.itdb_thumb_duplicate(other.Handle), false) {} + protected override void Destroy() { Itdb_Thumb.itdb_thumb_free(Handle); } public Pixbuf ToPixbufAtSize(Device device, int width, int height) { return new Pixbuf(Itdb_Thumb.itdb_thumb_to_pixbuf_at_size(device.Handle, Handle, width, height)); @@ -58,4 +58,4 @@ return pixbufs; } } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/bindings/mono/libgpod-sharp/Track.cs libgpod-0.7.95/bindings/mono/libgpod-sharp/Track.cs --- libgpod-0.7.94/bindings/mono/libgpod-sharp/Track.cs 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/bindings/mono/libgpod-sharp/Track.cs 2010-09-30 00:44:31.000000000 +0800 @@ -53,80 +53,80 @@ public IntPtr sort_albumartist; public IntPtr sort_composer; public IntPtr sort_tvshow; - public uint id; - public int size; - public int tracklen; - public int cd_nr; - public int cds; - public int track_nr; - public int tracks; - public int bitrate; - public ushort samplerate; - public ushort samplerate_low; - public int year; - public int volume; - public uint soundcheck; - public IntPtr time_added; - public IntPtr time_modified; - public IntPtr time_played; - public uint bookmark_time; - public uint rating; - public uint playcount; - public uint playcount2; - public uint recent_playcount; - public int transferred; - public short BPM; - public byte app_rating; - public byte type1; - public byte type2; - public byte compilation; - public uint starttime; - public uint stoptime; - public byte ischecked; - public ulong dbid; - public uint drm_userid; - public uint visible; - public uint filetype_marker; - public ushort artwork_count; - public uint artwork_size; - public float samplerate2; - public ushort unk126; - public uint unk132; - public IntPtr time_released; - public ushort unk144; - public ushort explicit_flag; - public uint unk148; - public uint unk152; - public uint skipcount; - public uint recent_skipcount; - public uint last_skipped; - public byte has_artwork; - public byte skip_when_shuffling; - public byte remember_playback_position; - public byte flag4; - public ulong dbid2; - public byte lyrics_flag; - public byte movie_flag; - public byte mark_unplayed; - public byte unk179; - public uint unk180; - public uint pregap; - public ulong samplecount; - public uint unk196; - public uint postgap; - public uint unk204; - public MediaType mediatype; - public uint season_nr; - public uint episode_nr; - public uint unk220; - public uint unk224; - public uint unk228, unk232, unk236, unk240, unk244; - public uint gapless_data; - public uint unk252; - public ushort gapless_track_flag; - public ushort gapless_album_flag; - public ushort album_id; - public IntPtr artwork; + public uint id; + public int size; + public int tracklen; + public int cd_nr; + public int cds; + public int track_nr; + public int tracks; + public int bitrate; + public ushort samplerate; + public ushort samplerate_low; + public int year; + public int volume; + public uint soundcheck; + public IntPtr time_added; + public IntPtr time_modified; + public IntPtr time_played; + public uint bookmark_time; + public uint rating; + public uint playcount; + public uint playcount2; + public uint recent_playcount; + public int transferred; + public short BPM; + public byte app_rating; + public byte type1; + public byte type2; + public byte compilation; + public uint starttime; + public uint stoptime; + public byte ischecked; + public ulong dbid; + public uint drm_userid; + public uint visible; + public uint filetype_marker; + public ushort artwork_count; + public uint artwork_size; + public float samplerate2; + public ushort unk126; + public uint unk132; + public IntPtr time_released; + public ushort unk144; + public ushort explicit_flag; + public uint unk148; + public uint unk152; + public uint skipcount; + public uint recent_skipcount; + public uint last_skipped; + public byte has_artwork; + public byte skip_when_shuffling; + public byte remember_playback_position; + public byte flag4; + public ulong dbid2; + public byte lyrics_flag; + public byte movie_flag; + public byte mark_unplayed; + public byte unk179; + public uint unk180; + public uint pregap; + public ulong samplecount; + public uint unk196; + public uint postgap; + public uint unk204; + public MediaType mediatype; + public uint season_nr; + public uint episode_nr; + public uint unk220; + public uint unk224; + public uint unk228, unk232, unk236, unk240, unk244; + public uint gapless_data; + public uint unk252; + public ushort gapless_track_flag; + public ushort gapless_album_flag; + public ushort album_id; + public IntPtr artwork; // Ignore the rest [DllImport ("gpod")] @@ -163,263 +163,270 @@ Audio = 0x0001, Movie = 0x0002, Podcast = 0x0004, + VideoPodcast= 0x0006, Audiobook = 0x0008, MusicVideo = 0x0020, TVShow = 0x0040, MusicTVShow = 0x0060, + RingTone = 0x004000, + Rental = 0x008000, + ItunesExtra = 0x010000, + Memo = 0x100000, + ITunesU = 0x200000, + EpubBook = 0x400000 } public unsafe class Track : GPodBase { public bool HasThumbnails { - get { return Itdb_Track.itdb_track_has_thumbnails (Handle); } + get { return Itdb_Track.itdb_track_has_thumbnails(Handle); } } public ITDB ITDB { - get { return new ITDB (((Itdb_Track *) Native)->itdb, true); } + get { return new ITDB(((Itdb_Track *) Native)->itdb, true); } } public string Title { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->title); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->title, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->title); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->title, value); } } public string IpodPath { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->ipod_path); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->ipod_path, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->ipod_path); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->ipod_path, value); } } public string Album { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->album); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->album, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->album); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->album, value); } } public string Artist { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->artist); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->artist, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->artist); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->artist, value); } } public string Genre { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->genre); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->genre, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->genre); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->genre, value); } } public string Filetype { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->filetype); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->filetype, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->filetype); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->filetype, value); } } public string Comment { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->comment); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->comment, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->comment); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->comment, value); } } public string Category { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->category); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->category, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->category); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->category, value); } } public string Composer { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->composer); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->composer, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->composer); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->composer, value); } } public string Grouping { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->grouping); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->grouping, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->grouping); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->grouping, value); } } public string Description { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->description); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->description, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->description); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->description, value); } } public string PodcastURL { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->podcasturl); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->podcasturl, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->podcasturl); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->podcasturl, value); } } public string PodcastRSS { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->podcastrss); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->podcastrss, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->podcastrss); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->podcastrss, value); } } public ChapterData ChapterData { - get { return new ChapterData (((Itdb_Track *) Native)->chapterdata); } + get { return new ChapterData(((Itdb_Track *) Native)->chapterdata); } set { ((Itdb_Track *) Native)->chapterdata = HandleRef.ToIntPtr(value.Handle); } } public string Subtitle { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->subtitle); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->subtitle, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->subtitle); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->subtitle, value); } } public string TVShow { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->tvshow); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->tvshow, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->tvshow); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->tvshow, value); } } public string TVEpisode { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->tvepisode); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->tvepisode, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->tvepisode); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->tvepisode, value); } } public string TVNetwork { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->tvnetwork); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->tvnetwork, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->tvnetwork); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->tvnetwork, value); } } public string AlbumArtist { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->albumartist); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->albumartist, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->albumartist); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->albumartist, value); } } public string Keywords { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->keywords); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->keywords, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->keywords); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->keywords, value); } } public string SortArtist { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_artist); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_artist, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_artist); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_artist, value); } } public string SortTitle { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_title); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_title, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_title); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_title, value); } } public string SortAlbum { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_album); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_album, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_album); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_album, value); } } public string SortAlbumArtist { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_albumartist); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_albumartist, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_albumartist); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_albumartist, value); } } public string SortComposer { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_composer); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_composer, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_composer); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_composer, value); } } public string SortTVShow { - get { return PtrToStringUTF8 (((Itdb_Track *) Native)->sort_tvshow); } - set { var x = (Itdb_Track *) Native; ReplaceStringUTF8 (ref x->sort_tvshow, value); } + get { return PtrToStringUTF8(((Itdb_Track *) Native)->sort_tvshow); } + set { var x = (Itdb_Track *) Native; ReplaceStringUTF8(ref x->sort_tvshow, value); } } - public int Size { get { return ((Itdb_Track *) Native)->size; } - set { ((Itdb_Track *) Native)->size = value; } } - public int TrackLength { get { return ((Itdb_Track *) Native)->tracklen; } - set { ((Itdb_Track *) Native)->tracklen = value; } } - public int CDNumber { get { return ((Itdb_Track *) Native)->cd_nr; } - set { ((Itdb_Track *) Native)->cd_nr = value; } } - public int CDs { get { return ((Itdb_Track *) Native)->cds; } - set { ((Itdb_Track *) Native)->cds = value; } } - public int TrackNumber { get { return ((Itdb_Track *) Native)->track_nr; } - set { ((Itdb_Track *) Native)->track_nr = value; } } - public int Tracks { get { return ((Itdb_Track *) Native)->tracks; } - set { ((Itdb_Track *) Native)->tracks = value; } } - public int Bitrate { get { return ((Itdb_Track *) Native)->bitrate; } - set { ((Itdb_Track *) Native)->bitrate = value; } } - public ushort Samplerate { get { return ((Itdb_Track *) Native)->samplerate; } - set { ((Itdb_Track *) Native)->samplerate = value; } } - public ushort SamplerateLow { get { return ((Itdb_Track *) Native)->samplerate_low; } - set { ((Itdb_Track *) Native)->samplerate_low = value; } } - public int Year { get { return ((Itdb_Track *) Native)->year; } - set { ((Itdb_Track *) Native)->year = value; } } - public int Volume { get { return ((Itdb_Track *) Native)->volume; } - set { ((Itdb_Track *) Native)->volume = value; } } - public uint Soundcheck { get { return ((Itdb_Track *) Native)->soundcheck; } - set { ((Itdb_Track *) Native)->soundcheck = value; } } - public DateTime TimeAdded { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_added); } - set { ((Itdb_Track *) Native)->time_added = Track.DateTimeTotime_t (value); } } - public DateTime TimeModified { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_modified); } - set { ((Itdb_Track *) Native)->time_modified = Track.DateTimeTotime_t (value); } } - public DateTime TimePlayed { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_played); } - set { ((Itdb_Track *) Native)->time_played = Track.DateTimeTotime_t(value); } } - public uint BookmarkTime { get { return ((Itdb_Track *) Native)->bookmark_time; } - set { ((Itdb_Track *) Native)->bookmark_time = value; } } - public uint Rating { get { return ((Itdb_Track *) Native)->rating; } - set { ((Itdb_Track *) Native)->rating = value; } } - public uint PlayCount { get { return ((Itdb_Track *) Native)->playcount; } - set { ((Itdb_Track *) Native)->playcount = value; } } - public uint PlayCount2 { get { return ((Itdb_Track *) Native)->playcount2; } - set { ((Itdb_Track *) Native)->playcount2 = value; } } - public uint RecentPlayCount { get { return ((Itdb_Track *) Native)->recent_playcount; } - set { ((Itdb_Track *) Native)->recent_playcount = value; } } - public bool Transferred { get { return ((Itdb_Track *) Native)->transferred != 0; } - set { ((Itdb_Track *) Native)->transferred = value ? 1 : 0; } } - public short BPM { get { return ((Itdb_Track *) Native)->BPM; } - set { ((Itdb_Track *) Native)->BPM = value; } } - public byte AppRating { get { return ((Itdb_Track *) Native)->app_rating; } - set { ((Itdb_Track *) Native)->app_rating = value; } } - public bool Compilation { get { return ((Itdb_Track *) Native)->compilation == 1; } - set { ((Itdb_Track *) Native)->compilation = (byte) (value ? 1 : 0); } } - public uint StartTime { get { return ((Itdb_Track *) Native)->starttime; } - set { ((Itdb_Track *) Native)->starttime = value; } } - public uint StopTime { get { return ((Itdb_Track *) Native)->stoptime; } - set { ((Itdb_Track *) Native)->stoptime = value; } } - public bool Checked { get { return ((Itdb_Track *) Native)->ischecked == 0; } - set { ((Itdb_Track *) Native)->ischecked = (byte) (value ? 0x0 : 0x1); } } - public ulong DBID { get { return ((Itdb_Track *) Native)->dbid; } - set { ((Itdb_Track *) Native)->dbid = value; } } - public uint DRMUserID { get { return ((Itdb_Track *) Native)->drm_userid; } - set { ((Itdb_Track *) Native)->drm_userid = value; } } - public uint Visible { get { return ((Itdb_Track *) Native)->visible; } - set { ((Itdb_Track *) Native)->visible = value; } } - public uint FiletypeMarker { get { return ((Itdb_Track *) Native)->filetype_marker; } - set { ((Itdb_Track *) Native)->filetype_marker = value; } } - public DateTime TimeReleased { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_released); } - set { ((Itdb_Track *) Native)->time_released = Track.DateTimeTotime_t(value); } } - public bool ExplicitFlag { get { return ((Itdb_Track *) Native)->explicit_flag == 1; } - set { ((Itdb_Track *) Native)->explicit_flag = (byte) (value ? 1 : 0); } } - public uint SkipCount { get { return ((Itdb_Track *) Native)->skipcount; } - set { ((Itdb_Track *) Native)->skipcount = value; } } - public uint RecentSkipCount { get { return ((Itdb_Track *) Native)->recent_skipcount; } - set { ((Itdb_Track *) Native)->recent_skipcount = value; } } - public uint LastSkipped { get { return ((Itdb_Track *) Native)->last_skipped; } - set { ((Itdb_Track *) Native)->last_skipped = value; } } - public bool SkipWhenShuffling { get { return ((Itdb_Track *) Native)->skip_when_shuffling == 1; } - set { ((Itdb_Track *) Native)->skip_when_shuffling = (byte) (value ? 1 : 0); } } - public bool RememberPlaybackPosition { get { return ((Itdb_Track *) Native)->remember_playback_position == 1; } - set { ((Itdb_Track *) Native)->remember_playback_position = (byte) (value ? 1 : 0); } } - public byte Flag4 { get { return ((Itdb_Track *) Native)->flag4; } - set { ((Itdb_Track *) Native)->flag4 = value; } } - public ulong DBID2 { get { return ((Itdb_Track *) Native)->dbid2; } - set { ((Itdb_Track *) Native)->dbid2 = value; } } - public bool LyricsFlag { get { return ((Itdb_Track *) Native)->lyrics_flag == 1; } - set { ((Itdb_Track *) Native)->lyrics_flag = (byte) (value ? 1 : 0); } } - public bool MovieFlag { get { return ((Itdb_Track *) Native)->movie_flag == 1; } - set { ((Itdb_Track *) Native)->movie_flag = (byte) (value ? 1 : 0); } } - public bool MarkUnplayed { get { return ((Itdb_Track *) Native)->mark_unplayed == 2; } - set { ((Itdb_Track *) Native)->mark_unplayed = (byte) (value ? 2 : 1); } } - public uint PreGap { get { return ((Itdb_Track *) Native)->pregap; } - set { ((Itdb_Track *) Native)->pregap = value; } } - public ulong SampleCount { get { return ((Itdb_Track *) Native)->samplecount; } - set { ((Itdb_Track *) Native)->samplecount = value; } } - public uint PostGap { get { return ((Itdb_Track *) Native)->postgap; } - set { ((Itdb_Track *) Native)->postgap = value; } } - public MediaType MediaType { get { return ((Itdb_Track *) Native)->mediatype; } - set { ((Itdb_Track *) Native)->mediatype = value; } } - public uint SeasonNumber { get { return ((Itdb_Track *) Native)->season_nr; } - set { ((Itdb_Track *) Native)->season_nr = value; } } - public uint EpisodeNumber { get { return ((Itdb_Track *) Native)->episode_nr; } - set { ((Itdb_Track *) Native)->episode_nr = value; } } - public uint GaplessData { get { return ((Itdb_Track *) Native)->gapless_data; } - set { ((Itdb_Track *) Native)->gapless_data = value; } } - public bool GaplessTrackFlag { get { return ((Itdb_Track *) Native)->gapless_track_flag == 1; } - set { ((Itdb_Track *) Native)->gapless_track_flag = (byte) (value ? 1 : 0); } } - public bool GaplessAlbumFlag { get { return ((Itdb_Track *) Native)->gapless_album_flag == 1; } - set { ((Itdb_Track *) Native)->gapless_album_flag = (byte) (value ? 1 : 0); } } - public Artwork Artwork { get { return new Artwork(((Itdb_Track *) Native)->artwork); } - set { ((Itdb_Track *) Native)->artwork = HandleRef.ToIntPtr(value.Handle); } } - - public Track() : this(Itdb_Track.itdb_track_new(), false) {} - public Track(Track other) : this(Itdb_Track.itdb_track_duplicate(other.Handle), false) {} - public Track(IntPtr handle, bool borrowed) : base(handle, borrowed) {} - public Track(IntPtr handle) : base(handle) {} - protected override void Destroy() { Itdb_Track.itdb_track_free(Handle); } + public int Size { get { return ((Itdb_Track *) Native)->size; } + set { ((Itdb_Track *) Native)->size = value; } } + public int TrackLength { get { return ((Itdb_Track *) Native)->tracklen; } + set { ((Itdb_Track *) Native)->tracklen = value; } } + public int CDNumber { get { return ((Itdb_Track *) Native)->cd_nr; } + set { ((Itdb_Track *) Native)->cd_nr = value; } } + public int CDs { get { return ((Itdb_Track *) Native)->cds; } + set { ((Itdb_Track *) Native)->cds = value; } } + public int TrackNumber { get { return ((Itdb_Track *) Native)->track_nr; } + set { ((Itdb_Track *) Native)->track_nr = value; } } + public int Tracks { get { return ((Itdb_Track *) Native)->tracks; } + set { ((Itdb_Track *) Native)->tracks = value; } } + public int Bitrate { get { return ((Itdb_Track *) Native)->bitrate; } + set { ((Itdb_Track *) Native)->bitrate = value; } } + public ushort Samplerate { get { return ((Itdb_Track *) Native)->samplerate; } + set { ((Itdb_Track *) Native)->samplerate = value; } } + public ushort SamplerateLow { get { return ((Itdb_Track *) Native)->samplerate_low; } + set { ((Itdb_Track *) Native)->samplerate_low = value; } } + public int Year { get { return ((Itdb_Track *) Native)->year; } + set { ((Itdb_Track *) Native)->year = value; } } + public int Volume { get { return ((Itdb_Track *) Native)->volume; } + set { ((Itdb_Track *) Native)->volume = value; } } + public uint Soundcheck { get { return ((Itdb_Track *) Native)->soundcheck; } + set { ((Itdb_Track *) Native)->soundcheck = value; } } + public DateTime TimeAdded { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_added); } + set { ((Itdb_Track *) Native)->time_added = Track.DateTimeTotime_t (value); } } + public DateTime TimeModified { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_modified); } + set { ((Itdb_Track *) Native)->time_modified = Track.DateTimeTotime_t (value); } } + public DateTime TimePlayed { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_played); } + set { ((Itdb_Track *) Native)->time_played = Track.DateTimeTotime_t(value); } } + public uint BookmarkTime { get { return ((Itdb_Track *) Native)->bookmark_time; } + set { ((Itdb_Track *) Native)->bookmark_time = value; } } + public uint Rating { get { return ((Itdb_Track *) Native)->rating; } + set { ((Itdb_Track *) Native)->rating = value; } } + public uint PlayCount { get { return ((Itdb_Track *) Native)->playcount; } + set { ((Itdb_Track *) Native)->playcount = value; } } + public uint PlayCount2 { get { return ((Itdb_Track *) Native)->playcount2; } + set { ((Itdb_Track *) Native)->playcount2 = value; } } + public uint RecentPlayCount { get { return ((Itdb_Track *) Native)->recent_playcount; } + set { ((Itdb_Track *) Native)->recent_playcount = value; } } + public bool Transferred { get { return ((Itdb_Track *) Native)->transferred != 0; } + set { ((Itdb_Track *) Native)->transferred = value ? 1 : 0; } } + public short BPM { get { return ((Itdb_Track *) Native)->BPM; } + set { ((Itdb_Track *) Native)->BPM = value; } } + public byte AppRating { get { return ((Itdb_Track *) Native)->app_rating; } + set { ((Itdb_Track *) Native)->app_rating = value; } } + public bool Compilation { get { return ((Itdb_Track *) Native)->compilation == 1; } + set { ((Itdb_Track *) Native)->compilation = (byte) (value ? 1 : 0); } } + public uint StartTime { get { return ((Itdb_Track *) Native)->starttime; } + set { ((Itdb_Track *) Native)->starttime = value; } } + public uint StopTime { get { return ((Itdb_Track *) Native)->stoptime; } + set { ((Itdb_Track *) Native)->stoptime = value; } } + public bool Checked { get { return ((Itdb_Track *) Native)->ischecked == 0; } + set { ((Itdb_Track *) Native)->ischecked = (byte) (value ? 0x0 : 0x1); } } + public ulong DBID { get { return ((Itdb_Track *) Native)->dbid; } + set { ((Itdb_Track *) Native)->dbid = value; } } + public uint DRMUserID { get { return ((Itdb_Track *) Native)->drm_userid; } + set { ((Itdb_Track *) Native)->drm_userid = value; } } + public uint Visible { get { return ((Itdb_Track *) Native)->visible; } + set { ((Itdb_Track *) Native)->visible = value; } } + public uint FiletypeMarker { get { return ((Itdb_Track *) Native)->filetype_marker; } + set { ((Itdb_Track *) Native)->filetype_marker = value; } } + public DateTime TimeReleased { get { return Track.time_tToDateTime (((Itdb_Track *) Native)->time_released); } + set { ((Itdb_Track *) Native)->time_released = Track.DateTimeTotime_t(value); } } + public bool ExplicitFlag { get { return ((Itdb_Track *) Native)->explicit_flag == 1; } + set { ((Itdb_Track *) Native)->explicit_flag = (byte) (value ? 1 : 0); } } + public uint SkipCount { get { return ((Itdb_Track *) Native)->skipcount; } + set { ((Itdb_Track *) Native)->skipcount = value; } } + public uint RecentSkipCount { get { return ((Itdb_Track *) Native)->recent_skipcount; } + set { ((Itdb_Track *) Native)->recent_skipcount = value; } } + public uint LastSkipped { get { return ((Itdb_Track *) Native)->last_skipped; } + set { ((Itdb_Track *) Native)->last_skipped = value; } } + public bool SkipWhenShuffling { get { return ((Itdb_Track *) Native)->skip_when_shuffling == 1; } + set { ((Itdb_Track *) Native)->skip_when_shuffling = (byte) (value ? 1 : 0); } } + public bool RememberPlaybackPosition { get { return ((Itdb_Track *) Native)->remember_playback_position == 1; } + set { ((Itdb_Track *) Native)->remember_playback_position = (byte) (value ? 1 : 0); } } + public byte Flag4 { get { return ((Itdb_Track *) Native)->flag4; } + set { ((Itdb_Track *) Native)->flag4 = value; } } + public ulong DBID2 { get { return ((Itdb_Track *) Native)->dbid2; } + set { ((Itdb_Track *) Native)->dbid2 = value; } } + public bool LyricsFlag { get { return ((Itdb_Track *) Native)->lyrics_flag == 1; } + set { ((Itdb_Track *) Native)->lyrics_flag = (byte) (value ? 1 : 0); } } + public bool MovieFlag { get { return ((Itdb_Track *) Native)->movie_flag == 1; } + set { ((Itdb_Track *) Native)->movie_flag = (byte) (value ? 1 : 0); } } + public bool MarkUnplayed { get { return ((Itdb_Track *) Native)->mark_unplayed == 2; } + set { ((Itdb_Track *) Native)->mark_unplayed = (byte) (value ? 2 : 1); } } + public uint PreGap { get { return ((Itdb_Track *) Native)->pregap; } + set { ((Itdb_Track *) Native)->pregap = value; } } + public ulong SampleCount { get { return ((Itdb_Track *) Native)->samplecount; } + set { ((Itdb_Track *) Native)->samplecount = value; } } + public uint PostGap { get { return ((Itdb_Track *) Native)->postgap; } + set { ((Itdb_Track *) Native)->postgap = value; } } + public MediaType MediaType { get { return ((Itdb_Track *) Native)->mediatype; } + set { ((Itdb_Track *) Native)->mediatype = value; } } + public uint SeasonNumber { get { return ((Itdb_Track *) Native)->season_nr; } + set { ((Itdb_Track *) Native)->season_nr = value; } } + public uint EpisodeNumber { get { return ((Itdb_Track *) Native)->episode_nr; } + set { ((Itdb_Track *) Native)->episode_nr = value; } } + public uint GaplessData { get { return ((Itdb_Track *) Native)->gapless_data; } + set { ((Itdb_Track *) Native)->gapless_data = value; } } + public bool GaplessTrackFlag { get { return ((Itdb_Track *) Native)->gapless_track_flag == 1; } + set { ((Itdb_Track *) Native)->gapless_track_flag = (byte) (value ? 1 : 0); } } + public bool GaplessAlbumFlag { get { return ((Itdb_Track *) Native)->gapless_album_flag == 1; } + set { ((Itdb_Track *) Native)->gapless_album_flag = (byte) (value ? 1 : 0); } } + public Artwork Artwork { get { return new Artwork(((Itdb_Track *) Native)->artwork); } + set { ((Itdb_Track *) Native)->artwork = HandleRef.ToIntPtr(value.Handle); } } + + public Track() : this(Itdb_Track.itdb_track_new(), false) {} + public Track(Track other) : this(Itdb_Track.itdb_track_duplicate(other.Handle), false) {} + public Track(IntPtr handle, bool borrowed) : base(handle, borrowed) {} + public Track(IntPtr handle) : base(handle) {} + protected override void Destroy() { Itdb_Track.itdb_track_free(Handle); } public Pixbuf ThumbnailGet(int width, int height) { return new Pixbuf(Itdb_Track.itdb_track_get_thumbnail(Handle, width, height)); @@ -441,4 +448,4 @@ Itdb_Track.itdb_track_remove_thumbnails(Handle); } } -} \ No newline at end of file +} diff -Nru libgpod-0.7.94/configure libgpod-0.7.95/configure --- libgpod-0.7.94/configure 2010-09-01 05:10:46.000000000 +0800 +++ libgpod-0.7.95/configure 2010-09-30 01:09:13.000000000 +0800 @@ -2751,7 +2751,7 @@ # LIBGPOD_MAJOR_VERSION=0 LIBGPOD_MINOR_VERSION=7 -LIBGPOD_MICRO_VERSION=94 +LIBGPOD_MICRO_VERSION=95 # If you need a modifier for the version number. # Normally empty, but can be used to make "fixup" releases. LIBGPOD_EXTRAVERSION= @@ -2763,7 +2763,7 @@ # changes to the signature and the semantic) # ? :+1 : ? == just internal changes # CURRENT : REVISION : AGE -LIBGPOD_SO_VERSION=6:1:2 +LIBGPOD_SO_VERSION=7:0:3 diff -Nru libgpod-0.7.94/configure.ac libgpod-0.7.95/configure.ac --- libgpod-0.7.94/configure.ac 2010-09-01 05:10:09.000000000 +0800 +++ libgpod-0.7.95/configure.ac 2010-09-30 01:09:00.000000000 +0800 @@ -12,7 +12,7 @@ # LIBGPOD_MAJOR_VERSION=0 LIBGPOD_MINOR_VERSION=7 -LIBGPOD_MICRO_VERSION=94 +LIBGPOD_MICRO_VERSION=95 # If you need a modifier for the version number. # Normally empty, but can be used to make "fixup" releases. LIBGPOD_EXTRAVERSION= @@ -25,7 +25,7 @@ # changes to the signature and the semantic) # ? :+1 : ? == just internal changes # CURRENT : REVISION : AGE -LIBGPOD_SO_VERSION=6:1:2 +LIBGPOD_SO_VERSION=7:0:3 AC_SUBST(LIBGPOD_SO_VERSION) AC_SUBST(LIBGPOD_MAJOR_VERSION) diff -Nru libgpod-0.7.94/debian/changelog libgpod-0.7.95/debian/changelog --- libgpod-0.7.94/debian/changelog 2010-09-08 18:13:55.000000000 +0800 +++ libgpod-0.7.95/debian/changelog 2010-09-30 11:49:48.000000000 +0800 @@ -1,12 +1,12 @@ -libgpod (0.7.94-0ubuntu2) maverick; urgency=low +libgpod (0.7.95-1) experimental; urgency=low - * debian/libgpod-dev.install: - - explicitey list libgpod-1.0.pc to not take libgpod-sharp.pc (in - libgpod-cil-dev package) + * New upstream release + * Drop 91_fix_dllconfig.patch, applied upstream + * Don't hardcode soname into chrpath invocation - -- Didier Roche Wed, 08 Sep 2010 12:13:55 +0200 + -- Chow Loong Jin Thu, 30 Sep 2010 11:49:35 +0800 -libgpod (0.7.94-0ubuntu1) maverick; urgency=low +libgpod (0.7.94-1) experimental; urgency=low [ Chow Loong Jin ] * New upstream release @@ -22,9 +22,8 @@ [ Didier Roche ] * debian/rules: - generate .pot files for launchpad to sync ubuntu from debian - (-0ubuntu1 for now, can be synced on next debian upload) - -- Chow Loong Jin Sat, 04 Sep 2010 20:48:41 +0800 + -- Chow Loong Jin Thu, 09 Sep 2010 18:58:58 +0800 libgpod (0.7.93-0.3) unstable; urgency=low diff -Nru libgpod-0.7.94/debian/control libgpod-0.7.95/debian/control --- libgpod-0.7.94/debian/control 2010-09-06 23:28:34.000000000 +0800 +++ libgpod-0.7.95/debian/control 2010-09-30 11:49:48.000000000 +0800 @@ -1,8 +1,7 @@ Source: libgpod Priority: optional Section: libs -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: gtkpod Maintainers +Maintainer: gtkpod Maintainers Uploaders: Frank Lichtenheld , Chow Loong Jin Build-Depends: debhelper (>= 7.0.50~), @@ -149,6 +148,7 @@ are needed to run CLI applications which use this library. Package: libgpod-cil-dev +Section: libdevel Architecture: all Depends: libgpod-cil (= ${source:Version}), ${misc:Depends} Description: CLI bindings for libgpod -- development files diff -Nru libgpod-0.7.94/debian/patches/91_fix_dllconfig.patch libgpod-0.7.95/debian/patches/91_fix_dllconfig.patch --- libgpod-0.7.94/debian/patches/91_fix_dllconfig.patch 2010-09-06 18:52:29.000000000 +0800 +++ libgpod-0.7.95/debian/patches/91_fix_dllconfig.patch 1970-01-01 07:30:00.000000000 +0730 @@ -1,39 +0,0 @@ -Description: Correct the name of the dllmap from "libgpod" to "gpod", and remove - quotes from .so name -Author: Chow Loong Jin -Index: libgpod/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in -=================================================================== ---- libgpod.orig/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in 2010-09-04 21:40:58.652220329 +0800 -+++ libgpod/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in 2010-09-04 22:22:55.169135265 +0800 -@@ -1,4 +1,4 @@ - -- -+ - - -Index: libgpod/bindings/mono/libgpod-sharp/Makefile.am -=================================================================== ---- libgpod.orig/bindings/mono/libgpod-sharp/Makefile.am 2010-09-04 22:23:18.639213358 +0800 -+++ libgpod/bindings/mono/libgpod-sharp/Makefile.am 2010-09-04 22:23:38.839280316 +0800 -@@ -18,7 +18,7 @@ - Thumbnail.cs \ - Track.cs - --dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname=\(.*\)/\1/g") -+dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname='\(.*\)'/\1/g") - libgpod-sharp.dll.config: $(top_srcdir)/bindings/mono/libgpod-sharp/libgpod-sharp.dll.config.in - sed "s/@DLNAME@/$(dlname)/g" $< >$@ - -Index: libgpod/bindings/mono/libgpod-sharp/Makefile.in -=================================================================== ---- libgpod.orig/bindings/mono/libgpod-sharp/Makefile.in 2010-09-04 22:23:18.679213490 +0800 -+++ libgpod/bindings/mono/libgpod-sharp/Makefile.in 2010-09-04 22:24:17.099406509 +0800 -@@ -301,7 +301,7 @@ - Thumbnail.cs \ - Track.cs - --dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname=\(.*\)/\1/g") -+dlname := $(shell grep "^dlname=" $(top_builddir)/src/libgpod.la | sed "s/^dlname='\(.*\)'/\1/g") - pkgconfigdir = $(libdir)/pkgconfig - pkgconfig_DATA = libgpod-sharp.pc - EXTRAS = \ diff -Nru libgpod-0.7.94/debian/patches/series libgpod-0.7.95/debian/patches/series --- libgpod-0.7.94/debian/patches/series 2010-09-06 18:52:29.000000000 +0800 +++ libgpod-0.7.95/debian/patches/series 2010-09-30 11:49:48.000000000 +0800 @@ -1,4 +1,3 @@ 10_kfreebsd.patch 25_xsltproc-nonet.patch 90_speed_itdb_resolve.patch -91_fix_dllconfig.patch diff -Nru libgpod-0.7.94/debian/rules libgpod-0.7.95/debian/rules --- libgpod-0.7.94/debian/rules 2010-09-06 18:53:28.000000000 +0800 +++ libgpod-0.7.95/debian/rules 2010-09-30 11:49:48.000000000 +0800 @@ -48,8 +48,8 @@ debian/tmp/usr/bin/ipod-time-sync chrpath -d debian/tmp/usr/bin/* chrpath -d debian/tmp/lib/udev/*-info - chrpath -d debian/tmp*/usr/lib/libgpod.so.4.2.1 - chrpath -d debian/tmp/usr/lib/python*/dist-packages/gpod/_gpod.so + chrpath -d debian/tmp*/usr/lib/libgpod.so.$(SONAME) + chrpath -d debian/tmp/usr/lib/python*/*-packages/gpod/_gpod.so # python things! build/python%: build/libgpod$(SONAME)/install-stamp diff -Nru libgpod-0.7.94/docs/reference/html/ch01.html libgpod-0.7.95/docs/reference/html/ch01.html --- libgpod-0.7.94/docs/reference/html/ch01.html 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/ch01.html 2010-09-30 01:10:58.000000000 +0800 @@ -21,7 +21,7 @@

-iPod database components

+iPod database components
Tracks — Data structure to store metadata about an iPod track diff -Nru libgpod-0.7.94/docs/reference/html/index.html libgpod-0.7.95/docs/reference/html/index.html --- libgpod-0.7.94/docs/reference/html/index.html 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/index.html 2010-09-30 01:10:58.000000000 +0800 @@ -33,10 +33,10 @@   

-

for libgpod 0.7.93

+

for libgpod 0.7.94

-

Permission is granted to copy, distribute and/or modify +

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no diff -Nru libgpod-0.7.94/docs/reference/html/index.sgml libgpod-0.7.95/docs/reference/html/index.sgml --- libgpod-0.7.94/docs/reference/html/index.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/index.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -374,6 +374,8 @@ + + diff -Nru libgpod-0.7.94/docs/reference/html/libgpod.devhelp2 libgpod-0.7.95/docs/reference/html/libgpod.devhelp2 --- libgpod-0.7.94/docs/reference/html/libgpod.devhelp2 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/libgpod.devhelp2 2010-09-30 01:10:58.000000000 +0800 @@ -381,6 +381,8 @@ + + diff -Nru libgpod-0.7.94/docs/reference/html/libgpod-Device.html libgpod-0.7.95/docs/reference/html/libgpod-Device.html --- libgpod-0.7.94/docs/reference/html/libgpod-Device.html 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/libgpod-Device.html 2010-09-30 01:10:58.000000000 +0800 @@ -86,6 +86,7 @@ gboolean sysinfo_changed; gint timezone_shift; void *iphone_sync_context; + int iphone_sync_nest_level; } Itdb_Device;

@@ -139,6 +140,12 @@ itdb_start/stop_sync + +

int iphone_sync_nest_level;

+Nesting count for itdb_start/stop_sync calls + itdb_start/stop_sync + +

Since 0.4.0

@@ -501,7 +508,9 @@ ITDB_IPOD_GENERATION_NANO_5, ITDB_IPOD_GENERATION_TOUCH_3, ITDB_IPOD_GENERATION_IPAD_1, - ITDB_IPOD_GENERATION_IPHONE_4 + ITDB_IPOD_GENERATION_IPHONE_4, + ITDB_IPOD_GENERATION_TOUCH_4, + ITDB_IPOD_GENERATION_NANO_6 } Itdb_IpodGeneration;

@@ -661,11 +670,23 @@

ITDB_IPOD_GENERATION_IPAD_1

- + +

ITDB_IPOD_GENERATION_IPHONE_4

- +Fourth Generation iPhone + + + +

ITDB_IPOD_GENERATION_TOUCH_4

+Fourth Generation iPod Touch + + + +

ITDB_IPOD_GENERATION_NANO_6

+ +
@@ -956,15 +977,18 @@

ITDB_IPOD_MODEL_SHUFFLE_GOLD

- + +

ITDB_IPOD_MODEL_SHUFFLE_STAINLESS

- + +

ITDB_IPOD_MODEL_IPAD

- + + @@ -1099,7 +1123,8 @@

gint row_bytes_alignment;

- +Specifies the number of bytes a pixel row must be aligned to + diff -Nru libgpod-0.7.94/docs/reference/html/libgpod-File-handling-functions.html libgpod-0.7.95/docs/reference/html/libgpod-File-handling-functions.html --- libgpod-0.7.94/docs/reference/html/libgpod-File-handling-functions.html 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/libgpod-File-handling-functions.html 2010-09-30 01:10:58.000000000 +0800 @@ -271,6 +271,10 @@ but on iPhones and iPod Touch this makes sure the "Sync in progress" screen is shown for the whole duration of the writing process.

+

+Calls to itdb_start_sync must be paired with calls to itdb_stop_sync. Nesting +is allowed. +

@@ -297,6 +301,10 @@ (but is safe to be used). On iPhones and iPod Touch this will hide the "Sync in progress" screen.

+

+Calls to itdb_stop_sync must be paired with calls to itdb_start_sync. Nesting +is allowed, and only the final itdb_stop_sync will actually stop the sync. +

diff -Nru libgpod-0.7.94/docs/reference/html/libgpod-Tracks.html libgpod-0.7.95/docs/reference/html/libgpod-Tracks.html --- libgpod-0.7.94/docs/reference/html/libgpod-Tracks.html 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/html/libgpod-Tracks.html 2010-09-30 01:10:58.000000000 +0800 @@ -1050,18 +1050,18 @@

enum Itdb_Mediatype

typedef enum
 {
-    ITDB_MEDIATYPE_AUDIO        = 0x000001,
-    ITDB_MEDIATYPE_MOVIE        = 0x000002,
-    ITDB_MEDIATYPE_PODCAST      = 0x000004,
-    ITDB_MEDIATYPE_AUDIOBOOK    = 0x000008,
-    ITDB_MEDIATYPE_MUSICVIDEO   = 0x000020,
-    ITDB_MEDIATYPE_TVSHOW       = 0x000040,
-    ITDB_MEDIATYPE_RINGTONE     = 0x004000,
-    ITDB_MEDIATYPE_RENTAL       = 0x008000,
-    ITDB_MEDIATYPE_ITUNES_EXTRA = 0x010000,
-    ITDB_MEDIATYPE_MEMO         = 0x100000,
-    ITDB_MEDIATYPE_ITUNES_U     = 0x200000,
-    ITDB_MEDIATYPE_EPUB_BOOK    = 0x400000
+    ITDB_MEDIATYPE_AUDIO        = (1 << 0),
+    ITDB_MEDIATYPE_MOVIE        = (1 << 1),
+    ITDB_MEDIATYPE_PODCAST      = (1 << 2),
+    ITDB_MEDIATYPE_AUDIOBOOK    = (1 << 3),
+    ITDB_MEDIATYPE_MUSICVIDEO   = (1 << 5),
+    ITDB_MEDIATYPE_TVSHOW       = (1 << 6),
+    ITDB_MEDIATYPE_RINGTONE     = (1 << 14),
+    ITDB_MEDIATYPE_RENTAL       = (1 << 15),
+    ITDB_MEDIATYPE_ITUNES_EXTRA = (1 << 16),
+    ITDB_MEDIATYPE_MEMO         = (1 << 20),
+    ITDB_MEDIATYPE_ITUNES_U     = (1 << 21),
+    ITDB_MEDIATYPE_EPUB_BOOK    = (1 << 22)
 } Itdb_Mediatype;
 

@@ -1070,7 +1070,11 @@

The mediatype is used to determine what menu a track appears under. For example, setting the mediatype to ITDB_MEDIATYPE_PODCAST makes the track -appear on the Podcast menu. +appear on the Podcast menu. Media type is a bitfield, so it can be a +binary combination of these constants, make sure to use binary operators +when you want to operate on media types (eg use a binary AND in +preference over a straight == when you want to test if a track has a +given media type).

@@ -1132,7 +1136,8 @@ - +

ITDB_MEDIATYPE_EPUB_BOOK

+
diff -Nru libgpod-0.7.94/docs/reference/tmpl/artwork.sgml libgpod-0.7.95/docs/reference/tmpl/artwork.sgml --- libgpod-0.7.94/docs/reference/tmpl/artwork.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/artwork.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -19,6 +19,9 @@ + + + @@ -47,6 +50,7 @@ +@void: @Returns: diff -Nru libgpod-0.7.94/docs/reference/tmpl/chapterdata.sgml libgpod-0.7.95/docs/reference/tmpl/chapterdata.sgml --- libgpod-0.7.94/docs/reference/tmpl/chapterdata.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/chapterdata.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -18,6 +18,9 @@ + + + @@ -49,6 +52,7 @@ +@void: @Returns: @@ -74,6 +78,7 @@ +@void: @Returns: diff -Nru libgpod-0.7.94/docs/reference/tmpl/device.sgml libgpod-0.7.95/docs/reference/tmpl/device.sgml --- libgpod-0.7.94/docs/reference/tmpl/device.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/device.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -17,6 +17,9 @@ + + + @@ -30,12 +33,14 @@ @sysinfo_changed: @timezone_shift: @iphone_sync_context: +@iphone_sync_nest_level: +@void: @Returns: @@ -130,6 +135,7 @@ +@void: @Returns: @@ -167,6 +173,10 @@ @ITDB_IPOD_GENERATION_CLASSIC_3: @ITDB_IPOD_GENERATION_NANO_5: @ITDB_IPOD_GENERATION_TOUCH_3: +@ITDB_IPOD_GENERATION_IPAD_1: +@ITDB_IPOD_GENERATION_IPHONE_4: +@ITDB_IPOD_GENERATION_TOUCH_4: +@ITDB_IPOD_GENERATION_NANO_6: @@ -222,6 +232,9 @@ @ITDB_IPOD_MODEL_SHUFFLE_BLACK: @ITDB_IPOD_MODEL_IPHONE_WHITE: @ITDB_IPOD_MODEL_IPHONE_BLACK: +@ITDB_IPOD_MODEL_SHUFFLE_GOLD: +@ITDB_IPOD_MODEL_SHUFFLE_STAINLESS: +@ITDB_IPOD_MODEL_IPAD: @@ -247,10 +260,10 @@ @back_color: @display_width: @interlaced: -@align_row_bytes: @color_adjustment: @gamma: @associated_format: +@row_bytes_alignment: diff -Nru libgpod-0.7.94/docs/reference/tmpl/Internal.sgml libgpod-0.7.95/docs/reference/tmpl/Internal.sgml --- libgpod-0.7.94/docs/reference/tmpl/Internal.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/Internal.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -17,3 +17,6 @@ + + + diff -Nru libgpod-0.7.94/docs/reference/tmpl/itunesdb-copying.sgml libgpod-0.7.95/docs/reference/tmpl/itunesdb-copying.sgml --- libgpod-0.7.94/docs/reference/tmpl/itunesdb-copying.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/itunesdb-copying.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -18,6 +18,9 @@ + + + diff -Nru libgpod-0.7.94/docs/reference/tmpl/itunesdb-db.sgml libgpod-0.7.95/docs/reference/tmpl/itunesdb-db.sgml --- libgpod-0.7.94/docs/reference/tmpl/itunesdb-db.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/itunesdb-db.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -89,6 +89,9 @@ + + + @@ -143,6 +146,7 @@ +@void: @Returns: diff -Nru libgpod-0.7.94/docs/reference/tmpl/itunesdb-lowlevel.sgml libgpod-0.7.95/docs/reference/tmpl/itunesdb-lowlevel.sgml --- libgpod-0.7.94/docs/reference/tmpl/itunesdb-lowlevel.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/itunesdb-lowlevel.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -18,6 +18,9 @@ + + + diff -Nru libgpod-0.7.94/docs/reference/tmpl/itunesdb-time.sgml libgpod-0.7.95/docs/reference/tmpl/itunesdb-time.sgml --- libgpod-0.7.94/docs/reference/tmpl/itunesdb-time.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/itunesdb-time.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -24,11 +24,15 @@ + + + +@void: @Returns: diff -Nru libgpod-0.7.94/docs/reference/tmpl/photodb.sgml libgpod-0.7.95/docs/reference/tmpl/photodb.sgml --- libgpod-0.7.94/docs/reference/tmpl/photodb.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/photodb.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -91,6 +91,9 @@ + + + diff -Nru libgpod-0.7.94/docs/reference/tmpl/playlists.sgml libgpod-0.7.95/docs/reference/tmpl/playlists.sgml --- libgpod-0.7.94/docs/reference/tmpl/playlists.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/playlists.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -19,6 +19,9 @@ + + + diff -Nru libgpod-0.7.94/docs/reference/tmpl/smart-playlists.sgml libgpod-0.7.95/docs/reference/tmpl/smart-playlists.sgml --- libgpod-0.7.94/docs/reference/tmpl/smart-playlists.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/smart-playlists.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -17,6 +17,9 @@ + + + @@ -275,6 +278,7 @@ +@void: @Returns: diff -Nru libgpod-0.7.94/docs/reference/tmpl/track.sgml libgpod-0.7.95/docs/reference/tmpl/track.sgml --- libgpod-0.7.94/docs/reference/tmpl/track.sgml 2010-09-01 05:10:59.000000000 +0800 +++ libgpod-0.7.95/docs/reference/tmpl/track.sgml 2010-09-30 01:10:58.000000000 +0800 @@ -18,6 +18,9 @@ + + + @@ -171,6 +174,7 @@ @ITDB_MEDIATYPE_ITUNES_EXTRA: @ITDB_MEDIATYPE_MEMO: @ITDB_MEDIATYPE_ITUNES_U: +@ITDB_MEDIATYPE_EPUB_BOOK: @@ -184,6 +188,7 @@ +@void: @Returns: diff -Nru libgpod-0.7.94/NEWS libgpod-0.7.95/NEWS --- libgpod-0.7.94/NEWS 2010-09-01 05:03:28.000000000 +0800 +++ libgpod-0.7.95/NEWS 2010-09-30 01:08:23.000000000 +0800 @@ -1,4 +1,30 @@ -Overview of changes in libgpod 0.7.93 +Overview of changes in libgpod 0.7.95 +===================================== + +For information about iPhone/iPod Touch/iPod Nano 5g support, please read +carefully the overview of libgpod 0.7.90 below. The iPhone 4, iPod Touch 4 +and the iPad aren't supported, other iOS4 devices might work. The Nano 6g +(Touch Nano) isn't supported either. + +This release brings some improvements to the generation of the sqlite +databases (used by iOS devices), in particular improved playcounts handling. +It also adds some bug fixes to the mono bindings. + +* improved support for sqlite databases (Joel Smith) +* bug fixes and playlist support for mono bindings (Alan McGovern, Gabriel + Burt, Nathaniel McCallum) +* small itdb_start_sync/itdb_stop_sync behaviour change, now the calls need + to be paired, but itdb_start_sync can be called N times, and the "Sync in + Progress" screen will only go away after the Nth call to itdb_stop_sync + (Hector Martin) +* be more smart when auto-guessing whether to use iPod_Control or + iTunes_Control (Whitney Young) +* improve error handling in itdb_init and itdb_write, before that there + were error cases that were not properly reported to the caller (Christophe + Fergeau) + + +Overview of changes in libgpod 0.7.94 ===================================== For information about iPhone/iPod Touch/iPod Nano 5g support, please read diff -Nru libgpod-0.7.94/src/itdb_device.c libgpod-0.7.95/src/itdb_device.c --- libgpod-0.7.94/src/itdb_device.c 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/src/itdb_device.c 2010-09-30 00:44:31.000000000 +0800 @@ -268,6 +268,23 @@ {"C074", 16, ITDB_IPOD_MODEL_NANO_RED, ITDB_IPOD_GENERATION_NANO_5, 14}, {"C075", 16, ITDB_IPOD_MODEL_NANO_PINK, ITDB_IPOD_GENERATION_NANO_5, 14}, + /* iPod nano touch (Sixth Generation) */ + {"C525", 8, ITDB_IPOD_MODEL_NANO_SILVER, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C688", 8, ITDB_IPOD_MODEL_NANO_BLACK, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C689", 8, ITDB_IPOD_MODEL_NANO_BLUE, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C690", 8, ITDB_IPOD_MODEL_NANO_GREEN, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C691", 8, ITDB_IPOD_MODEL_NANO_ORANGE, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C692", 8, ITDB_IPOD_MODEL_NANO_PINK, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C693", 8, ITDB_IPOD_MODEL_NANO_RED, ITDB_IPOD_GENERATION_NANO_6, 14}, + + {"C526", 16, ITDB_IPOD_MODEL_NANO_SILVER, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C694", 16, ITDB_IPOD_MODEL_NANO_BLACK, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C695", 16, ITDB_IPOD_MODEL_NANO_BLUE, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C696", 16, ITDB_IPOD_MODEL_NANO_GREEN, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C697", 16, ITDB_IPOD_MODEL_NANO_ORANGE, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C698", 16, ITDB_IPOD_MODEL_NANO_PINK, ITDB_IPOD_GENERATION_NANO_6, 14}, + {"C699", 16, ITDB_IPOD_MODEL_NANO_RED, ITDB_IPOD_GENERATION_NANO_6, 14}, + /* iPod Touch 1st gen */ {"A623", 8, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_1, 50}, {"A627", 16, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_1, 50}, @@ -286,6 +303,11 @@ {"C008", 32, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_3, 50}, {"C011", 64, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_3, 50}, + /* iPod Touch 4th gen */ + {"C540", 8, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_4, 50}, + {"C544", 32, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_4, 50}, + {"C547", 64, ITDB_IPOD_MODEL_TOUCH_SILVER, ITDB_IPOD_GENERATION_TOUCH_4, 50}, + /* iPhone */ {"A501", 4, ITDB_IPOD_MODEL_IPHONE_1, ITDB_IPOD_GENERATION_IPHONE_1, 50}, {"A712", 8, ITDB_IPOD_MODEL_IPHONE_1, ITDB_IPOD_GENERATION_IPHONE_1, 50}, @@ -672,6 +694,7 @@ { "YX7", "B228" }, /* 1GB Blue Shuffle 2g */ { "YX9", "B225" }, /* 1GB Silver Shuffle 2g */ { "8CQ", "C167" }, /* 1GB Gold Shuffle 2g */ + { "1ZH", "B518" }, /* 2GB Silver Shuffle 2g */ { "UNA", "A350" }, { "UNB", "A350" }, { "UPR", "A352" }, @@ -791,6 +814,8 @@ { "73A", "C074" }, /* 16GB Red Nano 5g */ { "73B", "C075" }, /* 16GB Pink Nano 5g */ + { "CMN", "C525" }, /* 8GB Silver Nano 6g */ + { "A1S", "C306" }, /* 2GB Silver Shuffle 4g */ { "A78", "C323" }, /* 2GB Black Shuffle 4g */ { "ALB", "C381" }, /* 2GB Green Shuffle 4g */ @@ -808,9 +833,11 @@ { "0JW", "B376" }, /* 32GB Silver iPod Touch (1st gen) */ { "201", "B528" }, /* 8GB Silver iPod Touch (2nd gen) */ { "203", "B531" }, /* 16GB Silver iPod Touch (2nd gen) */ - { "75J", "C086" }, /* 8GB Silver iPod Touch (3rd gen) */ - { "6K2", "C008" }, /* 32GB Silver iPod Touch (3rd gen) */ - { "6K4", "C011" }, /* 64GB Silver iPod Touch (3rd gen) */ + { "75J", "C086" }, /* 8GB iPod Touch (3rd gen) */ + { "6K2", "C008" }, /* 32GB iPod Touch (3rd gen) */ + { "6K4", "C011" }, /* 64GB iPod Touch (3rd gen) */ + { "CP7", "C540" }, /* 8GB iPod Touch (4th gen) */ + { "CP9", "C544" }, /* 32GB iPod Touch (4th gen) */ { "VR0", "A501" }, /* 4GB Silver iPhone 1st gen */ { "WH8", "A712" }, /* 8GB Silver iPhone */ @@ -1338,9 +1365,11 @@ case ITDB_IPOD_GENERATION_CLASSIC_3: return FALSE; case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -1396,12 +1425,14 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_CLASSIC_1: case ITDB_IPOD_GENERATION_CLASSIC_2: case ITDB_IPOD_GENERATION_CLASSIC_3: case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -1700,6 +1731,7 @@ case ITDB_IPOD_GENERATION_SHUFFLE_4: case ITDB_IPOD_GENERATION_NANO_1: case ITDB_IPOD_GENERATION_NANO_2: + case ITDB_IPOD_GENERATION_NANO_6: return FALSE; case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: @@ -1712,6 +1744,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -1838,6 +1871,8 @@ case ITDB_IPOD_GENERATION_IPAD_1: case ITDB_IPOD_GENERATION_IPHONE_4: + case ITDB_IPOD_GENERATION_TOUCH_4: + case ITDB_IPOD_GENERATION_NANO_6: return ITDB_CHECKSUM_HASHAB; case ITDB_IPOD_GENERATION_UNKNOWN: @@ -2063,6 +2098,7 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_SHUFFLE_1: case ITDB_IPOD_GENERATION_SHUFFLE_2: case ITDB_IPOD_GENERATION_SHUFFLE_3: @@ -2075,6 +2111,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -2111,6 +2148,7 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_VIDEO_1: case ITDB_IPOD_GENERATION_VIDEO_2: case ITDB_IPOD_GENERATION_CLASSIC_1: @@ -2119,6 +2157,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -2157,6 +2196,7 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_SHUFFLE_1: case ITDB_IPOD_GENERATION_SHUFFLE_2: case ITDB_IPOD_GENERATION_SHUFFLE_3: @@ -2170,6 +2210,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: @@ -2209,6 +2250,7 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: case ITDB_IPOD_GENERATION_VIDEO_1: case ITDB_IPOD_GENERATION_VIDEO_2: case ITDB_IPOD_GENERATION_CLASSIC_1: @@ -2217,6 +2259,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: case ITDB_IPOD_GENERATION_IPHONE_3: diff -Nru libgpod-0.7.94/src/itdb_device.h libgpod-0.7.95/src/itdb_device.h --- libgpod-0.7.94/src/itdb_device.h 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/src/itdb_device.h 2010-09-30 00:44:31.000000000 +0800 @@ -98,6 +98,8 @@ * and UTC * @iphone_sync_context:Private data passed as is to libimobiledevice by * itdb_start/stop_sync + * @iphone_sync_nest_level: Nesting count for itdb_start/stop_sync calls + * itdb_start/stop_sync * * Structure representing an iPod device * @@ -113,6 +115,7 @@ gboolean sysinfo_changed; gint timezone_shift; void *iphone_sync_context; + int iphone_sync_nest_level; }; /** diff -Nru libgpod-0.7.94/src/itdb.h libgpod-0.7.95/src/itdb.h --- libgpod-0.7.94/src/itdb.h 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/src/itdb.h 2010-09-30 00:44:31.000000000 +0800 @@ -120,6 +120,7 @@ * @ITDB_IPOD_GENERATION_TOUCH_1: First Generation iPod Touch * @ITDB_IPOD_GENERATION_TOUCH_2: Second Generation iPod Touch * @ITDB_IPOD_GENERATION_TOUCH_3: Third Generation iPod Touch + * @ITDB_IPOD_GENERATION_TOUCH_4: Fourth Generation iPod Touch * @ITDB_IPOD_GENERATION_IPHONE_1: First Generation iPhone * @ITDB_IPOD_GENERATION_IPHONE_2: Second Generation iPhone (aka iPhone 3G) * @ITDB_IPOD_GENERATION_IPHONE_3: Third Generation iPhone (aka iPhone 3GS) @@ -163,7 +164,9 @@ ITDB_IPOD_GENERATION_NANO_5, ITDB_IPOD_GENERATION_TOUCH_3, ITDB_IPOD_GENERATION_IPAD_1, - ITDB_IPOD_GENERATION_IPHONE_4 + ITDB_IPOD_GENERATION_IPHONE_4, + ITDB_IPOD_GENERATION_TOUCH_4, + ITDB_IPOD_GENERATION_NANO_6 } Itdb_IpodGeneration; /** @@ -1230,9 +1233,11 @@ * @ITDB_MEDIATYPE_AUDIO: Audio files * @ITDB_MEDIATYPE_MOVIE: Movies * @ITDB_MEDIATYPE_PODCAST: Podcasts + * @ITDB_MEDIATYPE_VIDEO_PODCAST: Video Podcasts * @ITDB_MEDIATYPE_AUDIOBOOK: Audio books * @ITDB_MEDIATYPE_MUSICVIDEO: Music videos * @ITDB_MEDIATYPE_TVSHOW: TV Shows + * @ITDB_MEDIATYPE_MUSIC_TVSHOW: TV Shows (also show in Music) * @ITDB_MEDIATYPE_RINGTONE: Ringtone * @ITDB_MEDIATYPE_RENTAL: Rental * @ITDB_MEDIATYPE_ITUNES_EXTRA: ? @@ -1243,26 +1248,36 @@ * * The mediatype is used to determine what menu a track appears under. For * example, setting the mediatype to #ITDB_MEDIATYPE_PODCAST makes the track - * appear on the Podcast menu. + * appear on the Podcast menu. Media type is a bitfield, so it can be a + * binary combination of these constants, make sure to use binary operators + * when you want to operate on media types (eg use a binary AND in + * preference over a straight == when you want to test if a track has a + * given media type). * * Since: 0.5.0 */ typedef enum { - ITDB_MEDIATYPE_AUDIO = 0x000001, - ITDB_MEDIATYPE_MOVIE = 0x000002, - ITDB_MEDIATYPE_PODCAST = 0x000004, - ITDB_MEDIATYPE_AUDIOBOOK = 0x000008, - ITDB_MEDIATYPE_MUSICVIDEO = 0x000020, - ITDB_MEDIATYPE_TVSHOW = 0x000040, - ITDB_MEDIATYPE_RINGTONE = 0x004000, - ITDB_MEDIATYPE_RENTAL = 0x008000, - ITDB_MEDIATYPE_ITUNES_EXTRA = 0x010000, - ITDB_MEDIATYPE_MEMO = 0x100000, - ITDB_MEDIATYPE_ITUNES_U = 0x200000, - ITDB_MEDIATYPE_EPUB_BOOK = 0x400000 + ITDB_MEDIATYPE_AUDIO = (1 << 0), + ITDB_MEDIATYPE_MOVIE = (1 << 1), + ITDB_MEDIATYPE_PODCAST = (1 << 2), + ITDB_MEDIATYPE_AUDIOBOOK = (1 << 3), + ITDB_MEDIATYPE_MUSICVIDEO = (1 << 5), + ITDB_MEDIATYPE_TVSHOW = (1 << 6), + ITDB_MEDIATYPE_RINGTONE = (1 << 14), + ITDB_MEDIATYPE_RENTAL = (1 << 15), + ITDB_MEDIATYPE_ITUNES_EXTRA = (1 << 16), + ITDB_MEDIATYPE_MEMO = (1 << 20), + ITDB_MEDIATYPE_ITUNES_U = (1 << 21), + ITDB_MEDIATYPE_EPUB_BOOK = (1 << 22) } Itdb_Mediatype; +/* Known compound media types which have been observed in iPod databases. + * This list is in no way exhaustive, and these constants are only helpers, + * there's nothing wrong with not using them. + */ +#define ITDB_MEDIATYPE_VIDEO_PODCAST (ITDB_MEDIATYPE_MOVIE | ITDB_MEDIATYPE_PODCAST) +#define ITDB_MEDIATYPE_MUSIC_TVSHOW (ITDB_MEDIATYPE_MUSICVIDEO | ITDB_MEDIATYPE_TVSHOW) typedef struct _Itdb_Track_Private Itdb_Track_Private; /** * Itdb_Track: @@ -1747,9 +1762,20 @@ ITDB_FILE_ERROR_ITDB_CORRUPT } ItdbFileError; +typedef enum +{ + ITDB_ERROR_SEEK, + ITDB_ERROR_CORRUPT, + ITDB_ERROR_NOTFOUND, + ITDB_ERROR_RENAME, + ITDB_ERROR_ITDB_CORRUPT, + ITDB_ERROR_SQLITE +} ItdbError; + /* Error domain */ -#define ITDB_FILE_ERROR itdb_file_error_quark () +#define ITDB_ERROR itdb_file_error_quark () +#define ITDB_FILE_ERROR ITDB_ERROR GQuark itdb_file_error_quark (void); diff -Nru libgpod-0.7.94/src/itdb_hash72.c libgpod-0.7.95/src/itdb_hash72.c --- libgpod-0.7.94/src/itdb_hash72.c 2010-02-07 23:30:02.000000000 +0800 +++ libgpod-0.7.95/src/itdb_hash72.c 2010-09-30 00:44:31.000000000 +0800 @@ -311,12 +311,17 @@ gboolean itdb_hash72_compute_hash_for_sha1 (const Itdb_Device *device, const guchar sha1[20], - guchar signature[46]) + guchar signature[46], + GError **error) { struct Hash78Info *hash_info; hash_info = read_hash_info (device); if (hash_info == NULL) { + if (error != NULL) { + g_set_error (error, ITDB_FILE_ERROR, ITDB_FILE_ERROR_NOTFOUND, + "Can't write iPod database because of missing HashInfo file"); + } return FALSE; } hash_generate (signature, sha1, hash_info->iv, hash_info->rndpart); @@ -341,5 +346,5 @@ header = (MhbdHeader *)itdb_data; header->hashing_scheme = GUINT16_FROM_LE (ITDB_CHECKSUM_HASH72); itdb_hash72_compute_itunesdb_sha1 (itdb_data, itdb_len, sha1); - return itdb_hash72_compute_hash_for_sha1 (device, sha1, header->hash72); + return itdb_hash72_compute_hash_for_sha1 (device, sha1, header->hash72, error); } diff -Nru libgpod-0.7.94/src/itdb_itunesdb.c libgpod-0.7.95/src/itdb_itunesdb.c --- libgpod-0.7.94/src/itdb_itunesdb.c 2010-09-01 05:00:23.000000000 +0800 +++ libgpod-0.7.95/src/itdb_itunesdb.c 2010-09-30 00:44:31.000000000 +0800 @@ -111,12 +111,14 @@ #include "itdb_device.h" #include "itdb_private.h" #include "itdb_zlib.h" +#include "itdb_plist.h" #include #include #include #include #include +#include #include #include #include @@ -904,7 +906,7 @@ } -/* called by init_playcounts */ +/* called by playcounts_init */ static gboolean playcounts_read (FImport *fimp, FContents *cts) { GList* playcounts = NULL; @@ -1015,7 +1017,7 @@ } -/* called by init_playcounts */ +/* called by playcounts_init */ static gboolean itunesstats_read (FImport *fimp, FContents *cts) { GList* playcounts = NULL; @@ -1117,7 +1119,84 @@ return TRUE; } +static gint64 playcounts_plist_get_gint64 (GHashTable *track_dict, + const char *key) +{ + GValue *value; + + value = g_hash_table_lookup (track_dict, key); + if (value && G_VALUE_HOLDS (value, G_TYPE_INT64)) { + return g_value_get_int64 (value); + } + + return 0; +} + +/* called by playcounts_init */ +static gboolean playcounts_plist_read (FImport *fimp, GValue *plist_data) +{ + GHashTable *playcounts; + struct playcount *playcount; + GHashTable *pc_dict, *track_dict; + GValue *to_parse; + GValueArray *array; + gint i; + guint32 mac_time; + guint64 *dbid; + g_return_val_if_fail (G_VALUE_HOLDS (plist_data, G_TYPE_HASH_TABLE), FALSE); + pc_dict = g_value_get_boxed (plist_data); + + to_parse = g_hash_table_lookup (pc_dict, "tracks"); + if (to_parse == NULL) { + return FALSE; + } + if (!G_VALUE_HOLDS (to_parse, G_TYPE_VALUE_ARRAY)) { + return FALSE; + } + + playcounts = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, g_free); + + array = (GValueArray*)g_value_get_boxed (to_parse); + for (i = 0; i < array->n_values; i++) { + if (!G_VALUE_HOLDS (g_value_array_get_nth (array, i), G_TYPE_HASH_TABLE)) { + continue; + } + + track_dict = g_value_get_boxed (g_value_array_get_nth (array, i)); + if (track_dict == NULL) + continue; + + to_parse = g_hash_table_lookup (track_dict, "persistentID"); + if (!to_parse) + continue; + + dbid = g_new0 (guint64, 1); + if (!G_VALUE_HOLDS (to_parse, G_TYPE_INT64)) + continue; + *dbid = g_value_get_int64 (to_parse); + playcount = g_new0 (struct playcount, 1); + g_hash_table_insert (playcounts, dbid, playcount); + + playcount->bookmark_time = playcounts_plist_get_gint64 (track_dict, "bookmarkTimeInMS"); + playcount->playcount = playcounts_plist_get_gint64 (track_dict, "playCount"); + mac_time = playcounts_plist_get_gint64 (track_dict, "playMacOSDate"); + playcount->time_played = device_time_mac_to_time_t (fimp->itdb->device, mac_time); + playcount->skipcount = playcounts_plist_get_gint64 (track_dict, "skipCount"); + mac_time = playcounts_plist_get_gint64 (track_dict, "skipMacOSDate"); + playcount->last_skipped = device_time_mac_to_time_t (fimp->itdb->device, mac_time); + playcount->rating = playcounts_plist_get_gint64 (track_dict, "userRating"); + if (!playcount->rating) + playcount->rating = NO_PLAYCOUNT; + + to_parse = g_hash_table_lookup (track_dict, "playedState"); + if (to_parse && G_VALUE_HOLDS (to_parse, G_TYPE_BOOLEAN)) { + ; /* What do we do with this? */ + } + } + fimp->pcounts2 = playcounts; + return TRUE; +} /* Read the Play Count file (formed by adding "Play Counts" to the * directory component of fimp->itdb->itdb_filename) and set up the @@ -1132,10 +1211,12 @@ { const gchar *plc[] = {"Play Counts", NULL}; const gchar *ist[] = {"iTunesStats", NULL}; - gchar *plcname, *dirname, *istname; + const gchar *plcpl[] = {"PlayCounts.plist", NULL}; + gchar *plcname, *dirname, *istname, *plcplname; gboolean result=TRUE; struct stat filestat; FContents *cts; + GValue *plist_data; g_return_val_if_fail (fimp, FALSE); g_return_val_if_fail (!fimp->error, FALSE); @@ -1147,6 +1228,7 @@ plcname = itdb_resolve_path (dirname, plc); istname = itdb_resolve_path (dirname, ist); + plcplname = itdb_resolve_path (dirname, plcpl); g_free (dirname); @@ -1189,9 +1271,28 @@ } } } + else if (plcplname) + { + /* skip if PlayCounts.plist file has zero-length */ + stat (plcplname, &filestat); + if (filestat.st_size > 0) + { + plist_data = itdb_plist_parse_from_file (plcplname, &fimp->error); + if (plist_data) + { + result = playcounts_plist_read (fimp, plist_data); + g_value_unset (plist_data); + } + else + { + result = FALSE; + } + } + } g_free (plcname); g_free (istname); + g_free (plcplname); return result; } @@ -1207,6 +1308,9 @@ g_list_free (fimp->pos_glist); g_list_free (fimp->tracks); playcounts_free (fimp); + if (fimp->pcounts2 != NULL) { + g_hash_table_destroy (fimp->pcounts2); + } g_free (fimp); } } @@ -1530,26 +1634,33 @@ if (check_header_seek (cts, "chap", seek+4)) { guint32 length; + guint32 childlength; guint32 startpos; + guint32 children; + gint j; gunichar2 *string_utf16; startpos = get32bint (cts, seek+8); + children = get32bint (cts, seek+12); seek += 20; - if (check_header_seek (cts, "name", seek+4)) + for (j=0; jpcounts2) + { + playcount = g_hash_table_lookup (fimp->pcounts2, &track->dbid); + free_playcount = FALSE; + } if (playcount) { if (playcount->rating != NO_PLAYCOUNT) @@ -2586,8 +2704,8 @@ track->skipcount += playcount->skipcount; track->recent_skipcount = playcount->skipcount; - - g_free (playcount); + if (free_playcount) + g_free (playcount); } fimp->tracks = g_list_prepend(fimp->tracks, track); return seek; @@ -4195,6 +4313,56 @@ g_list_free (coltracks); } +static void +itdb_chapterdata_build_chapter_blob_internal (WContents *cts, + Itdb_Chapterdata *chapterdata) +{ + gulong atom_len_seek; + gint numchapters; + GList *ch_gl = NULL; + /* printf("[%s] -- inserting into \"chapter\"\n", __func__); */ + + numchapters = g_list_length (chapterdata->chapters); + + put32lint (cts, chapterdata->unk024); /* unknown */ + put32lint (cts, chapterdata->unk028); /* unknown */ + put32lint (cts, chapterdata->unk032); /* unknown */ + atom_len_seek = cts->pos; /* needed to fix length */ + put32bint (cts, -1); /* total length of sean atom, fix later */ + put_header (cts, "sean"); + put32bint (cts, 1); /* unknown */ + put32bint (cts, numchapters+1); /* children */ + put32bint (cts, 0); /* unknown */ + for (ch_gl=chapterdata->chapters; ch_gl; ch_gl=ch_gl->next) + { + gunichar2 *title_utf16; + Itdb_Chapter *chapter = ch_gl->data; + glong len; + title_utf16 = g_utf8_to_utf16 (chapter->chaptertitle, -1, NULL, &len, NULL); + fixup_big_utf16 (title_utf16); + put32bint (cts, 42+2*len); /* total length */ + put_header (cts, "chap"); + put32bint (cts, chapter->startpos); /* should we check if startpos=0 here? */ + put32bint (cts, 1); /* children */ + put32bint (cts, 0); /* unknown */ + put32bint (cts, 22+2*len); /* length */ + put_header (cts, "name"); + put32bint (cts, 1); /* unknown */ + put32_n0 (cts, 2); /* unknown */ + put16bint (cts, len); + put_data (cts, (gchar *)title_utf16, 2*len); + g_free (title_utf16); + } + put32bint (cts, 28); /* size */ + put_header (cts, "hedr"); + put32bint (cts, 1); /* unknown */ + put32bint (cts, 0); /* children */ + put32_n0 (cts, 2); /* unknown */ + put32bint (cts, 1); /* unknown */ + + put32bint_seek (cts, cts->pos-atom_len_seek, atom_len_seek); /* size */ +} + /* Write out one mhod header. type: see enum of MHMOD_IDs; data: utf8 string for text items @@ -4306,54 +4474,12 @@ g_return_if_fail (mhod->data.chapterdata); { gulong header_seek = cts->pos; /* needed to fix length */ - GList *gl; - gint numchapters = g_list_length (mhod->data.chapterdata->chapters); put_header (cts, "mhod"); /* header */ put32lint (cts, 24); /* header size */ put32lint (cts, -1); /* total length, fix later */ put32lint (cts, mhod->type); /* entry type */ put32_n0 (cts, 2); /* unknown */ - put32lint (cts, mhod->data.chapterdata->unk024); /* unknown */ - put32lint (cts, mhod->data.chapterdata->unk028); /* unknown */ - put32lint (cts, mhod->data.chapterdata->unk032); /* unknown */ - put32bint (cts, -1); /* total length of sean atom, fix later */ - put_header (cts, "sean"); - put32bint (cts, 1); /* unknown */ - put32bint (cts, numchapters+1); /* children */ - put32bint (cts, 0); /* unknown */ - for (gl=mhod->data.chapterdata->chapters; gl; gl=gl->next) - { - gunichar2 *title_utf16; - Itdb_Chapter *chapter = gl->data; -/* gint len = strlen(chapter->chaptertitle); */ - glong len; - title_utf16 = NULL; - title_utf16 = g_utf8_to_utf16 (chapter->chaptertitle, - -1,NULL,&len,NULL); - fixup_big_utf16 (title_utf16); - put32bint (cts, 42+2*len); /* total length */ - put_header (cts, "chap"); - put32bint (cts, chapter->startpos); /* should we check if startpos=0 here? */ - put32bint (cts, 1); /* children */ - put32bint (cts, 0); /* unknown */ - put32bint (cts, 22+2*len); /* length */ - put_header (cts, "name"); - put32bint (cts, 1); /* unknown */ - put32_n0 (cts, 2); /* unknown */ - put16bint (cts, len); - put_data (cts, (gchar *)title_utf16, 2*len); - g_free (title_utf16); - - } - put32bint (cts, 28); /* size */ - put_header (cts, "hedr"); - put32bint (cts, 1); /* unknown */ - put32bint (cts, 0); /* children */ - put32_n0 (cts, 2); /* unknown */ - put32bint (cts, 1); /* unknown */ - - - put32bint_seek (cts, cts->pos-(header_seek+36), header_seek+36); /* fix length of sean atom */ + itdb_chapterdata_build_chapter_blob_internal (cts, mhod->data.chapterdata); fix_header (cts, header_seek); } break; @@ -5761,15 +5887,6 @@ goto err; } - /* write albums (mhsd type 4) */ - if (!write_mhsd_albums (fexp)) { - g_set_error (&fexp->error, - ITDB_FILE_ERROR, - ITDB_FILE_ERROR_ITDB_CORRUPT, - _("Error writing list of albums (mhsd type 4)")); - goto err; - } - /* write special podcast version mhsd (mhsd type 3) */ if (!fexp->error && !write_mhsd_playlists (fexp, 3)) { g_set_error (&fexp->error, @@ -5787,6 +5904,14 @@ goto err; } + /* write albums (mhsd type 4) */ + if (!write_mhsd_albums (fexp)) { + g_set_error (&fexp->error, + ITDB_FILE_ERROR, + ITDB_FILE_ERROR_ITDB_CORRUPT, + _("Error writing list of albums (mhsd type 4)")); + goto err; + } /* write artists (mhsd type 8) */ if (!fexp->error && !write_mhsd_artists (fexp)) { g_set_error (&fexp->error, @@ -5984,6 +6109,9 @@ * but on iPhones and iPod Touch this makes sure the "Sync in progress" screen * is shown for the whole duration of the writing process. * + * Calls to itdb_start_sync must be paired with calls to itdb_stop_sync. Nesting + * is allowed. + * * Returns: TRUE on success, FALSE on error */ gboolean itdb_start_sync (Itdb_iTunesDB *itdb) @@ -5992,14 +6120,12 @@ g_return_val_if_fail (itdb->device != NULL, FALSE); #ifdef HAVE_LIBIMOBILEDEVICE - g_return_val_if_fail (itdb->device->iphone_sync_context == NULL, FALSE); + if (itdb->device->iphone_sync_context != NULL) { + itdb->device->iphone_sync_nest_level++; + return TRUE; + } if (itdb_device_is_iphone_family (itdb->device)) { int sync_status; - - if (itdb->device->iphone_sync_context != NULL) { - /* already locked */ - return TRUE; - } sync_status = itdb_iphone_start_sync (itdb->device, &itdb->device->iphone_sync_context); if (sync_status == 0) { @@ -6022,11 +6148,21 @@ * (but is safe to be used). On iPhones and iPod Touch this will hide the * "Sync in progress" screen. * + * Calls to itdb_stop_sync must be paired with calls to itdb_start_sync. Nesting + * is allowed, and only the final itdb_stop_sync will actually stop the sync. + * * Returns: TRUE on success, FALSE on error */ gboolean itdb_stop_sync (Itdb_iTunesDB *itdb) { + g_return_val_if_fail (itdb != NULL, FALSE); + g_return_val_if_fail (itdb->device != NULL, FALSE); + #ifdef HAVE_LIBIMOBILEDEVICE + if (itdb->device->iphone_sync_nest_level) { + itdb->device->iphone_sync_nest_level--; + return TRUE; + } if (itdb_device_is_iphone_family (itdb->device)) { int sync_status; if (itdb->device->iphone_sync_context == NULL) { @@ -6336,8 +6472,8 @@ put32lint_seek(cts, cts->pos, track_seek); g_return_val_if_fail (write_rths(cts, track), FALSE); - if (track->mediatype == ITDB_MEDIATYPE_AUDIOBOOK || - track->mediatype == ITDB_MEDIATYPE_PODCAST) + if ((track->mediatype & ITDB_MEDIATYPE_AUDIOBOOK) || + (track->mediatype & ITDB_MEDIATYPE_PODCAST)) nonstdtrackcnt++; /* Go to the offset for the next track */ @@ -6405,8 +6541,8 @@ id = tr->dbid; ctr = current_track->data; /* Count the number of podcasts and audiobooks for later use */ - if (tr->mediatype == ITDB_MEDIATYPE_AUDIOBOOK || - tr->mediatype == ITDB_MEDIATYPE_PODCAST) + if ((tr->mediatype & ITDB_MEDIATYPE_AUDIOBOOK) || + (tr->mediatype & ITDB_MEDIATYPE_PODCAST)) nonstdtrackcnt++; while( id != ctr->dbid) @@ -7456,12 +7592,20 @@ */ gchar *itdb_get_control_dir (const gchar *mountpoint) { + gchar *p_iphone[] = {"iTunes_Control", NULL}; gchar *p_ipod[] = {"iPod_Control", NULL}; gchar *p_mobile[] = {"iTunes", "iTunes_Control", NULL}; - gchar *p_iphone[] = {"iTunes_Control", NULL}; /* Use an array with all possibilities, so further extension will - be easy */ - gchar **paths[] = {p_ipod, p_mobile, p_iphone, NULL}; + be easy. It is important that checking for the iTunes_Control + directory be done before the iPod_Control directory because + some devices actually have both directories. The iTunes_Control + directory is correct in these cases. This happens for devices + that Apple shipped with the iPod_Control as the control directory + and later switched to iTunes_Control instead. iTunes appears to + remove files from the old iPod_Control directory but leave the + directory structure intact. Finding this empty directory structure + first will result in a failure to find files. */ + gchar **paths[] = {p_iphone, p_ipod, p_mobile, NULL}; gchar ***ptr; gchar *result = NULL; @@ -7887,6 +8031,38 @@ return TRUE; } +/** + * itdb_chapterdata_build_chapter_blob: + * @chapterdata: Itdb_Chapterdata pointer of chapter data to be encoded + * + * Creates an iTunesDB binary blob of chapter data from @chapterdata. + * This helper function is used by both mk_mhod() in itdb_itunesdb.c + * and mk_Extras() in itdb_sqlite.c, so take care when updating to + * maintain compatibility with both chapterdata blobs. + * + * NOTE: Caller must call g_byte_array_free(chapter_blob, TRUE) on the + * returned chapter_blob + * + * Returns: a binary itdb blob of chapter data (to be freed by the caller) + * + * Since: 0.7.95 + */ +G_GNUC_INTERNAL GByteArray *itdb_chapterdata_build_chapter_blob(Itdb_Chapterdata *chapterdata, gboolean reversed) +{ + WContents *cts; + GByteArray * chapter_blob = NULL; + + cts = wcontents_new(""); + cts->reversed = reversed; + cts->pos = 0; + + itdb_chapterdata_build_chapter_blob_internal (cts, chapterdata); + + chapter_blob = g_byte_array_sized_new(cts->pos); + g_byte_array_append(chapter_blob, (guint8 *)cts->contents, cts->pos); + wcontents_free(cts); + return chapter_blob; +} /*------------------------------------------------------------------*\ @@ -7940,6 +8116,35 @@ return device->mountpoint; } +static gchar *itdb_device_get_control_dir (const Itdb_Device *device) +{ + Itdb_IpodInfo const *info = NULL; + char *podpath; + + podpath = itdb_get_control_dir (device->mountpoint); + if (podpath != NULL) { + return podpath; + } + + /* The device doesn't already have an iPod_Control directory, let's try + * to get which one is appropriate to use + */ + info = itdb_device_get_ipod_info (device); + + if (itdb_device_is_shuffle (device)) { + podpath = g_build_filename (device->mountpoint, "iPod_Control", NULL); + } else if (itdb_device_is_iphone_family (device)) { + podpath = g_build_filename (device->mountpoint,"iTunes_Control", NULL); + } else if (info->ipod_model == ITDB_IPOD_MODEL_MOBILE_1) { + podpath = g_build_filename (device->mountpoint, + "iTunes", "iTunes_Control", + NULL); + } else { + podpath = g_build_filename (device->mountpoint, "iPod_Control", NULL); + } + + return podpath; +} /*------------------------------------------------------------------*\ @@ -7953,38 +8158,19 @@ gboolean result; gchar *pbuf; gint i, dirnum; - Itdb_IpodInfo const *info = NULL; - gboolean calconnotes, devicefile; gchar *podpath; + gchar *model_number; + Itdb_IpodInfo const *info = NULL; g_return_val_if_fail (device, FALSE); mp = device->mountpoint; - g_return_val_if_fail (mp, FALSE); + info = itdb_device_get_ipod_info (device); - /* Retrieve the model from the device information */ - info = itdb_device_get_ipod_info(device); - - if (itdb_device_is_shuffle (device)) { - podpath = g_strdup ("iPod_Control"); - calconnotes = FALSE; - devicefile = TRUE; - } else if (itdb_device_is_iphone_family (device)) { - podpath = g_strdup ("iTunes_Control"); - calconnotes = FALSE; - devicefile = TRUE; - } else if (info->ipod_model == ITDB_IPOD_MODEL_MOBILE_1) { - podpath = g_build_filename ("iTunes", "iTunes_Control", NULL); - calconnotes = FALSE; - devicefile = TRUE; - } else { - podpath = g_strdup ("iPod_Control"); - calconnotes = TRUE; - devicefile = TRUE; - } + g_return_val_if_fail (mp, FALSE); /* Construct the Control directory */ - pbuf = g_build_filename (mp, podpath, NULL); + pbuf = itdb_device_get_control_dir (device); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { if (g_mkdir_with_parents(pbuf, 0777) != 0) @@ -7993,9 +8179,13 @@ } } g_free (pbuf); + podpath = itdb_get_control_dir (mp); + if (!podpath) { + goto error_dir; + } /* Construct the Music directory inside the Control directory */ - pbuf = g_build_filename (mp, podpath, "Music", NULL); + pbuf = g_build_filename (podpath, "Music", NULL); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { if((g_mkdir(pbuf, 0777) != 0)) @@ -8006,7 +8196,7 @@ g_free (pbuf); /* Construct the iTunes directory inside the Control directory */ - pbuf = g_build_filename (mp, podpath, "iTunes", NULL); + pbuf = g_build_filename (podpath, "iTunes", NULL); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { if((g_mkdir(pbuf, 0777) != 0)) @@ -8022,7 +8212,7 @@ if (itdb_device_supports_artwork(device) || (info->ipod_model == ITDB_IPOD_MODEL_UNKNOWN)) { - pbuf = g_build_filename (mp, podpath, "Artwork", NULL); + pbuf = g_build_filename (podpath, "Artwork", NULL); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { if((g_mkdir(pbuf, 0777) != 0)) { @@ -8064,7 +8254,7 @@ for(i = 0; i < dirnum; i++) { gchar *num = g_strdup_printf ("F%02d", i); - pbuf = g_build_filename (mp, podpath, "Music", num, NULL); + pbuf = g_build_filename (podpath, "Music", num, NULL); g_free (num); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { @@ -8077,7 +8267,8 @@ } /* Build Calendar directory for models requiring it */ - if (calconnotes) + if (!itdb_device_is_iphone_family (device) + && !itdb_device_is_shuffle (device)) { pbuf = g_build_filename (mp, "Calendars", NULL); if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) @@ -8112,33 +8303,28 @@ } /* Construct a Device directory file for special models */ - if (devicefile) + pbuf = g_build_filename (podpath, "Device", NULL); + if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) { - gchar *model_number; - - pbuf = g_build_filename (mp, podpath, "Device", NULL); - if (!g_file_test (pbuf, G_FILE_TEST_EXISTS)) - { - if((g_mkdir(pbuf, 0777) != 0)) - { - goto error_dir; - } - } - g_free (pbuf); + if((g_mkdir(pbuf, 0777) != 0)) + { + goto error_dir; + } + } + g_free (pbuf); - model_number = itdb_device_get_sysinfo (device, "ModelNumStr"); - /* Construct a SysInfo file */ - if (model_number && (strlen (model_number) != 0)) - { - pbuf = NULL; - if (!itdb_device_write_sysinfo (device, error)) - { - g_free (model_number); - goto error_dir; - } - } - g_free (model_number); + model_number = itdb_device_get_sysinfo (device, "ModelNumStr"); + /* Construct a SysInfo file */ + if (model_number && (strlen (model_number) != 0)) + { + pbuf = NULL; + if (!itdb_device_write_sysinfo (device, error)) + { + g_free (model_number); + goto error_dir; + } } + g_free (model_number); pbuf = NULL; error_dir: diff -Nru libgpod-0.7.94/src/itdb_playlist.c libgpod-0.7.95/src/itdb_playlist.c --- libgpod-0.7.94/src/itdb_playlist.c 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/src/itdb_playlist.c 2010-09-30 00:44:31.000000000 +0800 @@ -1595,7 +1595,7 @@ for (tl = pl->members; tl; tl = tl->next) { track = tl->data; - if (track->mediatype != ITDB_MEDIATYPE_AUDIOBOOK) + if (!(track->mediatype & ITDB_MEDIATYPE_AUDIOBOOK)) { return FALSE; } diff -Nru libgpod-0.7.94/src/itdb_plist.c libgpod-0.7.95/src/itdb_plist.c --- libgpod-0.7.94/src/itdb_plist.c 2010-09-01 05:00:23.000000000 +0800 +++ libgpod-0.7.95/src/itdb_plist.c 2010-09-20 21:45:04.000000000 +0800 @@ -37,7 +37,7 @@ * in GValue. The types are mapped in the following way: * - => G_TYPE_STRING (char*) * - => G_TYPE_DOUBLE (double) - * - => G_TYPE_INT (gint) + * - => G_TYPE_INT64 (gint64) * - , => G_TYPE_BOOLEAN (gboolean) * - => G_TYPE_GSTRING (GString *) * - => G_TYPE_VALUE_ARRAY (GValueArray *) @@ -82,11 +82,11 @@ { char *str_val; char *end_ptr; - gint int_val; + gint64 int_val; GValue *value; str_val = (char *)xmlNodeGetContent(a_node); - int_val = strtol (str_val, &end_ptr, 0); + int_val = strtoll (str_val, &end_ptr, 0); if (*end_ptr != '\0') { g_set_error (error, ITDB_DEVICE_ERROR, ITDB_DEVICE_ERROR_XML_PARSING, "invalid integer value: %s", str_val); @@ -96,8 +96,8 @@ xmlFree (str_val); value = g_new0(GValue, 1); - g_value_init(value, G_TYPE_INT); - g_value_set_int (value, int_val); + g_value_init(value, G_TYPE_INT64); + g_value_set_int64 (value, int_val); return value; } diff -Nru libgpod-0.7.94/src/itdb_private.h libgpod-0.7.95/src/itdb_private.h --- libgpod-0.7.94/src/itdb_private.h 2010-09-01 05:00:23.000000000 +0800 +++ libgpod-0.7.95/src/itdb_private.h 2010-09-30 00:44:31.000000000 +0800 @@ -91,6 +91,7 @@ GList *pos_glist; /* temporary list to store position indicators */ GList *tracks; /* temporary list to store tracks */ GList *playcounts; /* contents of Play Counts file */ + GHashTable *pcounts2;/* contents of the PlayCounts.plist file */ GTree *idtree; /* temporary tree with track id tree */ GError *error; /* where to report errors to */ } FImport; @@ -240,7 +241,12 @@ GError **error); G_GNUC_INTERNAL gboolean itdb_hash72_compute_hash_for_sha1 (const Itdb_Device *device, const guchar sha1[20], - guchar signature[46]); + guchar signature[46], + GError **error); + +G_GNUC_INTERNAL GByteArray *itdb_chapterdata_build_chapter_blob(Itdb_Chapterdata *chapterdata, + gboolean reversed); + #ifdef HAVE_LIBIMOBILEDEVICE G_GNUC_INTERNAL int itdb_iphone_start_sync(Itdb_Device *device, void **prepdata); G_GNUC_INTERNAL int itdb_iphone_stop_sync(void *sync_ctx); diff -Nru libgpod-0.7.94/src/itdb_sqlite.c libgpod-0.7.95/src/itdb_sqlite.c --- libgpod-0.7.94/src/itdb_sqlite.c 2010-09-01 05:00:23.000000000 +0800 +++ libgpod-0.7.95/src/itdb_sqlite.c 2010-09-30 00:44:34.000000000 +0800 @@ -361,8 +361,10 @@ int rebuild = 0; gchar *dbf = NULL; sqlite3 *db = NULL; + sqlite3_stmt *stmt_chapter = NULL; char *errmsg = NULL; struct stat fst; + GList *gl = NULL; dbf = g_build_filename(outpath, "Extras.itdb", NULL); printf("[%s] Processing '%s'\n", __func__, dbf); @@ -398,10 +400,13 @@ } sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); + if (SQLITE_OK != sqlite3_prepare_v2(db, "INSERT INTO \"chapter\" VALUES(?,?);", -1, &stmt_chapter, NULL)) { + fprintf(stderr, "[%s] sqlite3_prepare error: %s\n", __func__, sqlite3_errmsg(db)); + goto leave; + } /* kill all entries in 'chapter' as they will be re-inserted */ - /* TODO: we do not support this in the moment, so don't touch this */ - /*if (SQLITE_OK != sqlite3_exec(db, "DELETE FROM chapter;", NULL, NULL, &errmsg)) { + if (SQLITE_OK != sqlite3_exec(db, "DELETE FROM chapter;", NULL, NULL, &errmsg)) { fprintf(stderr, "[%s] sqlite3_exec error: %s\n", __func__, sqlite3_errmsg(db)); if (errmsg) { fprintf(stderr, "[%s] additional error information: %s\n", __func__, errmsg); @@ -409,7 +414,7 @@ errmsg = NULL; } goto leave; - }*/ + } /* kill all entries in 'lyrics' as they will be re-inserted */ /* TODO: we do not support this in the moment, so don't touch this */ @@ -423,11 +428,38 @@ goto leave; }*/ + for (gl = itdb->tracks; gl; gl = gl->next) { + Itdb_Track *track = gl->data; + if (track->chapterdata) { + int idx = 0; + GByteArray *chapter_blob = itdb_chapterdata_build_chapter_blob(track->chapterdata, FALSE); + /* printf("[%s] -- inserting into \"chapter\"\n", __func__); */ + res = sqlite3_reset(stmt_chapter); + if (res != SQLITE_OK) { + fprintf(stderr, "[%s] 1 sqlite3_reset returned %d\n", __func__, res); + } + /* item_pid INTEGER NOT NULL */ + sqlite3_bind_int64(stmt_chapter, ++idx, track->dbid); + /* data BLOB */ + sqlite3_bind_blob(stmt_chapter, ++idx, chapter_blob->data, chapter_blob->len, SQLITE_TRANSIENT); + + res = sqlite3_step(stmt_chapter); + if (res == SQLITE_DONE) { + /* expected result */ + } else { + fprintf(stderr, "[%s] 8 sqlite3_step returned %d\n", __func__, res); + } + g_byte_array_free(chapter_blob, TRUE); + } + } sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); res = 0; printf("[%s] done.\n", __func__); leave: + if (stmt_chapter) { + sqlite3_finalize(stmt_chapter); + } if (db) { sqlite3_close(db); } @@ -1264,11 +1296,11 @@ /* series_name TEXT */ sqlite3_bind_text(stmt_video_info, ++idx, track->tvshow, -1, SQLITE_STATIC); /* sort_series_name TEXT */ - sqlite3_bind_text(stmt_video_info, ++idx, track->sort_tvshow, -1, SQLITE_STATIC); + bind_first_text(stmt_item, ++idx, 2, track->sort_tvshow, track->tvshow); /* episode_id TEXT */ sqlite3_bind_text(stmt_video_info, ++idx, track->tvepisode, -1, SQLITE_STATIC); /* episode_sort_id INTEGER */ - sqlite3_bind_int(stmt_video_info, ++idx, track->episode_nr); + sqlite3_bind_int(stmt_video_info, ++idx, track->season_nr << 16 | track->episode_nr); /* network_name TEXT */ sqlite3_bind_text(stmt_video_info, ++idx, track->tvnetwork, -1, SQLITE_STATIC); /* extended_content_rating TEXT */ @@ -1876,7 +1908,7 @@ final_sha1 = &g_array_index(cbk, guchar, CBK_HEADER_SIZE); cbk_hash72 = &g_array_index(cbk, guchar, 0); success = itdb_hash72_compute_hash_for_sha1 (itdb->device, final_sha1, - cbk_hash72); + cbk_hash72, NULL); if (!success) { g_array_free(cbk, TRUE); return FALSE; @@ -1924,38 +1956,41 @@ return 0; } -static int ensure_itlp_dir_exists(const char *itlpdir) +static int ensure_itlp_dir_exists(const char *itlpdir, GError **error) { /* check if directory exists */ if (!g_file_test(itlpdir, G_FILE_TEST_EXISTS)) { if (g_mkdir(itlpdir, 0755) != 0) { - fprintf(stderr, "Could not create directory '%s': %s\n", itlpdir, strerror(errno)); - return FALSE; + g_set_error (error, G_FILE_ERROR, + g_file_error_from_errno(errno), + "Could not create directory '%s': %s", + itlpdir, strerror(errno)); + return FALSE; } } else if (!g_file_test(itlpdir, G_FILE_TEST_IS_DIR)) { - fprintf(stderr, "'%s' is not a directory as it should be!\n", itlpdir); - return FALSE; + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR, + "'%s' is not a directory as it should be", + itlpdir); + return FALSE; } return TRUE; } -static int copy_itdb_file(gchar *from_dir, gchar *to_dir, gchar *fname) +static int copy_itdb_file(const gchar *from_dir, const gchar *to_dir, + const gchar *fname, GError **error) { int res = 0; gchar *srcname = g_build_filename(from_dir, fname, NULL); gchar *dstname = g_build_filename(to_dir, fname, NULL); - GError *error = NULL; - if (itdb_cp(srcname, dstname, &error)) { + if (itdb_cp(srcname, dstname, error)) { fprintf(stderr, "itdbprep: copying '%s'\n", fname); res++; } - - if (error) { - fprintf(stderr, "Error copying '%s' to '%s': %s\n", srcname, dstname, error->message); - g_error_free(error); + if (error && *error) { + fprintf(stderr, "Error copying '%s' to '%s': %s\n", srcname, dstname, (*error)->message); } if (srcname) { @@ -2009,7 +2044,7 @@ printf("itlp directory='%s'\n", itlpdir); - if (!ensure_itlp_dir_exists(itlpdir)) { + if (!ensure_itlp_dir_exists(itlpdir, &fexp->error)) { res = -1; goto leave; } @@ -2023,7 +2058,9 @@ tmpdir = g_build_path(g_get_tmp_dir(), tmpnam(NULL), NULL); if (g_mkdir(tmpdir, 0755) != 0) { - fprintf(stderr, "Could not create temporary directory '%s': %s\n", tmpdir, strerror(errno)); + g_set_error (&fexp->error, G_FILE_ERROR, g_file_error_from_errno(errno), + "Could not create temporary directory '%s': %s", + tmpdir, strerror(errno)); res = -1; goto leave; } @@ -2031,19 +2068,31 @@ /* generate itdb files in temporary directory */ if (build_itdb_files(fexp->itdb, fexp->albums, fexp->artists, fexp->composers, tmpdir, itdb_device_get_uuid(fexp->itdb->device)) != 0) { + g_set_error (&fexp->error, ITDB_ERROR, ITDB_ERROR_SQLITE, + "Failed to generate sqlite database"); res = -1; goto leave; } else { /* copy files */ - int cpcnt = 0; - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Dynamic.itdb"); - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Extras.itdb"); - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Genius.itdb"); - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Library.itdb"); - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Locations.itdb"); - cpcnt += copy_itdb_file(tmpdir, itlpdir, "Locations.itdb.cbk"); - if (cpcnt != 6) { - res = -1; + const char *itdb_files[] = { "Dynamic.itdb", "Extras.itdb", + "Genius.itdb", "Library.itdb", + "Locations.itdb", "Locations.itdb.cbk", + NULL }; + const char **file; + GError *error = NULL; + g_assert (fexp->error == NULL); + for (file = itdb_files; *file != NULL; file++) { + copy_itdb_file(tmpdir, itlpdir, *file, &error); + if (error) { + res = -1; + /* only the last error will be reported, but this way we + * copy as many files as possible even when errors occur + */ + g_clear_error (&fexp->error); + g_propagate_error (&fexp->error, error); + } + } + if (fexp->error) { goto leave; } } diff -Nru libgpod-0.7.94/src/itdb_sysinfo_extended_parser.c libgpod-0.7.95/src/itdb_sysinfo_extended_parser.c --- libgpod-0.7.94/src/itdb_sysinfo_extended_parser.c 2010-09-01 05:00:23.000000000 +0800 +++ libgpod-0.7.95/src/itdb_sysinfo_extended_parser.c 2010-09-20 21:45:04.000000000 +0800 @@ -111,7 +111,7 @@ gboolean sqlite_db; }; -static gint get_int (GHashTable *dict, const char *key) +static gint64 get_int64 (GHashTable *dict, const char *key) { GValue *val; @@ -119,10 +119,10 @@ if (val == NULL) { return 0; } - if (!G_VALUE_HOLDS_INT (val)) { + if (!G_VALUE_HOLDS_INT64 (val)) { return 0; } - return g_value_get_int (val); + return g_value_get_int64 (val); } static gdouble get_double (GHashTable *dict, const char *key) @@ -177,8 +177,8 @@ static const DictFieldMapping sysinfo_ipod_properties_fields_mapping[] = { { "BuildID", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, build_id) }, { "ConnectedBus", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, connected_bus) }, - { "MaxTransferSpeed", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, max_transfer_speed) }, - { "FamilyID", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, family_id) }, + { "MaxTransferSpeed", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, max_transfer_speed) }, + { "FamilyID", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, family_id) }, { "ProductType", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, product_type) }, { "FireWireGUID", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, firewire_guid) }, { "FireWireVersion", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, firewire_version) }, @@ -186,17 +186,17 @@ { "MinITunesVersion", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, min_itunes_version) }, { "PlaylistFoldersSupported", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, playlist_folders_supported) }, { "SerialNumber", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, serial_number) }, - { "UpdaterFamilyID", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, updater_family_id) }, + { "UpdaterFamilyID", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, updater_family_id) }, { "VisibleBuildID", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, visible_build_id) }, - { "OEMID", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, oem_id) }, - { "OEMU", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, oem_u) }, - { "DBVersion", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, db_version) }, + { "OEMID", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, oem_id) }, + { "OEMU", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, oem_u) }, + { "DBVersion", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, db_version) }, { "MinBuildID", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, min_build_id) }, { "Language", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, language) }, { "VoiceMemosSupported", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, voice_memos_supported) }, - { "UpdateMethod", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, update_method) }, - { "MaxFWBlocks", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, max_fw_blocks) }, - { "FWPartSize", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, fw_part_size) }, + { "UpdateMethod", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, update_method) }, + { "MaxFWBlocks", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, max_fw_blocks) }, + { "FWPartSize", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, fw_part_size) }, { "AutoRebootAfterFirmwareUpdate", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, auto_reboot_after_firmware_update) }, { "VolumeFormat", G_TYPE_STRING, G_STRUCT_OFFSET (SysInfoIpodProperties, volume_format) }, { "ForcedDiskMode", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, forced_disk_mode) }, @@ -207,27 +207,27 @@ { "CanHibernate", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, can_hibernate) }, { "CameWithCD", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, came_with_cd) }, { "SupportsSparseArtwork", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, supports_sparse_artwork) }, - { "MaxThumbFileSize", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, max_thumb_file_size) }, - { "RAM", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, ram) }, - { "HotPlugState", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, hotplug_state) }, - { "BatteryPollInterval", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, battery_poll_interval) }, + { "MaxThumbFileSize", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, max_thumb_file_size) }, + { "RAM", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, ram) }, + { "HotPlugState", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, hotplug_state) }, + { "BatteryPollInterval", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, battery_poll_interval) }, { "SortFieldsSupported", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, sort_fields_supported) }, { "vCardWithJPEGSupported", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, vcard_with_jpeg_supported) }, - { "MaxFileSizeInGB", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, max_file_size_in_gb) }, - { "MaxTracks", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, max_tracks) }, - { "GamesPlatformID", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, games_platform_id) }, - { "GamesPlatformVersion", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, games_platform_version) }, - { "RentalClockBias", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, rental_clock_bias) }, + { "MaxFileSizeInGB", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, max_file_size_in_gb) }, + { "MaxTracks", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, max_tracks) }, + { "GamesPlatformID", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, games_platform_id) }, + { "GamesPlatformVersion", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, games_platform_version) }, + { "RentalClockBias", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, rental_clock_bias) }, { "SQLiteDB", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (SysInfoIpodProperties, sqlite_db) }, - { "ShadowDBVersion", G_TYPE_INT, G_STRUCT_OFFSET (SysInfoIpodProperties, shadowdb_version) }, + { "ShadowDBVersion", G_TYPE_INT64, G_STRUCT_OFFSET (SysInfoIpodProperties, shadowdb_version) }, { NULL, G_TYPE_NONE, 0 } }; static const DictFieldMapping sysinfo_image_format_fields_mapping[] = { - { "FormatId", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, format_id) }, - { "DisplayWidth", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, display_width) }, - { "RenderWidth", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, width) }, - { "RenderHeight", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, height) }, + { "FormatId", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, format_id) }, + { "DisplayWidth", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, display_width) }, + { "RenderWidth", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, width) }, + { "RenderHeight", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, height) }, /* PixelFormat needs to be converted to ItdbThumbFormat, this is special-cased * in g_value_to_image_format */ /* { "PixelFormat", G_TYPE_STRING, G_STRUCT_OFFSET (Itdb_ArtworkFormat, format) },*/ @@ -236,14 +236,14 @@ /* AlignRowBytes is an older version of RowBytesAlignment, it's equivalent * to a value of 4 for RowBytesAlignemnt */ /* { "AlignRowBytes", G_TYPE_BOOLEAN, G_STRUCT_OFFSET (Itdb_ArtworkFormat, align_row_bytes) },*/ - { "Rotation", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, rotation) }, + { "Rotation", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, rotation) }, /* BackColor needs to be converted to a gint, this is special-cased * in g_value_to_image_format */ -/* { "BackColor", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, back_color) }, */ - { "ColorAdjustment", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, color_adjustment) }, +/* { "BackColor", G_TYPE_INT64 G_STRUCT_OFFSET (Itdb_ArtworkFormat, back_color) }, */ + { "ColorAdjustment", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, color_adjustment) }, { "GammaAdjustment", G_TYPE_DOUBLE, G_STRUCT_OFFSET (Itdb_ArtworkFormat, gamma) }, - { "AssociatedFormat", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, associated_format) }, - { "RowBytesAlignment", G_TYPE_INT, G_STRUCT_OFFSET (Itdb_ArtworkFormat, row_bytes_alignment) }, + { "AssociatedFormat", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, associated_format) }, + { "RowBytesAlignment", G_TYPE_INT64, G_STRUCT_OFFSET (Itdb_ArtworkFormat, row_bytes_alignment) }, { NULL, G_TYPE_NONE, 0 } }; @@ -262,10 +262,10 @@ g_return_if_fail (it != NULL); while (it->name != NULL) { switch (it->type) { - case G_TYPE_INT: { + case G_TYPE_INT64: { gint *field; field = G_STRUCT_MEMBER_P (struct_ptr, it->offset); - *field = get_int (dict, it->name); + *field = get_int64 (dict, it->name); break; } @@ -340,7 +340,7 @@ g_return_if_fail (it != NULL); while (it->name != NULL) { switch (it->type) { - case G_TYPE_INT: { + case G_TYPE_INT64: { gint *field; field = G_STRUCT_MEMBER_P (struct_ptr, it->offset); g_print ("%s: %d\n", it->name, *field); diff -Nru libgpod-0.7.94/src/itdb_tzinfo.c libgpod-0.7.95/src/itdb_tzinfo.c --- libgpod-0.7.94/src/itdb_tzinfo.c 2010-04-05 05:00:15.000000000 +0800 +++ libgpod-0.7.95/src/itdb_tzinfo.c 2010-09-30 00:44:31.000000000 +0800 @@ -47,6 +47,7 @@ static gboolean parse_tzdata (const char *tzname, time_t start, time_t end, int *offset, gboolean *has_dst, int *dst_offset); +/* Mac epoch is 1st January 1904 00:00 in local time */ G_GNUC_INTERNAL time_t device_time_mac_to_time_t (Itdb_Device *device, guint64 mactime) { g_return_val_if_fail (device, 0); diff -Nru libgpod-0.7.94/tools/generic-callout.c libgpod-0.7.95/tools/generic-callout.c --- libgpod-0.7.94/tools/generic-callout.c 2010-08-31 05:40:32.000000000 +0800 +++ libgpod-0.7.95/tools/generic-callout.c 2010-09-30 00:44:31.000000000 +0800 @@ -129,6 +129,7 @@ case ITDB_IPOD_GENERATION_NANO_3: case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: return g_strdup ("nano"); case ITDB_IPOD_GENERATION_VIDEO_1: case ITDB_IPOD_GENERATION_VIDEO_2: @@ -140,6 +141,7 @@ case ITDB_IPOD_GENERATION_TOUCH_1: case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: return g_strdup ("touch"); case ITDB_IPOD_GENERATION_IPHONE_1: case ITDB_IPOD_GENERATION_IPHONE_2: @@ -196,6 +198,8 @@ return 4.0; case ITDB_IPOD_GENERATION_NANO_5: return 5.0; + case ITDB_IPOD_GENERATION_NANO_6: + return 6.0; case ITDB_IPOD_GENERATION_VIDEO_1: return 5.0; case ITDB_IPOD_GENERATION_VIDEO_2: @@ -211,6 +215,8 @@ return 2.0; case ITDB_IPOD_GENERATION_TOUCH_3: return 3.0; + case ITDB_IPOD_GENERATION_TOUCH_4: + return 4.0; case ITDB_IPOD_GENERATION_IPHONE_1: return 1.0; case ITDB_IPOD_GENERATION_IPHONE_2: @@ -386,6 +392,7 @@ case ITDB_IPOD_GENERATION_NANO_4: case ITDB_IPOD_GENERATION_NANO_5: + case ITDB_IPOD_GENERATION_NANO_6: /* FIXME: set the correct icon name once it's added to * gnome-icon-theme-extras */ @@ -412,6 +419,7 @@ return g_strconcat (prefix, "ipod-touch", NULL); case ITDB_IPOD_GENERATION_TOUCH_2: case ITDB_IPOD_GENERATION_TOUCH_3: + case ITDB_IPOD_GENERATION_TOUCH_4: return g_strconcat (prefix, "ipod-touch-2g", NULL); case ITDB_IPOD_GENERATION_IPHONE_1: return g_strdup ("phone-apple-iphone");