# HG changeset patch
# User t_mrc-ct@sourceforge.jp
# Date 1333174407 -32400
# Branch GECKO10011_2012111513_RELBRANCH
# Node ID a5ba9fd4c237708d6f935e8bd74bee0f15c984b7
# Parent  35efee8e46e620ad854948916caba74d2e4cb2e2
import BadgeDockIcon hack for 10.4 from Thunderbird 3.6 repo

diff --git a/mailnews/base/src/nsMessengerOSXIntegration.h b/mailnews/base/src/nsMessengerOSXIntegration.h
--- a/mailnews/base/src/nsMessengerOSXIntegration.h
+++ b/mailnews/base/src/nsMessengerOSXIntegration.h
@@ -81,6 +81,7 @@
   void FillToolTipInfo(nsIMsgFolder *aFolder, PRInt32 aNewCount);
   nsresult GetFirstFolderWithNewMail(nsIMsgFolder* aFolder, nsCString& aFolderURI);
   nsresult BadgeDockIcon();
+  nsresult BadgeDockIconForTiger(nsAutoString& badgeString);
   nsresult RestoreDockIcon();
   nsresult BounceDockIcon();
   nsresult GetNewMailAuthors(nsIMsgFolder* aFolder, nsString& aAuthors, PRInt32 aNewCount, PRInt32* aNotDisplayed);
@@ -91,6 +92,7 @@
   PRInt32 mUnreadTotal;
   PRInt32 mNewTotal;
   bool mOnlyCountInboxes;
+  bool mOnLeopardOrLater;
   bool mDoneInitialCount;
 };
 
diff --git a/mailnews/base/src/nsMessengerOSXIntegration.mm b/mailnews/base/src/nsMessengerOSXIntegration.mm
--- a/mailnews/base/src/nsMessengerOSXIntegration.mm
+++ b/mailnews/base/src/nsMessengerOSXIntegration.mm
@@ -97,6 +97,36 @@
 
 static PRLogModuleInfo *MsgDockCountsLogModule = nsnull;
 
+// HACK: this code is copied from nsToolkit.mm in order to deal with
+// version checks below.  This should be tidied once we are not on
+// MOZILLA_1_9_2_BRANCH.
+// But This Hack is back again!
+#define MAC_OS_X_VERSION_10_4_HEX 0x00001040
+#define MAC_OS_X_VERSION_10_5_HEX 0x00001050
+int OSXVersion()
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+  static SInt32 gOSXVersion = 0x0;
+  if (gOSXVersion == 0x0)
+  {
+    if (::Gestalt(gestaltSystemVersion, &gOSXVersion) != noErr)
+    {
+      // This should probably be changed when our minimum version changes
+      NS_ERROR("Couldn't determine OS X version, assuming 10.4");
+      gOSXVersion = MAC_OS_X_VERSION_10_4_HEX;
+    }
+  }
+  return gOSXVersion;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
+}
+
+PRBool OnLeopardOrLater()
+{
+  return (OSXVersion() >= MAC_OS_X_VERSION_10_5_HEX);
+}
+
 // HACK: Limitations in Focus/SetFocus on Mac (see bug 465446)
 nsresult FocusAppNative()
 {
@@ -201,6 +231,7 @@
   mUnreadTotal = 0;
   mNewTotal = 0;
   mOnlyCountInboxes = PR_TRUE;
+  mOnLeopardOrLater = OnLeopardOrLater();
   mDoneInitialCount = PR_FALSE;
 }
 
@@ -577,9 +608,15 @@
 nsresult
 nsMessengerOSXIntegration::RestoreDockIcon()
 {
-  id tile = [[NSApplication sharedApplication] dockTile];
-  [tile setBadgeLabel: nil];
-
+  if (mOnLeopardOrLater)
+  {
+    id tile = [[NSApplication sharedApplication] dockTile];
+    [tile setBadgeLabel: nil];
+  }
+  else // 10.4
+  {
+    RestoreApplicationDockTileImage();
+  }
   return NS_OK;
 }
 
@@ -638,8 +675,138 @@
     return NS_OK;
   }
 
-  id tile = [[NSApplication sharedApplication] dockTile];
-  [tile setBadgeLabel:[NSString stringWithFormat:@"%S", total.get()]];
+  // On 10.5 or later, we can use the new API for this.
+  if (mOnLeopardOrLater)
+  {
+    id tile = [[NSApplication sharedApplication] dockTile];
+    [tile setBadgeLabel:[NSString stringWithFormat:@"%S", total.get()]];
+    return NS_OK;
+  }
+  else
+  {
+    return BadgeDockIconForTiger(badgeString);
+  }
+}
+
+nsresult
+nsMessengerOSXIntegration::BadgeDockIconForTiger(nsAutoString& badgeString)
+{
+  // On 10.4 we have to draw this manually, clearing any existing badge artifacts first.
+  RestoreDockIcon();
+  CGContextRef context = ::BeginCGContextForApplicationDockTile();
+
+  // Draw a circle.
+  ::CGContextBeginPath(context);
+  ::CGContextAddArc(context, 95.0, 95.0, 25.0, 0.0, 2 * M_PI, true);
+  ::CGContextClosePath(context);
+
+  // use #2fc600 for the color.
+  ::CGContextSetRGBFillColor(context, 0.184, 0.776, 0.0, 1);
+  ::CGContextFillPath(context);
+
+  // Use a system font (kThemeUtilityWindowTitleFont)
+  ScriptCode sysScript = ::GetScriptManagerVariable(smSysScript);
+
+  Str255 fontName;
+  SInt16 fontSize;
+  Style fontStyle;
+  ::GetThemeFont(kThemeSmallEmphasizedSystemFont, sysScript, fontName,
+                 &fontSize, &fontStyle);
+
+  FMFontFamily family = ::FMGetFontFamilyFromName(fontName);
+  FMFont fmFont;
+
+  if (::FMGetFontFromFontFamilyInstance(family,
+                                        fontStyle,
+                                        &fmFont,
+                                        nsnull) != noErr)
+  {
+    NS_WARNING("FMGetFontFromFontFamilyInstance failed");
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  ATSUStyle style;
+  if (::ATSUCreateStyle(&style) != noErr)
+  {
+    NS_WARNING("ATSUCreateStyle failed");
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  Fixed size = Long2Fix(24);
+  RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
+
+  ATSUAttributeTag tags[3] = { kATSUFontTag, kATSUSizeTag, kATSUColorTag };
+  ByteCount valueSizes[3] = { sizeof(ATSUFontID), sizeof(Fixed),
+                              sizeof(RGBColor) };
+  ATSUAttributeValuePtr values[3] = { &fmFont, &size, &white };
+
+  if (::ATSUSetAttributes(style, 3, tags, valueSizes, values) != noErr)
+  {
+    NS_WARNING("ATSUSetAttributes failed");
+    ::ATSUDisposeStyle(style);
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  UniCharCount runLengths = kATSUToTextEnd;
+  ATSUTextLayout textLayout;
+  if (::ATSUCreateTextLayoutWithTextPtr(badgeString.get(),
+                                        kATSUFromTextBeginning,
+                                        kATSUToTextEnd,
+                                        badgeString.Length(),
+                                        1,
+                                        &runLengths,
+                                        &style,
+                                        &textLayout) != noErr)
+  {
+    NS_WARNING("ATSUCreateTextLayoutWithTextPtr failed");
+    ::ATSUDisposeStyle(style);
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  ATSUAttributeTag layoutTags[1] = { kATSUCGContextTag };
+  ByteCount layoutValueSizes[1] = { sizeof(CGContextRef) };
+  ATSUAttributeValuePtr layoutValues[1] = { &context };
+
+  if (::ATSUSetLayoutControls(textLayout,
+                              1,
+                              layoutTags,
+                              layoutValueSizes,
+                              layoutValues) != noErr)
+  {
+    NS_WARNING("ATSUSetLayoutControls failed");
+    ::ATSUDisposeStyle(style);
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  Rect boundingBox;
+  if (::ATSUMeasureTextImage(textLayout,
+                             kATSUFromTextBeginning,
+                             kATSUToTextEnd,
+                             Long2Fix(0),
+                             Long2Fix(0),
+                             &boundingBox) != noErr)
+  {
+    NS_WARNING("ATSUMeasureTextImage failed");
+    ::ATSUDisposeStyle(style);
+    ::EndCGContextForApplicationDockTile(context);
+    return NS_ERROR_FAILURE;
+  }
+
+  // Center text inside circle
+  ::ATSUDrawText(textLayout, kATSUFromTextBeginning, kATSUToTextEnd,
+                 Long2Fix(95 - (boundingBox.right - boundingBox.left) / 2),
+                 Long2Fix(95 - (boundingBox.bottom - boundingBox.top) / 2));
+
+  ::ATSUDisposeStyle(style);
+  ::ATSUDisposeTextLayout(textLayout);
+
+  ::CGContextFlush(context);
+  ::EndCGContextForApplicationDockTile(context);
   return NS_OK;
 }
 
