lbl.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cmath>
  5. #include <memory>
  6. #include "common/logging/log.h"
  7. #include "core/hle/ipc_helpers.h"
  8. #include "core/hle/kernel/hle_ipc.h"
  9. #include "core/hle/service/lbl/lbl.h"
  10. #include "core/hle/service/service.h"
  11. #include "core/hle/service/sm/sm.h"
  12. namespace Service::LBL {
  13. class LBL final : public ServiceFramework<LBL> {
  14. public:
  15. explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} {
  16. // clang-format off
  17. static const FunctionInfo functions[] = {
  18. {0, nullptr, "SaveCurrentSetting"},
  19. {1, nullptr, "LoadCurrentSetting"},
  20. {2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"},
  21. {3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"},
  22. {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"},
  23. {5, nullptr, "GetBrightnessSettingAppliedToBacklight"},
  24. {6, &LBL::SwitchBacklightOn, "SwitchBacklightOn"},
  25. {7, &LBL::SwitchBacklightOff, "SwitchBacklightOff"},
  26. {8, &LBL::GetBacklightSwitchStatus, "GetBacklightSwitchStatus"},
  27. {9, &LBL::EnableDimming, "EnableDimming"},
  28. {10, &LBL::DisableDimming, "DisableDimming"},
  29. {11, &LBL::IsDimmingEnabled, "IsDimmingEnabled"},
  30. {12, &LBL::EnableAutoBrightnessControl, "EnableAutoBrightnessControl"},
  31. {13, &LBL::DisableAutoBrightnessControl, "DisableAutoBrightnessControl"},
  32. {14, &LBL::IsAutoBrightnessControlEnabled, "IsAutoBrightnessControlEnabled"},
  33. {15, &LBL::SetAmbientLightSensorValue, "SetAmbientLightSensorValue"},
  34. {16, &LBL::GetAmbientLightSensorValue, "GetAmbientLightSensorValue"},
  35. {17, &LBL::SetBrightnessReflectionDelayLevel, "SetBrightnessReflectionDelayLevel"},
  36. {18, &LBL::GetBrightnessReflectionDelayLevel, "GetBrightnessReflectionDelayLevel"},
  37. {19, &LBL::SetCurrentBrightnessMapping, "SetCurrentBrightnessMapping"},
  38. {20, &LBL::GetCurrentBrightnessMapping, "GetCurrentBrightnessMapping"},
  39. {21, &LBL::SetCurrentAmbientLightSensorMapping, "SetCurrentAmbientLightSensorMapping"},
  40. {22, &LBL::GetCurrentAmbientLightSensorMapping, "GetCurrentAmbientLightSensorMapping"},
  41. {23, &LBL::IsAmbientLightSensorAvailable, "IsAmbientLightSensorAvailable"},
  42. {24, &LBL::SetCurrentBrightnessSettingForVrMode, "SetCurrentBrightnessSettingForVrMode"},
  43. {25, &LBL::GetCurrentBrightnessSettingForVrMode, "GetCurrentBrightnessSettingForVrMode"},
  44. {26, &LBL::EnableVrMode, "EnableVrMode"},
  45. {27, &LBL::DisableVrMode, "DisableVrMode"},
  46. {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"},
  47. {29, nullptr, "IsAutoBrightnessControlSupported"},
  48. };
  49. // clang-format on
  50. RegisterHandlers(functions);
  51. }
  52. private:
  53. enum class BacklightSwitchStatus : u32 {
  54. Off = 0,
  55. On = 1,
  56. };
  57. void SetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
  58. IPC::RequestParser rp{ctx};
  59. auto brightness = rp.Pop<float>();
  60. if (!std::isfinite(brightness)) {
  61. LOG_ERROR(Service_LBL, "Brightness is infinite!");
  62. brightness = 0.0f;
  63. }
  64. LOG_DEBUG(Service_LBL, "called brightness={}", brightness);
  65. current_brightness = brightness;
  66. update_instantly = true;
  67. IPC::ResponseBuilder rb{ctx, 2};
  68. rb.Push(ResultSuccess);
  69. }
  70. void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) {
  71. auto brightness = current_brightness;
  72. if (!std::isfinite(brightness)) {
  73. LOG_ERROR(Service_LBL, "Brightness is infinite!");
  74. brightness = 0.0f;
  75. }
  76. LOG_DEBUG(Service_LBL, "called brightness={}", brightness);
  77. IPC::ResponseBuilder rb{ctx, 3};
  78. rb.Push(ResultSuccess);
  79. rb.Push(brightness);
  80. }
  81. void SwitchBacklightOn(Kernel::HLERequestContext& ctx) {
  82. IPC::RequestParser rp{ctx};
  83. const auto fade_time = rp.Pop<u64_le>();
  84. LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time);
  85. backlight_enabled = true;
  86. IPC::ResponseBuilder rb{ctx, 2};
  87. rb.Push(ResultSuccess);
  88. }
  89. void SwitchBacklightOff(Kernel::HLERequestContext& ctx) {
  90. IPC::RequestParser rp{ctx};
  91. const auto fade_time = rp.Pop<u64_le>();
  92. LOG_WARNING(Service_LBL, "(STUBBED) called, fade_time={}", fade_time);
  93. backlight_enabled = false;
  94. IPC::ResponseBuilder rb{ctx, 2};
  95. rb.Push(ResultSuccess);
  96. }
  97. void GetBacklightSwitchStatus(Kernel::HLERequestContext& ctx) {
  98. LOG_DEBUG(Service_LBL, "called");
  99. IPC::ResponseBuilder rb{ctx, 3};
  100. rb.Push(ResultSuccess);
  101. rb.PushEnum<BacklightSwitchStatus>(backlight_enabled ? BacklightSwitchStatus::On
  102. : BacklightSwitchStatus::Off);
  103. }
  104. void EnableDimming(Kernel::HLERequestContext& ctx) {
  105. LOG_DEBUG(Service_LBL, "called");
  106. dimming = true;
  107. IPC::ResponseBuilder rb{ctx, 2};
  108. rb.Push(ResultSuccess);
  109. }
  110. void DisableDimming(Kernel::HLERequestContext& ctx) {
  111. LOG_DEBUG(Service_LBL, "called");
  112. dimming = false;
  113. IPC::ResponseBuilder rb{ctx, 2};
  114. rb.Push(ResultSuccess);
  115. }
  116. void IsDimmingEnabled(Kernel::HLERequestContext& ctx) {
  117. LOG_DEBUG(Service_LBL, "called");
  118. IPC::ResponseBuilder rb{ctx, 3};
  119. rb.Push(ResultSuccess);
  120. rb.Push(dimming);
  121. }
  122. void EnableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
  123. LOG_DEBUG(Service_LBL, "called");
  124. auto_brightness = true;
  125. update_instantly = true;
  126. IPC::ResponseBuilder rb{ctx, 2};
  127. rb.Push(ResultSuccess);
  128. }
  129. void DisableAutoBrightnessControl(Kernel::HLERequestContext& ctx) {
  130. LOG_DEBUG(Service_LBL, "called");
  131. auto_brightness = false;
  132. IPC::ResponseBuilder rb{ctx, 2};
  133. rb.Push(ResultSuccess);
  134. }
  135. void IsAutoBrightnessControlEnabled(Kernel::HLERequestContext& ctx) {
  136. LOG_DEBUG(Service_LBL, "called");
  137. IPC::ResponseBuilder rb{ctx, 3};
  138. rb.Push(ResultSuccess);
  139. rb.Push(auto_brightness);
  140. }
  141. void SetAmbientLightSensorValue(Kernel::HLERequestContext& ctx) {
  142. IPC::RequestParser rp{ctx};
  143. const auto light_value = rp.Pop<float>();
  144. LOG_DEBUG(Service_LBL, "called light_value={}", light_value);
  145. ambient_light_value = light_value;
  146. IPC::ResponseBuilder rb{ctx, 2};
  147. rb.Push(ResultSuccess);
  148. }
  149. void GetAmbientLightSensorValue(Kernel::HLERequestContext& ctx) {
  150. LOG_DEBUG(Service_LBL, "called");
  151. IPC::ResponseBuilder rb{ctx, 3};
  152. rb.Push(ResultSuccess);
  153. rb.Push(ambient_light_value);
  154. }
  155. void SetBrightnessReflectionDelayLevel(Kernel::HLERequestContext& ctx) {
  156. // This is Intentional, this function does absolutely nothing
  157. LOG_DEBUG(Service_LBL, "called");
  158. IPC::ResponseBuilder rb{ctx, 2};
  159. rb.Push(ResultSuccess);
  160. }
  161. void GetBrightnessReflectionDelayLevel(Kernel::HLERequestContext& ctx) {
  162. // This is intentional, the function is hard coded to return 0.0f on hardware
  163. LOG_DEBUG(Service_LBL, "called");
  164. IPC::ResponseBuilder rb{ctx, 3};
  165. rb.Push(ResultSuccess);
  166. rb.Push(0.0f);
  167. }
  168. void SetCurrentBrightnessMapping(Kernel::HLERequestContext& ctx) {
  169. // This is Intentional, this function does absolutely nothing
  170. LOG_DEBUG(Service_LBL, "called");
  171. IPC::ResponseBuilder rb{ctx, 2};
  172. rb.Push(ResultSuccess);
  173. }
  174. void GetCurrentBrightnessMapping(Kernel::HLERequestContext& ctx) {
  175. // This is Intentional, this function does absolutely nothing
  176. LOG_DEBUG(Service_LBL, "called");
  177. IPC::ResponseBuilder rb{ctx, 2};
  178. rb.Push(ResultSuccess);
  179. // This function is suppose to return something but it seems like it doesn't
  180. }
  181. void SetCurrentAmbientLightSensorMapping(Kernel::HLERequestContext& ctx) {
  182. // This is Intentional, this function does absolutely nothing
  183. LOG_DEBUG(Service_LBL, "called");
  184. IPC::ResponseBuilder rb{ctx, 2};
  185. rb.Push(ResultSuccess);
  186. }
  187. void GetCurrentAmbientLightSensorMapping(Kernel::HLERequestContext& ctx) {
  188. // This is Intentional, this function does absolutely nothing
  189. LOG_DEBUG(Service_LBL, "called");
  190. IPC::ResponseBuilder rb{ctx, 2};
  191. rb.Push(ResultSuccess);
  192. // This function is suppose to return something but it seems like it doesn't
  193. }
  194. void IsAmbientLightSensorAvailable(Kernel::HLERequestContext& ctx) {
  195. LOG_WARNING(Service_LBL, "(STUBBED) called");
  196. IPC::ResponseBuilder rb{ctx, 3};
  197. rb.Push(ResultSuccess);
  198. // TODO(ogniK): Only return true if there's no device error
  199. rb.Push(true);
  200. }
  201. void SetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
  202. IPC::RequestParser rp{ctx};
  203. auto brightness = rp.Pop<float>();
  204. if (!std::isfinite(brightness)) {
  205. LOG_ERROR(Service_LBL, "Brightness is infinite!");
  206. brightness = 0.0f;
  207. }
  208. LOG_DEBUG(Service_LBL, "called brightness={}", brightness);
  209. current_vr_brightness = brightness;
  210. IPC::ResponseBuilder rb{ctx, 2};
  211. rb.Push(ResultSuccess);
  212. }
  213. void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) {
  214. auto brightness = current_vr_brightness;
  215. if (!std::isfinite(brightness)) {
  216. LOG_ERROR(Service_LBL, "Brightness is infinite!");
  217. brightness = 0.0f;
  218. }
  219. LOG_DEBUG(Service_LBL, "called brightness={}", brightness);
  220. IPC::ResponseBuilder rb{ctx, 3};
  221. rb.Push(ResultSuccess);
  222. rb.Push(brightness);
  223. }
  224. void EnableVrMode(Kernel::HLERequestContext& ctx) {
  225. LOG_DEBUG(Service_LBL, "called");
  226. IPC::ResponseBuilder rb{ctx, 2};
  227. rb.Push(ResultSuccess);
  228. vr_mode_enabled = true;
  229. }
  230. void DisableVrMode(Kernel::HLERequestContext& ctx) {
  231. LOG_DEBUG(Service_LBL, "called");
  232. IPC::ResponseBuilder rb{ctx, 2};
  233. rb.Push(ResultSuccess);
  234. vr_mode_enabled = false;
  235. }
  236. void IsVrModeEnabled(Kernel::HLERequestContext& ctx) {
  237. LOG_DEBUG(Service_LBL, "called");
  238. IPC::ResponseBuilder rb{ctx, 3};
  239. rb.Push(ResultSuccess);
  240. rb.Push(vr_mode_enabled);
  241. }
  242. bool vr_mode_enabled = false;
  243. float current_brightness = 1.0f;
  244. float ambient_light_value = 0.0f;
  245. float current_vr_brightness = 1.0f;
  246. bool dimming = true;
  247. bool backlight_enabled = true;
  248. bool update_instantly = false;
  249. bool auto_brightness = false; // TODO(ogniK): Move to system settings
  250. };
  251. void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
  252. std::make_shared<LBL>(system)->InstallAsService(sm);
  253. }
  254. } // namespace Service::LBL