diff --git a/recovery.cpp b/recovery.cpp index 6ced420d013b65163ac3252ed80d938cd0523622..3b58138766b9fb6da19d0af759d6ba1248de5afc 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -781,7 +781,7 @@ load_locale_from_cache() { if (fp != NULL) { fgets(buffer, sizeof(buffer), fp); int j = 0; - int i; + unsigned int i; for (i = 0; i < sizeof(buffer) && buffer[i]; ++i) { if (!isspace(buffer[i])) { buffer[j++] = buffer[i]; @@ -849,6 +849,7 @@ main(int argc, char **argv) { ui = device->GetUI(); ui->Init(); + ui->SetLocale(locale); ui->SetBackground(RecoveryUI::NONE); if (show_text) ui->ShowText(true); diff --git a/res/images/erasing_text.png b/res/images/erasing_text.png index 2cd2e382515bbe6fefd2affe934b000a48db3be5..8b9f265fb570af8e0e15d40829ce4796309608a5 100644 Binary files a/res/images/erasing_text.png and b/res/images/erasing_text.png differ diff --git a/res/images/error_text.png b/res/images/error_text.png index 91be5fe5424dc6fbc440fca5904c492e07e5c27f..b64b3d7acafca7781252b8da589974f77e2560d0 100644 Binary files a/res/images/error_text.png and b/res/images/error_text.png differ diff --git a/res/images/installing_text.png b/res/images/installing_text.png index 42704b9965f544f57c7916f444dfde22119ca046..9c16c7708e5ea7b81ff0e6f8e468dea0851be6bc 100644 Binary files a/res/images/installing_text.png and b/res/images/installing_text.png differ diff --git a/res/images/no_command_text.png b/res/images/no_command_text.png index fbc20743f9ff95e51854e9d35d68bb0f93108471..2241259e2be5998c183f4727c5d3dbb74867e633 100644 Binary files a/res/images/no_command_text.png and b/res/images/no_command_text.png differ diff --git a/screen_ui.cpp b/screen_ui.cpp index 0b343754743994fa414ab69cbd4b6414d61c13a6..64a5dcdd2cd0efac09b93898bbcce1e4929adcd0 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -52,6 +52,7 @@ static double now() { ScreenRecoveryUI::ScreenRecoveryUI() : currentIcon(NONE), installingFrame(0), + rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), @@ -158,18 +159,35 @@ void ScreenRecoveryUI::draw_progress_locked() float p = progressScopeStart + progress * progressScopeSize; int pos = (int) (p * width); - if (pos > 0) { - gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); - } - if (pos < width-1) { - gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); + if (rtl_locale) { + // Fill the progress bar from right to left. + if (pos > 0) { + gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); + } + if (pos < width-1) { + gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); + } + } else { + // Fill the progress bar from left to right. + if (pos > 0) { + gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); + } + if (pos < width-1) { + gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); + } } } if (progressBarType == INDETERMINATE) { static int frame = 0; gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); - frame = (frame + 1) % indeterminate_frames; + // in RTL locales, we run the animation backwards, which + // makes the spinner spin the other way. + if (rtl_locale) { + frame = (frame + indeterminate_frames - 1) % indeterminate_frames; + } else { + frame = (frame + 1) % indeterminate_frames; + } } } } @@ -360,6 +378,28 @@ void ScreenRecoveryUI::Init() RecoveryUI::Init(); } +void ScreenRecoveryUI::SetLocale(const char* locale) { + if (locale) { + char* lang = strdup(locale); + for (char* p = lang; *p; ++p) { + if (*p == '_') { + *p = '\0'; + break; + } + } + + // A bit cheesy: keep an explicit list of supported languages + // that are RTL. + if (strcmp(lang, "ar") == 0 || // Arabic + strcmp(lang, "fa") == 0 || // Persian (Farsi) + strcmp(lang, "he") == 0 || // Hebrew (new language code) + strcmp(lang, "iw") == 0) { // Hebrew (old language code) + rtl_locale = true; + } + free(lang); + } +} + void ScreenRecoveryUI::SetBackground(Icon icon) { pthread_mutex_lock(&updateMutex); diff --git a/screen_ui.h b/screen_ui.h index 16ee741b7959a57d0d3130070b85074c01be622d..80051724b78a7d6819757cc08af28a81d0a2e440 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -29,6 +29,7 @@ class ScreenRecoveryUI : public RecoveryUI { ScreenRecoveryUI(); void Init(); + void SetLocale(const char* locale); // overall recovery state ("background image") void SetBackground(Icon icon); @@ -55,6 +56,7 @@ class ScreenRecoveryUI : public RecoveryUI { private: Icon currentIcon; int installingFrame; + bool rtl_locale; pthread_mutex_t updateMutex; gr_surface backgroundIcon[5]; diff --git a/ui.h b/ui.h index ccbb466ac658e2cd67656ad76a1ec56f3dc2a605..acb57663e607feb7a9d8702bc68ac7422c3a6092 100644 --- a/ui.h +++ b/ui.h @@ -30,6 +30,9 @@ class RecoveryUI { // Initialize the object; called before anything else. virtual void Init(); + // After calling Init(), you can tell the UI what locale it is operating in. + virtual void SetLocale(const char* locale) { } + // Set the overall recovery state ("background image"). enum Icon { NONE, INSTALLING_UPDATE, ERASING, NO_COMMAND, ERROR }; virtual void SetBackground(Icon icon) = 0;