# HG changeset patch
# User t_mrc-ct@sourceforge.jp
# Date 1350735831 -32400
# Branch GECKO1704esr_2013030721_RELBRANCH
# Node ID 14ce9a68788453b46130248c6174d76a98b6af7e
# Parent  5decb4b57b944334e48309a7e0af01e34a8e23c3
import BadgeDockIcon hack for 10.4 from Thunderbird 3.6 repo (with v17 fix)

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
@@ -48,12 +48,15 @@
   void FillToolTipInfo(nsIMsgFolder *aFolder, int32_t aNewCount);
   nsresult GetFirstFolderWithNewMail(nsIMsgFolder* aFolder, nsCString& aFolderURI);
   nsresult BadgeDockIcon();
+  nsresult BadgeDockIconForTiger(nsAutoString& badgeString);
   nsresult RestoreDockIcon();
   nsresult BounceDockIcon();
   nsresult GetNewMailAuthors(nsIMsgFolder* aFolder, nsString& aAuthors, int32_t aNewCount, int32_t* aNotDisplayed);
 
   int32_t mUnreadTotal;
   int32_t mUnreadChat;
+
+  bool mOnLeopardOrLater;
 };
 
 #endif // __nsMessengerOSXIntegration_h
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
@@ -66,6 +66,36 @@
 
 static PRLogModuleInfo *MsgDockCountsLogModule = nullptr;
 
+// 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()
 {
@@ -168,6 +198,7 @@
   mNewMailReceivedAtom = MsgGetAtom("NewMailReceived");
   mUnreadTotal = 0;
   mUnreadChat = 0;
+  mOnLeopardOrLater = OnLeopardOrLater();
 }
 
 nsMessengerOSXIntegration::~nsMessengerOSXIntegration()
@@ -527,8 +558,15 @@
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
-  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;
 
@@ -582,8 +620,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;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
