lbl.cpp 11 KB

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