# HG changeset patch
# User t_mrc-ct@users.sourceforge.jp
# Date 1403433223 -32400
# Branch GECKO3111_2014090813_RELBRANCH
# Node ID a166ddd340d75d3d0c9a942ad976c062b3ab4574
# Parent  c3020b3ec4ef40f7c90d229a7bad442d45df1a17
import BadgeDockIcon hack for 10.4 from Thunderbird 3.6 repo (with v31 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
@@ -46,17 +46,20 @@
   nsresult OnAlertClicked(const char16_t * aAlertCookie);
 #ifdef MOZ_SUITE
   nsresult OnAlertClickedSimple();
 #endif
   nsresult GetStringBundle(nsIStringBundle **aBundle);
   void FillToolTipInfo(nsIMsgFolder *aFolder, int32_t aNewCount);
   nsresult GetFirstFolderWithNewMail(nsIMsgFolder* aFolder, nsCString& aFolderURI);
   nsresult BadgeDockIcon();
+  nsresult BadgeDockIconForTiger(nsString& 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
@@ -56,16 +56,46 @@
 #define kBiffShowAlertPref "mail.biff.show_alert"
 #define kBiffAnimateDockIconPref "mail.biff.animate_dock_icon"
 #define kMaxDisplayCount 10
 #define kNewChatMessageTopic "new-directed-incoming-message"
 #define kUnreadImCountChangedTopic "unread-im-count-changed"
 
 using namespace mozilla::mailnews;
 
+// 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()
 {
   ProcessSerialNumber psn;
 
   if (::GetCurrentProcess(&psn) != 0)
    return NS_ERROR_FAILURE;
 
@@ -158,16 +188,17 @@
 }
 
 nsMessengerOSXIntegration::nsMessengerOSXIntegration()
 {
   mBiffStateAtom = MsgGetAtom("BiffState");
   mNewMailReceivedAtom = MsgGetAtom("NewMailReceived");
   mUnreadTotal = 0;
   mUnreadChat = 0;
+  mOnLeopardOrLater = OnLeopardOrLater();
 }
 
 nsMessengerOSXIntegration::~nsMessengerOSXIntegration()
 {
   RestoreDockIcon();
 }
 
 NS_IMPL_ADDREF(nsMessengerOSXIntegration)
@@ -502,18 +533,25 @@
   return NS_OK;
 }
 
 nsresult
 nsMessengerOSXIntegration::RestoreDockIcon()
 {
   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;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult
 nsMessengerOSXIntegration::BadgeDockIcon()
@@ -557,23 +595,153 @@
   nsAutoString badgeString;
   str->GetData(badgeString);
   if (badgeString.IsEmpty())
   {
     RestoreDockIcon();
     return NS_OK;
   }
 
-  id tile = [[NSApplication sharedApplication] dockTile];
-  [tile setBadgeLabel:[NSString stringWithFormat:@"%S", badgeString.get()]];
-  return NS_OK;
+  // 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", badgeString.get()]];
+    return NS_OK;
+  }
+  else
+  {
+    return BadgeDockIconForTiger(badgeString);
+  }
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
+nsresult
+nsMessengerOSXIntegration::BadgeDockIconForTiger(nsString& 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_IMETHODIMP
 nsMessengerOSXIntegration::OnItemPropertyFlagChanged(nsIMsgDBHdr *item, nsIAtom *property, uint32_t oldFlag, uint32_t newFlag)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMessengerOSXIntegration::OnItemAdded(nsIMsgFolder *, nsISupports *)
