1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/sys_info.h"
6
7#include <ApplicationServices/ApplicationServices.h>
8#include <CoreServices/CoreServices.h>
9#include <mach/mach_host.h>
10#include <mach/mach_init.h>
11
12#include "base/logging.h"
13
14namespace base {
15
16// static
17void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
18                                            int32* minor_version,
19                                            int32* bugfix_version) {
20  Gestalt(gestaltSystemVersionMajor,
21      reinterpret_cast<SInt32*>(major_version));
22  Gestalt(gestaltSystemVersionMinor,
23      reinterpret_cast<SInt32*>(minor_version));
24  Gestalt(gestaltSystemVersionBugFix,
25      reinterpret_cast<SInt32*>(bugfix_version));
26}
27
28// static
29int64 SysInfo::AmountOfPhysicalMemory() {
30  struct host_basic_info hostinfo;
31  mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
32  int result = host_info(mach_host_self(),
33                         HOST_BASIC_INFO,
34                         reinterpret_cast<host_info_t>(&hostinfo),
35                         &count);
36  DCHECK_EQ(HOST_BASIC_INFO_COUNT, count);
37  if (result != KERN_SUCCESS) {
38    NOTREACHED();
39    return 0;
40  }
41
42  return static_cast<int64>(hostinfo.max_mem);
43}
44
45// static
46void SysInfo::GetPrimaryDisplayDimensions(int* width, int* height) {
47  CGDirectDisplayID main_display = CGMainDisplayID();
48  if (width)
49    *width = CGDisplayPixelsWide(main_display);
50  if (height)
51    *height = CGDisplayPixelsHigh(main_display);
52}
53
54// static
55int SysInfo::DisplayCount() {
56  // Don't just return the number of online displays.  It includes displays
57  // that mirror other displays, which are not desired in the count.  It's
58  // tempting to use the count returned by CGGetActiveDisplayList, but active
59  // displays exclude sleeping displays, and those are desired in the count.
60
61  // It would be ridiculous to have this many displays connected, but
62  // CGDirectDisplayID is just an integer, so supporting up to this many
63  // doesn't hurt.
64  CGDirectDisplayID online_displays[128];
65  CGDisplayCount online_display_count = 0;
66  if (CGGetOnlineDisplayList(arraysize(online_displays),
67                             online_displays,
68                             &online_display_count) != kCGErrorSuccess) {
69    // 1 is a reasonable assumption.
70    return 1;
71  }
72
73  int display_count = 0;
74  for (CGDisplayCount online_display_index = 0;
75       online_display_index < online_display_count;
76       ++online_display_index) {
77    CGDirectDisplayID online_display = online_displays[online_display_index];
78    if (CGDisplayMirrorsDisplay(online_display) == kCGNullDirectDisplay) {
79      // If this display doesn't mirror any other, include it in the count.
80      // The primary display in a mirrored set will be counted, but those that
81      // mirror it will not be.
82      ++display_count;
83    }
84  }
85
86  return display_count;
87}
88
89}  // namespace base
90