public static function network_device_string()
 {
     $network = array();
     if (phodevi::is_macosx()) {
         // TODO: implement
     } else {
         if (phodevi::is_bsd()) {
             foreach (array('dev.em.0.%desc', 'dev.wpi.0.%desc', 'dev.mskc.0.%desc') as $controller) {
                 $pci = phodevi_bsd_parser::read_sysctl($controller);
                 if (!empty($pci)) {
                     array_push($network, $pci);
                 }
             }
         } else {
             if (phodevi::is_windows()) {
                 // TODO: implement
             } else {
                 if (phodevi::is_linux()) {
                     foreach (array('Ethernet controller', 'Network controller') as $controller) {
                         $pci = phodevi_linux_parser::read_pci($controller);
                         if (!empty($pci)) {
                             array_push($network, $pci);
                         }
                     }
                 }
             }
         }
     }
     return implode(' + ', $network);
 }
 public static function __pre_run_process()
 {
     self::$error_count = 0;
     self::$error_pointer = 0;
     self::$error_analysis = array();
     // Store the video resolution
     // Access the xrandr resolution directly to ensure it's not polling the FB size or one of the KMS modes
     self::$start_video_resolution = phodevi_gpu::gpu_xrandr_resolution();
     if (phodevi::is_linux() && phodevi::is_ati_graphics()) {
         $vsync_val = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/BUSID-*/OpenGL,VSyncControl');
         // Check for vSync
         if ($vsync_val == '0x00000002' || $vsync_val == '0x00000003') {
             self::$driver_forced_vsync = true;
         }
         //$catalyst_ai_val = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/BUSID-*/OpenGL,CatalystAI'); // Check for Catalyst AI
         //if($catalyst_ai_val == '0x00000001' || $catalyst_ai_val == '0x00000002')
         //	echo '\nCatalyst AI is enabled, which will use driver-specific optimizations in some tests that may offer extra performance enhancements.\n';
     } else {
         if (phodevi::is_nvidia_graphics()) {
             self::$error_pointer = self::nvidia_gpu_error_count();
             // Set the error pointer
             if (phodevi_parser::read_nvidia_extension('SyncToVBlank') == '1') {
                 shell_exec('nvidia-settings -a SyncToVBlank=0 2>&1');
                 self::$driver_forced_vsync = true;
             }
         }
     }
     if (self::$driver_forced_vsync == true) {
         //	echo '\nYour video driver is forcing vertical sync to be enabled. This will limit the system's frame-rate performance potential in any graphical tests!\n';
     }
     // vblank_mode=0 has long been set within pts-core, but put it here too just since there's these other checks here
     putenv('vblank_mode=0');
 }
 public static function read_sensor()
 {
     if (phodevi::is_linux()) {
         $sensor = phodevi_linux_parser::read_sensors(array('V5', '+5V'));
     } else {
         $sensor = -1;
     }
     return $sensor;
 }
 private function hdd_write_speed_linux()
 {
     if ($this->disk_to_monitor == NULL) {
         return -1;
     }
     $stat_path = '/sys/class/block/' . $this->disk_to_monitor . '/stat';
     $speed = phodevi_linux_parser::read_sys_disk_speed($stat_path, 'WRITE');
     return $speed;
 }
 public static function read_sensor()
 {
     if (phodevi::is_linux()) {
         $sensor = phodevi_linux_parser::read_sensors('VCore');
     } else {
         $sensor = -1;
     }
     return $sensor;
 }
 private function cpu_fanspeed_linux()
 {
     $fan_speed = -1;
     $raw_fan = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/fan1_input', 'POSITIVE_NUMERIC');
     if ($raw_fan == -1) {
         $raw_fan = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/fan1_input', 'POSITIVE_NUMERIC');
     }
     if ($raw_fan != -1) {
         $fan_speed = $raw_fan;
     }
     return $fan_speed;
 }
 public static function read_sensor()
 {
     // Reads the system's temperature
     $temp_c = -1;
     if (phodevi::is_linux()) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
         }
         if ($raw_temp != -1) {
             if ($raw_temp > 1000) {
                 $raw_temp = $raw_temp / 1000;
             }
             $temp_c = pts_math::set_precision($raw_temp, 2);
         }
         if ($temp_c == -1) {
             $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
             if (($end = strpos($acpi, ' ')) > 0) {
                 $temp_c = substr($acpi, 0, $end);
             }
         }
         if ($temp_c == -1) {
             $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
             if ($sensors != false && is_numeric($sensors)) {
                 $temp_c = $sensors;
             }
         }
         if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
             $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
             if ($temp_c > 1000) {
                 $temp_c = pts_math::set_precision($temp_c / 1000, 1);
             }
         }
     } else {
         if (phodevi::is_bsd()) {
             $acpi = phodevi_bsd_parser::read_sysctl(array('hw.sensors.acpi_tz1.temp0', 'hw.acpi.thermal.tz1.temperature'));
             if (($end = strpos($acpi, ' degC')) > 0 || ($end = strpos($acpi, 'C')) > 0) {
                 $acpi = substr($acpi, 0, $end);
                 if (is_numeric($acpi)) {
                     $temp_c = $acpi;
                 }
             }
         }
     }
     return $temp_c;
 }
 public static function read_sensor()
 {
     $fan_speed = -1;
     if (phodevi::is_linux()) {
         $raw_fan = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/fan1_input', 'POSITIVE_NUMERIC');
         if ($raw_fan == -1) {
             $raw_fan = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/fan1_input', 'POSITIVE_NUMERIC');
         }
         if ($raw_fan != -1) {
             $fan_speed = $raw_fan;
         }
     }
     return $fan_speed;
 }
 public function read_sensor()
 {
     $sensor = -1;
     if (phodevi::is_linux()) {
         if ($this->voltage_to_monitor == '12v') {
             $sensor = phodevi_linux_parser::read_sensors(array('V12', '+12V'));
         } elseif ($this->voltage_to_monitor == '5v') {
             $sensor = phodevi_linux_parser::read_sensors(array('V5', '+5V'));
         } elseif ($this->voltage_to_monitor == '3v') {
             $sensor = phodevi_linux_parser::read_sensors(array('V3.3', '+3.3V'));
         }
     }
     return $sensor;
 }
 private function cpu_power_linux()
 {
     $cpu_watts = -1;
     // Try hwmon interface for AMD 15h (Bulldozer FX CPUs) where this support was introduced for AMD CPUs and exposed by the fam15h_power hwmon driver
     // The fam15h_power driver doesn't expose the power consumption on a per-core/per-package basis but only an average
     $hwmon_watts = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/power1_input', 'POSITIVE_NUMERIC', array('name' => 'fam15h_power'));
     if ($hwmon_watts != -1) {
         if ($hwmon_watts > 1000000) {
             // convert to Watts
             $hwmon_watts = $hwmon_watts / 1000000;
         }
         $cpu_watts = pts_math::set_precision($hwmon_watts, 2);
     }
     return $cpu_watts;
 }
 public function read_sensor()
 {
     // Report graphics processor fan speed as a percent
     $fan_speed = -1;
     if (phodevi::is_nvidia_graphics()) {
         // NVIDIA fan speed reading support in NVIDIA 190.xx and newer
         // TODO: support for multiple fans, also for reading GPUFanTarget to get appropriate fan
         // nvidia-settings --describe GPUFanTarget
         $fan_speed = phodevi_parser::read_nvidia_extension('[fan:0]/GPUCurrentFanSpeed');
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $fan_speed = phodevi_linux_parser::read_ati_overdrive('FanSpeed');
         }
     }
     return $fan_speed;
 }
 public static function audio_processor_string()
 {
     $audio = null;
     if (phodevi::is_macosx()) {
         // TODO: implement
     } else {
         if (phodevi::is_bsd()) {
             foreach (array('dev.hdac.0.%desc') as $dev) {
                 $dev = phodevi_bsd_parser::read_sysctl($dev);
                 if (!empty($dev)) {
                     $audio = $dev;
                 }
             }
         } else {
             if (phodevi::is_windows()) {
                 // TODO: implement
             } else {
                 if (phodevi::is_linux()) {
                     foreach (pts_file_io::glob('/sys/class/sound/card*/hwC0D*/vendor_name') as $vendor_name) {
                         $card_dir = dirname($vendor_name) . '/';
                         if (!is_readable($card_dir . 'chip_name')) {
                             continue;
                         }
                         $vendor_name = pts_file_io::file_get_contents($vendor_name);
                         $chip_name = pts_file_io::file_get_contents($card_dir . 'chip_name');
                         $audio = $vendor_name . ' ' . $chip_name;
                         if (strpos($chip_name, 'HDMI') !== false || strpos($chip_name, 'DP') !== false) {
                             // If HDMI is in the audio string, likely the GPU-provided audio, so try to find the mainboard otherwise
                             $audio = null;
                         } else {
                             break;
                         }
                     }
                     if ($audio == null) {
                         $audio = phodevi_linux_parser::read_pci('Multimedia audio controller');
                     }
                     if ($audio == null) {
                         $audio = phodevi_linux_parser::read_pci('Audio device');
                     }
                 }
             }
         }
     }
     return $audio;
 }
 public static function read_sensor()
 {
     // speed in MB/s
     $speed = -1;
     if (phodevi::is_linux()) {
         static $sys_disk = null;
         if ($sys_disk == null) {
             foreach (pts_file_io::glob('/sys/class/block/sd*/stat') as $check_disk) {
                 if (pts_file_io::file_get_contents($check_disk) != null) {
                     $sys_disk = $check_disk;
                     break;
                 }
             }
         }
         $speed = phodevi_linux_parser::read_sys_disk_speed($sys_disk, 'READ');
     }
     return $speed;
 }
 public static function read_sensor()
 {
     // Determine the current processor frequency
     $cpu_core = 0;
     // TODO: for now just monitoring the first core
     $info = 0;
     if (phodevi::is_linux()) {
         // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
         if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq')) {
             $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq');
             $info = intval($info) / 1000;
         } else {
             if (is_file('/proc/cpuinfo')) {
                 $cpu_speeds = phodevi_linux_parser::read_cpuinfo('cpu MHz');
                 if (isset($cpu_speeds[0])) {
                     $cpu_core = isset($cpu_speeds[$cpu_core]) ? $cpu_core : 0;
                     $info = intval($cpu_speeds[$cpu_core]);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $info = shell_exec('psrinfo -v | grep MHz');
             $info = substr($info, strrpos($info, 'at') + 3);
             $info = trim(substr($info, 0, strpos($info, 'MHz')));
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('dev.cpu.0.freq');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorSpeed');
                     if (($cut_point = strpos($info, ' ')) > 0) {
                         $info = substr($info, 0, $cut_point);
                         $info = str_replace(',', '.', $info);
                     }
                     if ($info < 100) {
                         $info *= 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
 public static function read_sensor()
 {
     // Report graphics processor temperature
     $temp_c = -1;
     if (phodevi::is_nvidia_graphics()) {
         $temp_c = phodevi_parser::read_nvidia_extension('GPUCoreTemp');
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $temp_c = phodevi_linux_parser::read_ati_overdrive('Temperature');
         } else {
             foreach (array_merge(array('/sys/class/drm/card0/device/temp1_input'), pts_file_io::glob('/sys/class/drm/card0/device/hwmon/hwmon*/temp1_input')) as $temp_input) {
                 // This works for at least Nouveau driver with Linux 2.6.37 era DRM
                 if (is_readable($temp_input) == false) {
                     continue;
                 }
                 $temp_input = pts_file_io::file_get_contents($temp_input);
                 if (is_numeric($temp_input)) {
                     if ($temp_input > 1000) {
                         $temp_input /= 1000;
                     }
                     $temp_c = $temp_input;
                     break;
                 }
             }
             if ($temp_c == -1 && is_readable('/sys/kernel/debug/dri/0/i915_emon_status')) {
                 // Intel thermal
                 $i915_emon_status = file_get_contents('/sys/kernel/debug/dri/0/i915_emon_status');
                 $temp = strpos($i915_emon_status, 'GMCH temp: ');
                 if ($temp !== false) {
                     $temp = substr($i915_emon_status, $temp + 11);
                     $temp = substr($temp, 0, strpos($temp, PHP_EOL));
                     if (is_numeric($temp) && $temp > 0) {
                         $temp_c = $temp;
                     }
                 }
             }
         }
     }
     if ($temp_c > 1000 || $temp_c < 9) {
         // Invalid data
         return -1;
     }
     return $temp_c;
 }
 private function sys_temp_linux()
 {
     $temp_c = -1;
     $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
     }
     if ($raw_temp != -1) {
         if ($raw_temp > 1000) {
             $raw_temp = $raw_temp / 1000;
         }
         $temp_c = pts_math::set_precision($raw_temp, 2);
     }
     if ($temp_c == -1) {
         $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
         if (($end = strpos($acpi, ' ')) > 0) {
             $temp_c = substr($acpi, 0, $end);
         }
     }
     if ($temp_c == -1) {
         $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
         if ($sensors != false && is_numeric($sensors)) {
             $temp_c = $sensors;
         }
     }
     if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
         $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
         if ($temp_c > 1000) {
             $temp_c = pts_math::set_precision($temp_c / 1000, 1);
         }
     }
     return $temp_c;
 }
 private function cpu_freq_linux()
 {
     $frequency = -1;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current frequency.
     if (is_file('/sys/devices/system/cpu/' . $this->cpu_to_monitor . '/cpufreq/scaling_cur_freq')) {
         $frequency = pts_file_io::file_get_contents('/sys/devices/system/cpu/' . $this->cpu_to_monitor . '/cpufreq/scaling_cur_freq');
         $frequency = intval($frequency) / 1000;
     } else {
         if (is_file('/proc/cpuinfo')) {
             $cpu_speeds = phodevi_linux_parser::read_cpuinfo('cpu MHz');
             $cpu_number = intval(substr($this->cpu_to_monitor, 3));
             //cut 'cpu' from the beginning
             if (!isset($cpu_speeds[$cpu_number])) {
                 return -1;
             }
             $frequency = intval($cpu_speeds[$cpu_number]);
         }
     }
     return $frequency;
 }
 public static function cpu_model()
 {
     // Returns the processor name / frequency information
     $info = null;
     if (isset(phodevi::$vfs->cpuinfo)) {
         $physical_cpu_ids = phodevi_linux_parser::read_cpuinfo('physical id');
         $physical_cpu_count = count(array_unique($physical_cpu_ids));
         $cpu_strings = phodevi_linux_parser::read_cpuinfo(array('model name', 'Processor', 'cpu', 'cpu model'));
         $cpu_strings_unique = array_unique($cpu_strings);
         if ($physical_cpu_count == 1 || empty($physical_cpu_count)) {
             // Just one processor
             if (isset($cpu_strings[0]) && ($cut = strpos($cpu_strings[0], ' (')) !== false) {
                 $cpu_strings[0] = substr($cpu_strings[0], 0, $cut);
             }
             $info = isset($cpu_strings[0]) ? $cpu_strings[0] : null;
             if (strpos($info, 'ARM') !== false) {
                 if (is_dir('/sys/devices/system/exynos-core/') && stripos($info, 'Exynos') === false) {
                     $info = 'Exynos ' . $info;
                 }
             }
         } else {
             if ($physical_cpu_count > 1 && count($cpu_strings_unique) == 1) {
                 // Multiple processors, same model
                 $info = $physical_cpu_count . ' x ' . $cpu_strings[0];
             } else {
                 if ($physical_cpu_count > 1 && count($cpu_strings_unique) > 1) {
                     // Multiple processors, different models
                     $current_id = -1;
                     $current_string = $cpu_strings[0];
                     $current_count = 0;
                     $cpus = array();
                     for ($i = 0; $i < count($physical_cpu_ids); $i++) {
                         if ($current_string != $cpu_strings[$i] || $i == count($physical_cpu_ids) - 1) {
                             array_push($cpus, $current_count . ' x ' . $current_string);
                             $current_string = $cpu_strings[$i];
                             $current_count = 0;
                         }
                         if ($physical_cpu_ids[$i] != $current_id) {
                             $current_count++;
                             $current_id = $physical_cpu_ids[$i];
                         }
                     }
                     $info = implode(', ', $cpus);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('CPUType', '-C');
             if (count($dmi_cpu) == 0) {
                 $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorName');
             }
             if (count($dmi_cpu) > 0) {
                 $info = $dmi_cpu[0];
             } else {
                 $info = trim(shell_exec('dmesg 2>&1 | grep cpu0'));
                 $info = trim(substr($info, strrpos($info, 'cpu0:') + 6));
                 if (empty($info)) {
                     $info = array_pop(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorManufacturer'));
                 }
             }
             //TODO: Add in proper support for reading multiple CPUs, similar to the code from above
             $physical_cpu_count = count(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorSocketType'));
             if ($physical_cpu_count > 1 && !empty($info)) {
                 // TODO: For now assuming when multiple CPUs are installed, that they are of the same type
                 $info = $physical_cpu_count . ' x ' . $info;
             }
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('hw.model');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorName');
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Name');
                         if (!$info) {
                             $info = getenv('PROCESSOR_IDENTIFIER');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info)) {
         $info = 'Unknown';
     } else {
         if (($strip_point = strpos($info, '@')) > 0) {
             $info = trim(substr($info, 0, $strip_point));
             // stripping out the reported freq, since the CPU could be overclocked, etc
         }
         $info = pts_strings::strip_string($info);
         // It seems Intel doesn't report its name when reporting Pentium hardware
         if (strpos($info, 'Pentium') !== false && strpos($info, 'Intel') === false) {
             $info = 'Intel ' . $info;
         }
         if (substr($info, 0, 5) == 'Intel') {
             $cpu_words = explode(' ', $info);
             $cpu_words_count = count($cpu_words);
             // Convert strings like 'Intel Core i7 M 620' -> 'Intel Core i7 620M' and 'Intel Core i7 X 990' -> 'Intel Core i7 990X' to better reflect Intel product marketing names
             if ($cpu_words_count > 4 && is_numeric($cpu_words[$cpu_words_count - 1]) && strlen($cpu_words[$cpu_words_count - 2]) == 1 && strlen($cpu_words[$cpu_words_count - 3]) == 2) {
                 $cpu_words[$cpu_words_count - 1] .= $cpu_words[$cpu_words_count - 2];
                 unset($cpu_words[$cpu_words_count - 2]);
                 $info = implode(' ', $cpu_words);
             }
         }
     }
     return $info;
 }
 public static function read_lsb_distributor_id()
 {
     $vendor = phodevi_linux_parser::read_lsb('Distributor ID');
     // Quirks for derivative distributions that don't know how to handle themselves properly
     if ($vendor == 'MandrivaLinux' && phodevi_linux_parser::read_lsb('Description') == 'PCLinuxOS') {
         // PC Linux OS only stores its info in /etc/pclinuxos-release
         $vendor = false;
     }
     return $vendor;
 }
 public static function ati_overdrive_core_usage()
 {
     return phodevi_linux_parser::read_ati_overdrive('GPUload');
 }
 public static function chipset_string()
 {
     $info = false;
     if (phodevi::is_macosx()) {
         $sb_vendor = phodevi_osx_parser::read_osx_system_profiler('SPSerialATADataType', 'Vendor');
         $sb_product = phodevi_osx_parser::read_osx_system_profiler('SPSerialATADataType', 'Product');
         if ($sb_product == 'SSD') {
             $sb_product = null;
         }
         if (($cut_point = strpos($sb_product, ' ')) > 0) {
             $sb_product = substr($sb_product, 0, $cut_point);
         }
         // TODO: Can't find Northbridge
         $info = $sb_vendor . ' ' . $sb_product;
     } else {
         if (phodevi::is_windows()) {
             $info = phodevi_windows_parser::read_cpuz('Northbridge', null);
             if ($info != null) {
                 if (($e = strpos($info, 'rev')) !== false) {
                     $info = substr($info, 0, $e);
                 }
                 $info = trim($info);
             }
         } else {
             if (phodevi::is_solaris()) {
                 // Vendor Detection
                 $vendor_possible_udis = array('/org/freedesktop/Hal/devices/pci_0_0/pci_ide_3_2_0', '/org/freedesktop/Hal/devices/pci_0_0/pci_ide_1f_1_1');
                 $info = phodevi_solaris_parser::read_hal_property($vendor_possible_udis, 'info.vendor');
                 // TODO: Northbridge and Southbridge Detection For Solaris
             } else {
                 if (phodevi::is_linux() || phodevi::is_hurd()) {
                     $info = phodevi_linux_parser::read_pci(array('RAM memory', 'Host bridge'));
                     if (count(explode(' ', $info)) == 1) {
                         $bridge = phodevi_linux_parser::read_pci(array('Bridge', 'PCI bridge'));
                         if (!empty($bridge)) {
                             $match = false;
                             $break_words = array('Ethernet', 'PCI', 'High', 'USB');
                             for ($i = 0; $i < count($break_words) && !$match; $i++) {
                                 if (($pos = strpos($bridge, $break_words[$i])) > 0) {
                                     $bridge = trim(substr($bridge, 0, $pos));
                                     $info = $bridge;
                                     $match = true;
                                 }
                             }
                         }
                     }
                     if (!isset($bridge) || !empty($bridge)) {
                         // Attempt to detect Southbridge (if applicable)
                         $southbridge = phodevi_linux_parser::read_pci(array('ISA bridge', 'SATA controller'), false);
                         $southbridge_clean = null;
                         if (($start_cut = strpos($southbridge, '(')) > 0 && ($end_cut = strpos($southbridge, ')', $start_cut + 1)) > 0) {
                             $southbridge_extract = substr($southbridge, $start_cut + 1, $end_cut - $start_cut - 1);
                             if (strpos($southbridge_extract, 'rev') === false) {
                                 $southbridge_extract = explode(' ', $southbridge_extract);
                                 $southbridge_clean = $southbridge_extract[0];
                             } else {
                                 if (($s = strpos($southbridge, 'ICH')) > 0) {
                                     $southbridge_extract = substr($southbridge, $s);
                                     $southbridge_clean = substr($southbridge_extract, 0, strpos($southbridge_extract, ' '));
                                 }
                             }
                         } else {
                             if (($start_cut = strpos($southbridge, 'SB')) !== false) {
                                 $southbridge_extract = substr($southbridge, $start_cut);
                                 $southbridge_clean = substr($southbridge_extract, 0, strpos($southbridge_extract, ' '));
                             }
                         }
                         if (!empty($southbridge_clean) && $southbridge_clean != 'SB') {
                             $info .= ' + ' . $southbridge_clean;
                         }
                     }
                 }
             }
         }
     }
     return $info;
 }
 public static function memory_string()
 {
     $mem_string = null;
     $mem_prefix = null;
     $mem_size = false;
     $mem_speed = false;
     $mem_type = false;
     $mem_manufacturer = false;
     $mem_part = false;
     if (phodevi::is_macosx()) {
         $mem_size = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Size', true, array('Empty'));
         $mem_speed = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Speed');
         $mem_type = phodevi_osx_parser::read_osx_system_profiler('SPMemoryDataType', 'Type');
     } else {
         if (phodevi::is_solaris()) {
             $mem_size = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,InstalledSize');
             $mem_speed = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,Speed');
             $mem_type = phodevi_solaris_parser::read_sun_ddu_dmi_info('MemoryDevice*,MemoryDeviceType');
             if (is_array($mem_speed) && count($mem_speed) > 0) {
                 $mem_speed = array_shift($mem_speed);
             }
             $mem_speed = str_replace('MHZ', 'MHz', $mem_speed);
         } else {
             if (phodevi::is_windows()) {
                 $mem_size = phodevi_windows_parser::read_cpuz('DIMM #', 'Size', true);
                 foreach ($mem_size as $key => &$individual_size) {
                     $individual_size = pts_arrays::first_element(explode(' ', $individual_size));
                     if (!is_numeric($individual_size)) {
                         unset($mem_size[$key]);
                     }
                 }
                 $mem_type = phodevi_windows_parser::read_cpuz('Memory Type', null);
                 $mem_speed = intval(phodevi_windows_parser::read_cpuz('Memory Frequency', null)) . 'MHz';
             } else {
                 if (phodevi::is_linux()) {
                     $mem_size = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Size', false, array('Not Installed', 'No Module Installed', 'Undefined'));
                     $mem_speed = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Speed', true, array('Unknown', 'Undefined'));
                     $mem_type = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Type', true, array('Unknown', 'Other', 'Flash', 'Undefined'));
                     $mem_manufacturer = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Manufacturer', true, array('Unknown', 'Undefined'));
                     $mem_part = phodevi_linux_parser::read_dmidecode('memory', 'Memory Device', 'Part Number', true, array('Unknown', 'Undefined'));
                 }
             }
         }
     }
     if (is_array($mem_type)) {
         $mem_type = array_pop($mem_type);
     }
     if ($mem_size != false && (!is_array($mem_size) || count($mem_size) != 0)) {
         for ($i = 0; $i < count($mem_size); $i++) {
             switch (substr($mem_size[$i], -1)) {
                 case 'K':
                     // looks like sometimes Solaris now reports flash chip as memory. its string ends with K
                     unset($mem_size[$i]);
                     unset($mem_speed[$i]);
                     unset($mem_type[$i]);
                     break;
                 case 'M':
                     // report megabytes as MB, just not M, as on Solaris
                     $mem_size[$i] .= 'B';
                     break;
                 case 'B':
                     if (strtolower(substr($mem_size[$i], -2, 1)) == 'k') {
                         // some hardware on Linux via dmidecode reports flash chips
                         unset($mem_size[$i]);
                         //unset($mem_speed[$i]);
                         //unset($mem_type[$i]);
                     }
                     break;
             }
         }
         foreach ($mem_size as $i => $mem_stick) {
             if (!is_numeric(substr($mem_stick, 0, 3)) && stripos($mem_stick, 'GB') == false) {
                 // If the memory size isn't at least three digits (basically 128MB+), chances are something is wrong, i.e. reporting flash chip from dmidecode, so get rid of it.
                 unset($mem_size[$i]);
             }
         }
         $mem_count = count($mem_size);
         if (!empty($mem_type)) {
             if (($cut = strpos($mem_type, ' ')) > 0) {
                 $mem_type = substr($mem_type, 0, $cut);
             }
             if (!in_array($mem_type, array('Other')) && (pts_strings::keep_in_string($mem_type, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_LETTER) == $mem_type || phodevi::is_windows())) {
                 $mem_prefix = $mem_type;
             }
         } else {
             $mem_prefix = null;
         }
         if (!empty($mem_speed)) {
             if (($cut = strpos($mem_speed, ' (')) > 0) {
                 $mem_speed = substr($mem_speed, 0, $cut);
             }
             if (!empty($mem_prefix)) {
                 $mem_prefix .= '-';
             }
             $mem_prefix .= str_replace(' ', null, $mem_speed);
         }
         // TODO: Allow a combination of both functions below, so like 2 x 2GB + 3 x 1GB DDR2-800
         if ($mem_count > 1 && count(array_unique($mem_size)) > 1) {
             $mem_string = implode(' + ', $mem_size) . ' ' . $mem_prefix;
         } else {
             if ($mem_count * $mem_size[0] != phodevi::read_property('memory', 'capacity') && phodevi::read_property('memory', 'capacity') % $mem_size[0] == 0) {
                 // This makes sure the correct number of RAM modules is reported...
                 // On at least Linux with dmidecode on an AMD Opteron multi-socket setup it's only showing the data for one socket
                 if ($mem_size[0] < 1024) {
                     $mem_size[0] *= 1024;
                 }
                 $mem_count = phodevi::read_property('memory', 'capacity') / $mem_size[0];
             }
             $product_string = null;
             if (isset($mem_manufacturer[2]) && ctype_alpha($mem_manufacturer[0]) && stripos($mem_manufacturer, 'manufacturer') === false && stripos($mem_manufacturer, 'part') === false && stripos($mem_manufacturer, 'module') === false && stripos($mem_manufacturer, 'dimm') === false && isset($mem_manufacturer[2]) && ctype_alpha($mem_manufacturer)) {
                 $product_string .= ' ' . $mem_manufacturer;
             }
             if (isset($mem_part[2]) && stripos($mem_part, 'part') === false && stripos($mem_part, 'module') === false && stripos($mem_part, 'dimm') === false && substr($mem_part, 0, 2) != '0x' && !isset($mem_part[24]) && ctype_alnum($mem_part)) {
                 $product_string .= ' ' . $mem_part;
             }
             if (is_numeric($mem_size[0]) && stripos($mem_size[0], 'b') === false) {
                 if ($mem_size >= 1024) {
                     $mem_size[0] .= ' MB';
                 } else {
                     $mem_size[0] .= ' GB';
                 }
             }
             $mem_string = $mem_count . ' x ' . $mem_size[0] . ' ' . $mem_prefix . $product_string;
         }
     }
     if (empty($mem_string)) {
         $mem_string = phodevi::read_property('memory', 'capacity');
         if ($mem_string != null) {
             $mem_string .= 'MB';
         }
     }
     return trim($mem_string);
 }
Example #23
0
 private function cpu_temp_linux()
 {
     $temp_c = -1;
     // Try hwmon interface
     $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp2_input', 'POSITIVE_NUMERIC', array('name' => 'coretemp'));
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => 'k10temp'));
     }
     if ($raw_temp == -1) {
         // Try ACPI thermal
         // Assuming the system thermal sensor comes 2nd to the ACPI CPU temperature
         // It appears that way on a ThinkPad T60, but TODO find a better way to validate
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/thermal/thermal_zone*/temp', 'POSITIVE_NUMERIC', null, 2);
     }
     if ($raw_temp != -1) {
         if ($raw_temp > 1000) {
             $raw_temp = $raw_temp / 1000;
         }
         $temp_c = pts_math::set_precision($raw_temp, 2);
     }
     if ($temp_c == -1) {
         // Try LM_Sensors
         $sensors = phodevi_linux_parser::read_sensors(array('CPU Temp', 'Core 0', 'Core0 Temp', 'Core1 Temp'));
         if ($sensors != false && is_numeric($sensors) && $sensors > 0) {
             $temp_c = $sensors;
         }
     }
     if (pts_client::executable_in_path('ipmitool')) {
         $ipmi = phodevi_linux_parser::read_ipmitool_sensor('Temp 0');
         if ($ipmi > 0 && is_numeric($ipmi)) {
             $temp_c = $ipmi;
         }
     }
     return $temp_c;
 }
 public function read_sensor()
 {
     // Graphics processor real/current frequency
     $show_memory = false;
     $core_freq = 0;
     $mem_freq = 0;
     if (phodevi::is_nvidia_graphics()) {
         $nv_freq = phodevi_parser::read_nvidia_extension('GPUCurrentClockFreqs');
         $nv_freq = pts_strings::comma_explode($nv_freq);
         $core_freq = isset($nv_freq[0]) ? $nv_freq[0] : 0;
         $mem_freq = isset($nv_freq[1]) ? $nv_freq[1] : 0;
     } else {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $od_clocks = phodevi_linux_parser::read_ati_overdrive('CurrentClocks');
             if (is_array($od_clocks) && count($od_clocks) >= 2) {
                 $core_freq = array_shift($od_clocks);
                 $mem_freq = array_pop($od_clocks);
             }
         } else {
             if (phodevi::is_linux()) {
                 if (isset(phodevi::$vfs->radeon_pm_info)) {
                     // radeon_pm_info should be present with Linux 2.6.34+
                     foreach (pts_strings::trim_explode("\n", phodevi::$vfs->radeon_pm_info) as $pm_line) {
                         $pm_line = pts_strings::colon_explode($pm_line);
                         if (isset($pm_line[1])) {
                             list($descriptor, $value) = $pm_line;
                         } else {
                             continue;
                         }
                         switch ($descriptor) {
                             case 'current engine clock':
                                 $core_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                             case 'current memory clock':
                                 $mem_freq = pts_arrays::first_element(explode(' ', $value)) / 1000;
                                 break;
                         }
                     }
                     if ($core_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'sclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('sclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $core_freq = $x;
                         }
                     }
                     if ($mem_freq == null && ($x = strpos(phodevi::$vfs->radeon_pm_info, 'mclk: '))) {
                         $x = substr(phodevi::$vfs->radeon_pm_info, $x + strlen('mclk: '));
                         $x = substr($x, 0, strpos($x, ' '));
                         if (is_numeric($x)) {
                             if ($x > 1000) {
                                 $x = $x / 100;
                             }
                             $mem_freq = $x;
                         }
                     }
                 } else {
                     if (is_file('/sys/class/drm/card0/gt_cur_freq_mhz')) {
                         $gt_cur_freq_mhz = pts_file_io::file_get_contents('/sys/class/drm/card0/gt_cur_freq_mhz');
                         if ($gt_cur_freq_mhz > 2) {
                             $core_freq = $gt_cur_freq_mhz;
                         }
                     } else {
                         if (is_file('/sys/class/drm/card0/device/performance_level')) {
                             $performance_level = pts_file_io::file_get_contents('/sys/class/drm/card0/device/performance_level');
                             $performance_level = explode(' ', $performance_level);
                             $core_string = array_search('core', $performance_level);
                             if ($core_string !== false && isset($performance_level[$core_string + 1])) {
                                 $core_string = str_ireplace('MHz', null, $performance_level[$core_string + 1]);
                                 if (is_numeric($core_string) && $core_string > $core_freq) {
                                     $core_freq = $core_string;
                                 }
                             }
                             $mem_string = array_search('memory', $performance_level);
                             if ($mem_string !== false && isset($performance_level[$mem_string + 1])) {
                                 $mem_string = str_ireplace('MHz', null, $performance_level[$mem_string + 1]);
                                 if (is_numeric($mem_string) && $mem_string > $mem_freq) {
                                     $mem_freq = $mem_string;
                                 }
                             }
                         } else {
                             if (isset(phodevi::$vfs->i915_cur_delayinfo)) {
                                 $i915_cur_delayinfo = phodevi::$vfs->i915_cur_delayinfo;
                                 $cagf = strpos($i915_cur_delayinfo, 'CAGF: ');
                                 if ($cagf !== false) {
                                     $cagf_mhz = substr($i915_cur_delayinfo, $cagf + 6);
                                     $cagf_mhz = substr($cagf_mhz, 0, strpos($cagf_mhz, 'MHz'));
                                     if (is_numeric($cagf_mhz)) {
                                         $core_freq = $cagf_mhz;
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (!is_numeric($core_freq)) {
         $core_freq = 0;
     }
     if (!is_numeric($mem_freq)) {
         $mem_freq = 0;
     }
     if ($core_freq == 0 && $mem_freq == 0) {
         $show_memory = false;
         $core_freq = -1;
     }
     return $show_memory ? array($core_freq, $mem_freq) : $core_freq;
 }
 public static function monitor_layout()
 {
     // Determine layout for multiple monitors
     $monitor_layout = array('CENTER');
     if (phodevi::read_property('monitor', 'count') > 1) {
         $xdpy_monitors = phodevi_parser::read_xdpy_monitor_info();
         $hit_0_0 = false;
         for ($i = 0; $i < count($xdpy_monitors); $i++) {
             $monitor_position = explode('@', $xdpy_monitors[$i]);
             $monitor_position = trim($monitor_position[1]);
             $monitor_position_x = substr($monitor_position, 0, strpos($monitor_position, ','));
             $monitor_position_y = substr($monitor_position, strpos($monitor_position, ',') + 1);
             if ($monitor_position == '0,0') {
                 $hit_0_0 = true;
             } else {
                 if ($monitor_position_x > 0 && $monitor_position_y == 0) {
                     array_push($monitor_layout, $hit_0_0 ? 'RIGHT' : 'LEFT');
                 } else {
                     if ($monitor_position_x == 0 && $monitor_position_y > 0) {
                         array_push($monitor_layout, $hit_0_0 ? 'LOWER' : 'UPPER');
                     }
                 }
             }
         }
         if (count($monitor_layout) == 1) {
             // Something went wrong with xdpy information, go to fallback support
             if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
                 $amdpcsdb_monitor_layout = phodevi_linux_parser::read_amd_pcsdb('SYSTEM/BUSID-*/DDX,DesktopSetup');
                 $amdpcsdb_monitor_layout = pts_arrays::to_array($amdpcsdb_monitor_layout);
                 foreach ($amdpcsdb_monitor_layout as $card_monitor_configuration) {
                     switch ($card_monitor_configuration) {
                         case 'horizontal':
                             array_push($monitor_layout, 'RIGHT');
                             break;
                         case 'horizontal,reverse':
                             array_push($monitor_layout, 'LEFT');
                             break;
                         case 'vertical':
                             array_push($monitor_layout, 'ABOVE');
                             break;
                         case 'vertical,reverse':
                             array_push($monitor_layout, 'BELOW');
                             break;
                     }
                 }
             }
         }
     }
     return implode(',', $monitor_layout);
 }
 private static function sys_battery_power()
 {
     // Returns power consumption rate in mW
     $rate = -1;
     if (phodevi::is_linux()) {
         $power_now = phodevi_linux_parser::read_sysfs_node('/sys/class/power_supply/*/power_now', 'POSITIVE_NUMERIC', array('status' => 'Discharging'));
         if ($power_now != -1) {
             // sysfs power_now seems to be displayed in microWatts
             $rate = pts_math::set_precision($power_now / 1000, 2);
         }
         if ($rate == -1) {
             $battery = array('/battery/BAT0/state', '/battery/BAT1/state');
             $state = phodevi_linux_parser::read_acpi($battery, 'charging state');
             $power = phodevi_linux_parser::read_acpi($battery, 'present rate');
             $voltage = phodevi_linux_parser::read_acpi($battery, 'present voltage');
             if ($state == 'discharging') {
                 $power_unit = substr($power, strrpos($power, ' ') + 1);
                 $power = substr($power, 0, strpos($power, ' '));
                 if ($power_unit == 'mA') {
                     $voltage_unit = substr($voltage, strrpos($voltage, ' ') + 1);
                     $voltage = substr($voltage, 0, strpos($voltage, ' '));
                     if ($voltage_unit == 'mV') {
                         $rate = round($power * $voltage / 1000);
                     }
                 } else {
                     if ($power_unit == 'mW') {
                         $rate = $power;
                     }
                 }
             }
         }
         if ($rate == -1 && is_file('/sys/class/power_supply/BAT0/voltage_now') && is_file('/sys/class/power_supply/BAT0/current_now')) {
             $voltage_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT0/voltage_now') / 1000;
             $current_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT0/current_now') / 1000;
             $power_now = $voltage_now * $current_now / 1000;
             if ($power_now > 1) {
                 $rate = $power_now;
             }
         }
         if ($rate == -1 && is_file('/sys/class/power_supply/BAT1/voltage_now') && is_file('/sys/class/power_supply/BAT1/current_now')) {
             $voltage_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT1/voltage_now') / 1000;
             $current_now = pts_file_io::file_get_contents('/sys/class/power_supply/BAT1/current_now') / 1000;
             $power_now = $voltage_now * $current_now / 1000;
             if ($power_now > 1) {
                 $rate = $power_now;
             }
         }
     } else {
         if (phodevi::is_macosx()) {
             $amperage = abs(phodevi_osx_parser::read_osx_system_profiler('SPPowerDataType', 'Amperage'));
             // in mA
             $voltage = phodevi_osx_parser::read_osx_system_profiler('SPPowerDataType', 'Voltage');
             // in mV
             if ($amperage > 0 && $voltage > 0) {
                 $rate = round($amperage * $voltage / 1000);
             } else {
                 if (pts_client::executable_in_path('ioreg')) {
                     $ioreg = trim(shell_exec("ioreg -l | grep LegacyBatteryInfo | cut -d '{' -f 2 | tr -d \\} | tr ',' '=' | awk -F'=' '{print (\$2*\$10/10^22)}' 2>&1"));
                     if (is_numeric($ioreg) && $ioreg > 0) {
                         $rate = $ioreg;
                     }
                 }
             }
         } else {
             if (phodevi::is_solaris()) {
                 $battery = phodevi_solaris_parser::read_hal_property('/org/freedesktop/Hal/devices/pseudo/acpi_drv_0_battery0_0', 'battery.reporting.rate');
                 if (is_numeric($battery)) {
                     $rate = $battery;
                 }
             } else {
                 if (phodevi::is_bsd()) {
                     $battery = phodevi_bsd_parser::read_acpiconf('Present rate');
                     if ($battery && substr($battery, -2) == 'mW') {
                         $rate = substr($battery, 0, strpos($battery, ' '));
                     }
                 }
             }
         }
     }
     return $rate;
 }
 public static function __pre_run_process()
 {
     if (!(phodevi::is_nvidia_graphics() || phodevi::is_ati_graphics() && phodevi::is_linux())) {
         echo "\nNo supported driver found for graphics_override module!\n";
         return pts_module::MODULE_UNLOAD;
         // Not using a supported driver, quit the module
     }
     $force_aa = pts_module::read_variable("FORCE_AA");
     $force_af = pts_module::read_variable("FORCE_AF");
     if ($force_aa !== FALSE && in_array($force_aa, self::$supported_aa_levels)) {
         // First backup any existing override, then set the new value
         if (phodevi::is_nvidia_graphics()) {
             self::$preset_aa = phodevi_parser::read_nvidia_extension("FSAA");
             self::$preset_aa_control = phodevi_parser::read_nvidia_extension("FSAAAppControlled");
             switch ($force_aa) {
                 case 2:
                     $nvidia_aa = 2;
                     break;
                 case 4:
                     $nvidia_aa = 5;
                     break;
                 case 8:
                     $nvidia_aa = 7;
                     break;
                 case 16:
                     $nvidia_aa = 8;
                     break;
             }
             if (isset($nvidia_aa)) {
                 self::set_nvidia_extension("FSAA", $nvidia_aa);
                 self::set_nvidia_extension("FSAAAppControlled", 0);
             }
         } else {
             if (phodevi::is_ati_graphics()) {
                 self::$preset_aa = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AntiAliasSamples");
                 self::$preset_aa_control = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AAF");
                 switch ($force_aa) {
                     case 2:
                         $ati_aa = "0x00000002";
                         break;
                     case 4:
                         $ati_aa = "0x00000004";
                         break;
                     case 8:
                         $ati_aa = "0x00000008";
                         break;
                     case 16:
                         echo "\nThe ATI fglrx driver currently does not support 16x AA! Defaulting to 8x AA!\n";
                         $ati_aa = "0x00000008";
                         break;
                 }
                 if (isset($ati_aa)) {
                     self::set_amd_pcsdb("OpenGL,AntiAliasSamples", $ati_aa);
                     self::set_amd_pcsdb("OpenGL,AAF", "0x00000000");
                 }
             }
         }
     }
     if ($force_af !== FALSE && in_array($force_af, self::$supported_af_levels)) {
         // First backup any existing override, then set the new value
         if (phodevi::is_nvidia_graphics()) {
             self::$preset_af = phodevi_parser::read_nvidia_extension("LogAniso");
             self::$preset_af_control = phodevi_parser::read_nvidia_extension("LogAnisoAppControlled");
             switch ($force_af) {
                 case 2:
                     $nvidia_af = 1;
                     break;
                 case 4:
                     $nvidia_af = 2;
                     break;
                 case 8:
                     $nvidia_af = 3;
                     break;
                 case 16:
                     $nvidia_af = 4;
                     break;
             }
             if (isset($nvidia_af)) {
                 self::set_nvidia_extension("LogAniso", $nvidia_af);
                 self::set_nvidia_extension("LogAnisoAppControlled", 0);
             }
         } else {
             if (phodevi::is_ati_graphics()) {
                 self::$preset_af = phodevi_linux_parser::read_amd_pcsdb("OpenGL,AnisoDegree");
                 switch ($force_af) {
                     case 2:
                         $ati_af = "0x00000002";
                         break;
                     case 4:
                         $ati_af = "0x00000004";
                         break;
                     case 8:
                         $ati_af = "0x00000008";
                         break;
                     case 16:
                         $ati_af = "0x00000010";
                         break;
                 }
                 if (isset($ati_af)) {
                     self::set_amd_pcsdb("OpenGL,AnisoDegree", $ati_af);
                 }
             }
         }
     }
 }
 public static function motherboard_string()
 {
     // Returns the motherboard / system model name or number
     $info = null;
     if (phodevi::is_macosx()) {
         $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ModelName');
     } else {
         if (phodevi::is_solaris()) {
             $manufacturer = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Manufacturer', 'SystemInformation,Manufacturer'));
             $product = phodevi_solaris_parser::read_sun_ddu_dmi_info(array('MotherBoardInformation,Product', 'SystemInformation,Product', 'SystemInformation,Model'));
             if (count($manufacturer) == 1 && count($product) == 1) {
                 $info = $manufacturer[0] . ' ' . $product[0];
             }
         } else {
             if (phodevi::is_bsd()) {
                 $vendor = phodevi_bsd_parser::read_kenv('smbios.system.maker');
                 $product = phodevi_bsd_parser::read_kenv('smbios.system.product');
                 $version = phodevi_bsd_parser::read_kenv('smbios.system.version');
                 // for at least Lenovo ThinkPads this is where it displays ThinkPad model
                 if ($vendor != null && ($product != null || $version != null)) {
                     $info = $vendor . ' ' . $product . ' ' . $version;
                 } else {
                     if (($vendor = phodevi_bsd_parser::read_sysctl('hw.vendor')) != false && ($version = phodevi_bsd_parser::read_sysctl(array('hw.version', 'hw.product'))) != false) {
                         $info = trim($vendor . ' ' . $version);
                     } else {
                         if (($acpi = phodevi_bsd_parser::read_sysctl('dev.acpi.0.%desc')) != false) {
                             $info = trim($acpi);
                         }
                     }
                 }
             } else {
                 if (phodevi::is_linux()) {
                     $vendor = phodevi_linux_parser::read_sys_dmi(array('board_vendor', 'sys_vendor'));
                     $name = phodevi_linux_parser::read_sys_dmi(array('board_name', 'product_name'));
                     $version = phodevi_linux_parser::read_sys_dmi(array('board_version', 'product_version'));
                     if ($vendor != false && $name != false) {
                         $info = strpos($name . ' ', $vendor . ' ') === false ? $vendor . ' ' : null;
                         $info .= $name;
                         if ($version != false && strpos($info, $version) === false && pts_strings::string_only_contains($version, pts_strings::CHAR_NUMERIC | pts_strings::CHAR_DECIMAL)) {
                             $info .= (substr($version, 0, 1) == 'v' ? ' ' : ' v') . $version;
                         }
                     }
                     if (empty($info)) {
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('Hardware');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                         $bios_vendor = phodevi_linux_parser::read_sys_dmi('bios_vendor');
                         $bios_version = phodevi_linux_parser::read_sys_dmi('bios_version');
                         if ($bios_vendor != null) {
                             $info = $bios_vendor . ' ' . $bios_version;
                         }
                         if ($info == null) {
                             $hw_string = phodevi_linux_parser::read_cpuinfo('machine');
                             if (count($hw_string) == 1) {
                                 $info = $hw_string[0];
                             }
                         }
                     }
                     if (empty($info)) {
                         $info = phodevi_linux_parser::read_sys_dmi('product_name');
                     }
                     if (empty($info) && is_file('/sys/bus/soc/devices/soc0/machine')) {
                         $info = pts_file_io::file_get_contents('/sys/bus/soc/devices/soc0/machine');
                     }
                     if (empty($info)) {
                         // Works on the MIPS Creator CI20
                         $hardware = phodevi_linux_parser::read_cpuinfo('Hardware');
                         if (!empty($hardware)) {
                             $info = array_pop($hardware);
                         }
                     }
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Mainboard Model', null);
                     }
                 }
             }
         }
     }
     if ((strpos($info, 'Mac ') !== false || strpos($info, 'MacBook') !== false) && strpos($info, 'Apple') === false) {
         $info = 'Apple ' . $info;
     }
     // ensure words aren't repeated (e.g. VMware VMware Virtual and MSI MSI X58M (MS-7593))
     $info = implode(' ', array_unique(explode(' ', $info)));
     return $info;
 }
 public static function sw_display_driver($with_version = true)
 {
     if (phodevi::is_windows()) {
         return null;
     }
     $display_driver = phodevi::read_property('system', 'dri-display-driver');
     if (empty($display_driver)) {
         if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
             $display_driver = 'fglrx';
         } else {
             if (phodevi::is_nvidia_graphics() || is_file('/proc/driver/nvidia/version')) {
                 $display_driver = 'nvidia';
             } else {
                 if ((phodevi::is_mesa_graphics() || phodevi::is_bsd()) && stripos(phodevi::read_property('gpu', 'model'), 'NVIDIA') !== false) {
                     if (is_file('/sys/class/drm/version')) {
                         // If there's DRM loaded and NVIDIA, it should be Nouveau
                         $display_driver = 'nouveau';
                     } else {
                         // The dead xf86-video-nv doesn't use any DRM
                         $display_driver = 'nv';
                     }
                 } else {
                     // Fallback to hopefully detect the module, takes the first word off the GPU string and sees if it is the module
                     // This works in at least the case of the Cirrus driver
                     $display_driver = strtolower(pts_strings::first_in_string(phodevi::read_property('gpu', 'model')));
                 }
             }
         }
     }
     if (!empty($display_driver)) {
         $driver_version = phodevi_parser::read_xorg_module_version($display_driver . '_drv');
         if ($driver_version == false || $driver_version == '1.0.0') {
             switch ($display_driver) {
                 case 'amd':
                     // See if it's radeon driver
                     $driver_version = phodevi_parser::read_xorg_module_version('radeon_drv');
                     if ($driver_version != false) {
                         $display_driver = 'radeon';
                     }
                     break;
                 case 'vmwgfx':
                     // See if it's VMware driver
                     $driver_version = phodevi_parser::read_xorg_module_version('vmware_drv');
                     if ($driver_version != false) {
                         $display_driver = 'vmware';
                     }
                     break;
                 case 'radeon':
                     // RadeonHD driver also reports DRI driver as 'radeon', so try reading that instead
                     $driver_version = phodevi_parser::read_xorg_module_version('radeonhd_drv');
                     if ($driver_version != false) {
                         $display_driver = 'radeonhd';
                     }
                     break;
                 case 'nvidia':
                 case 'NVIDIA':
                 case 'nouveau':
                     // NVIDIA's binary driver usually ends up reporting 1.0.0
                     if ($nvs_value = phodevi_parser::read_nvidia_extension('NvidiaDriverVersion')) {
                         $display_driver = 'NVIDIA';
                         $driver_version = $nvs_value;
                     } else {
                         // NVIDIA's binary driver appends their driver version on the end of the OpenGL version string
                         $glxinfo = phodevi_parser::software_glxinfo_version();
                         if (($pos = strpos($glxinfo, 'NVIDIA ')) != false) {
                             $display_driver = 'NVIDIA';
                             $driver_version = substr($glxinfo, $pos + 7);
                         }
                     }
                     break;
                 default:
                     if (is_readable('/sys/class/graphics/fb0/name')) {
                         // This path works for at least finding NVIDIA Tegra 2 DDX (via tegra_fb)
                         $display_driver = file_get_contents('/sys/class/graphics/fb0/name');
                         $display_driver = str_replace(array('drm', '_fb'), null, $display_driver);
                         $driver_version = phodevi_parser::read_xorg_module_version($display_driver . '_drv');
                     }
                     break;
             }
         }
         if ($driver_version == false) {
             // If the version is empty, chances are the DDX driver string is incorrect
             $display_driver = null;
             // See if the VESA or fbdev driver is in use
             foreach (array('modesetting', 'fbdev', 'vesa') as $drv) {
                 $drv_version = phodevi_parser::read_xorg_module_version($drv . '_drv');
                 if ($drv_version) {
                     $display_driver = $drv;
                     $driver_version = $drv_version;
                     break;
                 }
             }
         }
         if (!empty($driver_version) && $with_version && $driver_version != '0.0.0') {
             $display_driver .= ' ' . $driver_version;
             // XXX: The below check is disabled since the Catalyst Version no longer seems reliably reported (circa Catalyst 13.x)
             if (false && phodevi::is_ati_graphics() && strpos($display_driver, 'fglrx') !== false) {
                 $catalyst_version = phodevi_linux_parser::read_amd_pcsdb('AMDPCSROOT/SYSTEM/LDC,Catalyst_Version');
                 if ($catalyst_version != null && $catalyst_version > 10.1 && $catalyst_version != 10.5 && $catalyst_version != 11.8) {
                     // This option was introduced around Catalyst 10.5 but seems to not be updated properly until Catalyst 10.11/10.12
                     $display_driver .= ' Catalyst ' . $catalyst_version . '';
                 }
             }
         }
     }
     return $display_driver;
 }
 public static function gpu_model()
 {
     // Report graphics processor string
     $info = phodevi_parser::read_glx_renderer();
     $video_ram = phodevi::read_property('gpu', 'memory-capacity');
     if (phodevi::is_ati_graphics() && phodevi::is_linux()) {
         $crossfire_status = phodevi_linux_parser::read_amd_pcsdb('SYSTEM/Crossfire/chain/*,Enable');
         $crossfire_status = pts_arrays::to_array($crossfire_status);
         $crossfire_card_count = 0;
         for ($i = 0; $i < count($crossfire_status); $i++) {
             if ($crossfire_status[$i] == '0x00000001') {
                 $crossfire_card_count += 2;
                 // For now assume each chain is 2 cards, but proper way would be NumSlaves + 1
             }
         }
         $adapters = phodevi_linux_parser::read_amd_graphics_adapters();
         if (count($adapters) > 0) {
             $video_ram = $video_ram > 64 ? ' ' . $video_ram . 'MB' : null;
             // assume more than 64MB of vRAM
             if ($crossfire_card_count > 1 && $crossfire_card_count <= count($adapters)) {
                 $unique_adapters = array_unique($adapters);
                 if (count($unique_adapters) == 1) {
                     if (strpos($adapters[0], 'X2') > 0 && $crossfire_card_count > 1) {
                         $crossfire_card_count -= 1;
                     }
                     $info = $crossfire_card_count . ' x ' . $adapters[0] . $video_ram . ' CrossFire';
                 } else {
                     $info = implode(', ', $unique_adapters) . ' CrossFire';
                 }
             } else {
                 $info = $adapters[0] . $video_ram;
             }
         }
     } else {
         if (phodevi::is_macosx()) {
             $system_profiler_info = implode(' + ', phodevi_osx_parser::read_osx_system_profiler('SPDisplaysDataType', 'ChipsetModel', true));
             if (!empty($system_profiler_info)) {
                 $info = $system_profiler_info;
             }
         } else {
             if (phodevi::is_nvidia_graphics()) {
                 if ($info == null) {
                     if (pts_client::executable_in_path('nvidia-settings')) {
                         $nv_gpus = shell_exec('nvidia-settings -q gpus 2>&1');
                         // TODO: search for more than one GPU
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '[0]'));
                         $nv_gpus = substr($nv_gpus, strpos($nv_gpus, '(') + 1);
                         $nv_gpus = substr($nv_gpus, 0, strpos($nv_gpus, ')'));
                         if (stripos($nv_gpus, 'GeForce') !== false || stripos($nv_gpus, 'Quadro') !== false) {
                             $info = $nv_gpus;
                         }
                     }
                 }
                 $sli_mode = phodevi_parser::read_nvidia_extension('SLIMode');
                 if (!empty($sli_mode) && $sli_mode != 'Off') {
                     $info .= ' SLI';
                 }
             } else {
                 if (phodevi::is_solaris()) {
                     if (($cut = strpos($info, 'DRI ')) !== false) {
                         $info = substr($info, $cut + 4);
                     }
                     if (($cut = strpos($info, ' Chipset')) !== false) {
                         $info = substr($info, 0, $cut);
                     }
                     if ($info == false && isset(phodevi::$vfs->xorg_log)) {
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 14);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (($c = strpos($xorg_log, '[')) || ($c = strpos($xorg_log, '('))) {
                                 $xorg_log = substr($xorg_log, 0, $c);
                             }
                             if (phodevi::is_product_string($xorg_log)) {
                                 $info = $xorg_log;
                             }
                         }
                     }
                 } else {
                     if (phodevi::is_bsd()) {
                         $drm_info = phodevi_bsd_parser::read_sysctl('dev.drm.0.%desc');
                         if (!$drm_info) {
                             $drm_info = phodevi_bsd_parser::read_sysctl('dev.nvidia.0.%desc');
                         }
                         if (!$drm_info) {
                             $agp_info = phodevi_bsd_parser::read_sysctl('dev.agp.0.%desc');
                             if ($agp_info != false) {
                                 $info = $agp_info;
                             }
                         } else {
                             $info = $drm_info;
                         }
                         if ($info == null && isset(phodevi::$vfs->xorg_log)) {
                             $xorg_log = phodevi::$vfs->xorg_log;
                             if (($e = strpos($xorg_log, ' at 01@00:00:0')) !== false) {
                                 $xorg_log = substr($xorg_log, 0, $e);
                                 $info = substr($xorg_log, strrpos($xorg_log, 'Found ') + 6);
                             }
                         }
                     } else {
                         if (phodevi::is_windows()) {
                             $info = phodevi_windows_parser::read_cpuz('Display Adapters', 'Name');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info) || strpos($info, 'Mesa ') !== false || strpos($info, 'Gallium ') !== false) {
         if (phodevi::is_windows() == false) {
             $info_pci = phodevi_linux_parser::read_pci('VGA compatible controller', false);
             if (!empty($info_pci)) {
                 $info = $info_pci;
                 if (strpos($info, 'Intel 2nd Generation Core Family') !== false || strpos($info, 'Gen Core') !== false) {
                     // Try to come up with a better non-generic string
                     $was_reset = false;
                     if (isset(phodevi::$vfs->xorg_log)) {
                         /*
                         $ cat /var/log/Xorg.0.log | grep -i Chipset
                         [     8.421] (II) intel: Driver for Intel Integrated Graphics Chipsets: i810,
                         [     8.421] (II) VESA: driver for VESA chipsets: vesa
                         [     8.423] (II) intel(0): Integrated Graphics Chipset: Intel(R) Sandybridge Mobile (GT2+)
                         [     8.423] (--) intel(0): Chipset: "Sandybridge Mobile (GT2+)"
                         */
                         $xorg_log = phodevi::$vfs->xorg_log;
                         if (($x = strpos($xorg_log, 'Integrated Graphics Chipset: ')) !== false) {
                             $xorg_log = substr($xorg_log, $x + 29);
                             $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                             if (stripos($xorg_log, 'Intel') === false) {
                                 $xorg_log = 'Intel ' . $xorg_log;
                             }
                             // if string is too long, likely not product
                             if (!isset($xorg_log[45])) {
                                 $info = $xorg_log;
                                 $was_reset = true;
                             }
                         } else {
                             if (($x = strpos($xorg_log, '(0): Chipset: ')) !== false) {
                                 $xorg_log = substr($xorg_log, $x + 14);
                                 $xorg_log = str_replace(array('(R)', '"'), null, substr($xorg_log, 0, strpos($xorg_log, PHP_EOL)));
                                 if (stripos($xorg_log, 'Intel') === false) {
                                     $xorg_log = 'Intel ' . $xorg_log;
                                 }
                                 // if string is too long, likely not product
                                 if (!isset($xorg_log[45])) {
                                     $info = $xorg_log;
                                     $was_reset = true;
                                 }
                             }
                         }
                     }
                     if ($was_reset == false && isset(phodevi::$vfs->i915_capabilities)) {
                         $i915_caps = phodevi::$vfs->i915_capabilities;
                         if (($x = strpos($i915_caps, 'gen: ')) !== false) {
                             $gen = substr($i915_caps, $x + 5);
                             $gen = substr($gen, 0, strpos($gen, PHP_EOL));
                             if (is_numeric($gen)) {
                                 $info = 'Intel Gen' . $gen;
                                 if (strpos($i915_caps, 'is_mobile: yes') !== false) {
                                     $info .= ' Mobile';
                                 }
                             }
                         }
                     }
                 }
             }
         }
         if (($start_pos = strpos($info, ' DRI ')) > 0) {
             $info = substr($info, $start_pos + 5);
         }
         if (empty($info) && isset(phodevi::$vfs->xorg_log)) {
             $log_parse = phodevi::$vfs->xorg_log;
             $log_parse = substr($log_parse, strpos($log_parse, 'Chipset') + 8);
             $log_parse = substr($log_parse, 0, strpos($log_parse, 'found'));
             if (strpos($log_parse, '(--)') === false && strlen(str_ireplace(array('ATI', 'NVIDIA', 'VIA', 'Intel'), '', $log_parse)) != strlen($log_parse)) {
                 $info = $log_parse;
             }
         }
         if (empty($info) && is_readable('/sys/class/graphics/fb0/name')) {
             switch (pts_file_io::file_get_contents('/sys/class/graphics/fb0/name')) {
                 case 'omapdrm':
                     $info = 'Texas Instruments OMAP';
                     // The OMAP DRM driver currently is for OMAP2/3/4 hardware
                     break;
                 case 'exynos':
                     $info = 'Samsung EXYNOS';
                     // The Exynos DRM driver
                     break;
                 case 'tegra_fb':
                     $info = 'NVIDIA TEGRA';
                     // The Exynos DRM driver
                     break;
                 default:
                     if (is_file('/dev/mali')) {
                         $info = 'ARM Mali';
                         // One of the ARM Mali models
                     }
                     break;
             }
         }
         if (substr($info, -1) == ')' && ($open_p = strrpos($info, '(')) != false) {
             $end_check = strpos($info, ' ', $open_p);
             $to_check = substr($info, $open_p + 1, $end_check - $open_p - 1);
             // Don't report card revision from PCI info
             if ($to_check == 'rev') {
                 $info = substr($info, 0, $open_p - 1);
             }
         }
     }
     if (($bracket_open = strpos($info, '[')) !== false) {
         // Report only the information inside the brackets if it's more relevant...
         // Mainly with Linux systems where the PCI information is reported like 'nVidia GF104 [GeForce GTX 460]'
         if (($bracket_close = strpos($info, ']', $bracket_open + 1)) !== false) {
             $inside_bracket = substr($info, $bracket_open + 1, $bracket_close - $bracket_open - 1);
             if (stripos($inside_bracket, 'Quadro') !== false || stripos($inside_bracket, 'GeForce') !== false) {
                 $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
             } else {
                 if (stripos($inside_bracket, 'Radeon') !== false || stripos($inside_bracket, 'Fire') !== false || stripos($inside_bracket, 'Fusion') !== false) {
                     $info = $inside_bracket . ' ' . substr($info, $bracket_close + 1);
                 }
             }
         }
     }
     if (stripos($info, 'NVIDIA') === false && (stripos($info, 'Quadro') !== false || stripos($info, 'GeForce') !== false)) {
         $info = 'NVIDIA' . ' ' . $info;
     } else {
         if (stripos($info, 'ATI') === false && stripos($info, 'AMD') === false && (stripos($info, 'Radeon') !== false || stripos($info, 'Fire') !== false || stripos($info, 'Fusion') !== false)) {
             // Fire would be for FireGL or FirePro hardware
             $info = 'AMD ' . $info;
         }
     }
     if (phodevi::is_linux() && ($vendor = phodevi_linux_parser::read_pci_subsystem_value('VGA compatible controller')) != null && stripos($info, $vendor) === false && (stripos($info, 'AMD') !== false || stripos($info, 'NVIDIA') !== false)) {
         $info = $vendor . ' ' . $info;
     }
     if ($video_ram > 64 && strpos($info, $video_ram) == false) {
         $info .= ' ' . $video_ram . 'MB';
     }
     $clean_phrases = array('OpenGL Engine');
     $info = str_replace($clean_phrases, null, $info);
     return $info;
 }