summaryrefslogtreecommitdiffstats
path: root/screen_ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'screen_ui.cpp')
-rw-r--r--screen_ui.cpp128
1 files changed, 55 insertions, 73 deletions
diff --git a/screen_ui.cpp b/screen_ui.cpp
index f1b38781a..b9aba807d 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -19,8 +19,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <linux/input.h>
-#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -32,8 +30,10 @@
#include <unistd.h>
#include <algorithm>
+#include <chrono>
#include <memory>
#include <string>
+#include <thread>
#include <unordered_map>
#include <vector>
@@ -169,8 +169,12 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
stage(-1),
max_stage(-1),
locale_(""),
- rtl_locale_(false),
- updateMutex(PTHREAD_MUTEX_INITIALIZER) {}
+ rtl_locale_(false) {}
+
+ScreenRecoveryUI::~ScreenRecoveryUI() {
+ progress_thread_stopped_ = true;
+ progress_thread_.join();
+}
GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
@@ -361,7 +365,7 @@ void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector<std::string
surfaces.emplace(name, std::unique_ptr<GRSurface, decltype(&free)>(text_image, &free));
}
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
gr_color(0, 0, 0, 255);
gr_clear();
@@ -393,7 +397,6 @@ void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector<std::string
}
// Update the whole screen.
gr_flip();
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::CheckBackgroundTextImages() {
@@ -613,52 +616,46 @@ void ScreenRecoveryUI::update_progress_locked() {
gr_flip();
}
-// Keeps the progress bar updated, even when the process is otherwise busy.
-void* ScreenRecoveryUI::ProgressThreadStartRoutine(void* data) {
- reinterpret_cast<ScreenRecoveryUI*>(data)->ProgressThreadLoop();
- return nullptr;
-}
-
void ScreenRecoveryUI::ProgressThreadLoop() {
double interval = 1.0 / kAnimationFps;
- while (true) {
+ while (!progress_thread_stopped_) {
double start = now();
- pthread_mutex_lock(&updateMutex);
-
bool redraw = false;
-
- // update the installation animation, if active
- // skip this if we have a text overlay (too expensive to update)
- if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) {
- if (!intro_done) {
- if (current_frame == intro_frames - 1) {
- intro_done = true;
- current_frame = 0;
+ {
+ std::lock_guard<std::mutex> lg(updateMutex);
+
+ // update the installation animation, if active
+ // skip this if we have a text overlay (too expensive to update)
+ if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) {
+ if (!intro_done) {
+ if (current_frame == intro_frames - 1) {
+ intro_done = true;
+ current_frame = 0;
+ } else {
+ ++current_frame;
+ }
} else {
- ++current_frame;
+ current_frame = (current_frame + 1) % loop_frames;
}
- } else {
- current_frame = (current_frame + 1) % loop_frames;
- }
-
- redraw = true;
- }
- // move the progress bar forward on timed intervals, if configured
- int duration = progressScopeDuration;
- if (progressBarType == DETERMINATE && duration > 0) {
- double elapsed = now() - progressScopeTime;
- float p = 1.0 * elapsed / duration;
- if (p > 1.0) p = 1.0;
- if (p > progress) {
- progress = p;
redraw = true;
}
- }
- if (redraw) update_progress_locked();
+ // move the progress bar forward on timed intervals, if configured
+ int duration = progressScopeDuration;
+ if (progressBarType == DETERMINATE && duration > 0) {
+ double elapsed = now() - progressScopeTime;
+ float p = 1.0 * elapsed / duration;
+ if (p > 1.0) p = 1.0;
+ if (p > progress) {
+ progress = p;
+ redraw = true;
+ }
+ }
+
+ if (redraw) update_progress_locked();
+ }
- pthread_mutex_unlock(&updateMutex);
double end = now();
// minimum of 20ms delay between frames
double delay = interval - (end - start);
@@ -749,7 +746,8 @@ bool ScreenRecoveryUI::Init(const std::string& locale) {
LoadAnimation();
- pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);
+ // Keep the progress bar updated, even when the process is otherwise busy.
+ progress_thread_ = std::thread(&ScreenRecoveryUI::ProgressThreadLoop, this);
return true;
}
@@ -797,16 +795,14 @@ void ScreenRecoveryUI::LoadAnimation() {
}
void ScreenRecoveryUI::SetBackground(Icon icon) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
currentIcon = icon;
update_screen_locked();
-
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::SetProgressType(ProgressType type) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (progressBarType != type) {
progressBarType = type;
}
@@ -814,11 +810,10 @@ void ScreenRecoveryUI::SetProgressType(ProgressType type) {
progressScopeSize = 0;
progress = 0;
update_progress_locked();
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::ShowProgress(float portion, float seconds) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
progressBarType = DETERMINATE;
progressScopeStart += progressScopeSize;
progressScopeSize = portion;
@@ -826,11 +821,10 @@ void ScreenRecoveryUI::ShowProgress(float portion, float seconds) {
progressScopeDuration = seconds;
progress = 0;
update_progress_locked();
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::SetProgress(float fraction) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (fraction < 0.0) fraction = 0.0;
if (fraction > 1.0) fraction = 1.0;
if (progressBarType == DETERMINATE && fraction > progress) {
@@ -842,14 +836,12 @@ void ScreenRecoveryUI::SetProgress(float fraction) {
update_progress_locked();
}
}
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::SetStage(int current, int max) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
stage = current;
max_stage = max;
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
@@ -860,7 +852,7 @@ void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap)
fputs(str.c_str(), stdout);
}
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (text_rows_ > 0 && text_cols_ > 0) {
for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
if (*ptr == '\n' || text_col_ >= text_cols_) {
@@ -873,7 +865,6 @@ void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap)
text_[text_row_][text_col_] = '\0';
update_screen_locked();
}
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::Print(const char* fmt, ...) {
@@ -891,23 +882,21 @@ void ScreenRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) {
}
void ScreenRecoveryUI::PutChar(char ch) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (ch != '\n') text_[text_row_][text_col_++] = ch;
if (ch == '\n' || text_col_ >= text_cols_) {
text_col_ = 0;
++text_row_;
}
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::ClearText() {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
text_col_ = 0;
text_row_ = 0;
for (size_t i = 0; i < text_rows_; ++i) {
memset(text_[i], 0, text_cols_ + 1);
}
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::ShowFile(FILE* fp) {
@@ -984,17 +973,16 @@ void ScreenRecoveryUI::ShowFile(const std::string& filename) {
void ScreenRecoveryUI::StartMenu(const std::vector<std::string>& headers,
const std::vector<std::string>& items, size_t initial_selection) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (text_rows_ > 0 && text_cols_ > 1) {
menu_ = std::make_unique<Menu>(scrollable_menu_, text_rows_, text_cols_ - 1, headers, items,
initial_selection);
update_screen_locked();
}
- pthread_mutex_unlock(&updateMutex);
}
int ScreenRecoveryUI::SelectMenu(int sel) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (menu_) {
int old_sel = menu_->selection();
sel = menu_->Select(sel);
@@ -1003,17 +991,15 @@ int ScreenRecoveryUI::SelectMenu(int sel) {
update_screen_locked();
}
}
- pthread_mutex_unlock(&updateMutex);
return sel;
}
void ScreenRecoveryUI::EndMenu() {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
if (menu_) {
menu_.reset();
update_screen_locked();
}
- pthread_mutex_unlock(&updateMutex);
}
size_t ScreenRecoveryUI::ShowMenu(const std::vector<std::string>& headers,
@@ -1065,31 +1051,27 @@ size_t ScreenRecoveryUI::ShowMenu(const std::vector<std::string>& headers,
}
bool ScreenRecoveryUI::IsTextVisible() {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
int visible = show_text;
- pthread_mutex_unlock(&updateMutex);
return visible;
}
bool ScreenRecoveryUI::WasTextEverVisible() {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
int ever_visible = show_text_ever;
- pthread_mutex_unlock(&updateMutex);
return ever_visible;
}
void ScreenRecoveryUI::ShowText(bool visible) {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
show_text = visible;
if (show_text) show_text_ever = true;
update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::Redraw() {
- pthread_mutex_lock(&updateMutex);
+ std::lock_guard<std::mutex> lg(updateMutex);
update_screen_locked();
- pthread_mutex_unlock(&updateMutex);
}
void ScreenRecoveryUI::KeyLongPress(int) {