diff options
Diffstat (limited to 'healthd/healthd_draw.cpp')
-rw-r--r-- | healthd/healthd_draw.cpp | 212 |
1 files changed, 117 insertions, 95 deletions
diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp index ea3d991c0..30f2cf3be 100644 --- a/healthd/healthd_draw.cpp +++ b/healthd/healthd_draw.cpp | |||
@@ -21,77 +21,96 @@ | |||
21 | #include "healthd_draw.h" | 21 | #include "healthd_draw.h" |
22 | 22 | ||
23 | #define LOGE(x...) KLOG_ERROR("charger", x); | 23 | #define LOGE(x...) KLOG_ERROR("charger", x); |
24 | #define LOGW(x...) KLOG_WARNING("charger", x); | ||
24 | #define LOGV(x...) KLOG_DEBUG("charger", x); | 25 | #define LOGV(x...) KLOG_DEBUG("charger", x); |
25 | 26 | ||
26 | HealthdDraw::HealthdDraw(animation* anim) | 27 | HealthdDraw::HealthdDraw(animation* anim) |
27 | : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), | 28 | : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), |
28 | kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { | 29 | kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { |
29 | gr_init(); | 30 | int ret = gr_init(); |
30 | gr_font_size(gr_sys_font(), &char_width_, &char_height_); | 31 | |
31 | 32 | if (ret < 0) { | |
32 | screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1); | 33 | LOGE("gr_init failed\n"); |
33 | screen_height_ = gr_fb_height(); | 34 | graphics_available = false; |
34 | 35 | return; | |
35 | int res; | 36 | } |
36 | if (!anim->text_clock.font_file.empty() && | 37 | |
37 | (res = gr_init_font(anim->text_clock.font_file.c_str(), | 38 | graphics_available = true; |
38 | &anim->text_clock.font)) < 0) { | 39 | sys_font = gr_sys_font(); |
39 | LOGE("Could not load time font (%d)\n", res); | 40 | if (sys_font == nullptr) { |
40 | } | 41 | LOGW("No system font, screen fallback text not available\n"); |
41 | if (!anim->text_percent.font_file.empty() && | 42 | } else { |
42 | (res = gr_init_font(anim->text_percent.font_file.c_str(), | 43 | gr_font_size(sys_font, &char_width_, &char_height_); |
43 | &anim->text_percent.font)) < 0) { | 44 | } |
44 | LOGE("Could not load percent font (%d)\n", res); | 45 | |
45 | } | 46 | screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1); |
47 | screen_height_ = gr_fb_height(); | ||
48 | |||
49 | int res; | ||
50 | if (!anim->text_clock.font_file.empty() && | ||
51 | (res = gr_init_font(anim->text_clock.font_file.c_str(), &anim->text_clock.font)) < 0) { | ||
52 | LOGE("Could not load time font (%d)\n", res); | ||
53 | } | ||
54 | if (!anim->text_percent.font_file.empty() && | ||
55 | (res = gr_init_font(anim->text_percent.font_file.c_str(), &anim->text_percent.font)) < 0) { | ||
56 | LOGE("Could not load percent font (%d)\n", res); | ||
57 | } | ||
46 | } | 58 | } |
47 | 59 | ||
48 | HealthdDraw::~HealthdDraw() {} | 60 | HealthdDraw::~HealthdDraw() {} |
49 | 61 | ||
50 | void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { | 62 | void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { |
51 | clear_screen(); | 63 | if (!graphics_available) return; |
52 | 64 | clear_screen(); | |
53 | /* try to display *something* */ | 65 | |
54 | if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) | 66 | /* try to display *something* */ |
55 | draw_unknown(surf_unknown); | 67 | if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) |
56 | else | 68 | draw_unknown(surf_unknown); |
57 | draw_battery(batt_anim); | 69 | else |
58 | gr_flip(); | 70 | draw_battery(batt_anim); |
71 | gr_flip(); | ||
59 | } | 72 | } |
60 | 73 | ||
61 | void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); } | 74 | void HealthdDraw::blank_screen(bool blank) { |
75 | if (!graphics_available) return; | ||
76 | gr_fb_blank(blank); | ||
77 | } | ||
62 | 78 | ||
63 | void HealthdDraw::clear_screen(void) { | 79 | void HealthdDraw::clear_screen(void) { |
64 | gr_color(0, 0, 0, 255); | 80 | if (!graphics_available) return; |
65 | gr_clear(); | 81 | gr_color(0, 0, 0, 255); |
82 | gr_clear(); | ||
66 | } | 83 | } |
67 | 84 | ||
68 | int HealthdDraw::draw_surface_centered(GRSurface* surface) { | 85 | int HealthdDraw::draw_surface_centered(GRSurface* surface) { |
69 | int w = gr_get_width(surface); | 86 | if (!graphics_available) return 0; |
70 | int h = gr_get_height(surface); | 87 | |
71 | int x = (screen_width_ - w) / 2 + kSplitOffset; | 88 | int w = gr_get_width(surface); |
72 | int y = (screen_height_ - h) / 2; | 89 | int h = gr_get_height(surface); |
73 | 90 | int x = (screen_width_ - w) / 2 + kSplitOffset; | |
74 | LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); | 91 | int y = (screen_height_ - h) / 2; |
75 | gr_blit(surface, 0, 0, w, h, x, y); | 92 | |
76 | if (kSplitScreen) { | ||
77 | x += screen_width_ - 2 * kSplitOffset; | ||
78 | LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); | 93 | LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); |
79 | gr_blit(surface, 0, 0, w, h, x, y); | 94 | gr_blit(surface, 0, 0, w, h, x, y); |
80 | } | 95 | if (kSplitScreen) { |
96 | x += screen_width_ - 2 * kSplitOffset; | ||
97 | LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); | ||
98 | gr_blit(surface, 0, 0, w, h, x, y); | ||
99 | } | ||
81 | 100 | ||
82 | return y + h; | 101 | return y + h; |
83 | } | 102 | } |
84 | 103 | ||
85 | int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) { | 104 | int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) { |
86 | int str_len_px = gr_measure(font, str); | 105 | if (!graphics_available) return 0; |
106 | int str_len_px = gr_measure(font, str); | ||
87 | 107 | ||
88 | if (x < 0) x = (screen_width_ - str_len_px) / 2; | 108 | if (x < 0) x = (screen_width_ - str_len_px) / 2; |
89 | if (y < 0) y = (screen_height_ - char_height_) / 2; | 109 | if (y < 0) y = (screen_height_ - char_height_) / 2; |
90 | gr_text(font, x + kSplitOffset, y, str, false /* bold */); | 110 | gr_text(font, x + kSplitOffset, y, str, false /* bold */); |
91 | if (kSplitScreen) | 111 | if (kSplitScreen) gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */); |
92 | gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */); | ||
93 | 112 | ||
94 | return y + char_height_; | 113 | return y + char_height_; |
95 | } | 114 | } |
96 | 115 | ||
97 | void HealthdDraw::determine_xy(const animation::text_field& field, | 116 | void HealthdDraw::determine_xy(const animation::text_field& field, |
@@ -119,77 +138,80 @@ void HealthdDraw::determine_xy(const animation::text_field& field, | |||
119 | } | 138 | } |
120 | 139 | ||
121 | void HealthdDraw::draw_clock(const animation* anim) { | 140 | void HealthdDraw::draw_clock(const animation* anim) { |
122 | static constexpr char CLOCK_FORMAT[] = "%H:%M"; | 141 | static constexpr char CLOCK_FORMAT[] = "%H:%M"; |
123 | static constexpr int CLOCK_LENGTH = 6; | 142 | static constexpr int CLOCK_LENGTH = 6; |
124 | 143 | ||
125 | const animation::text_field& field = anim->text_clock; | 144 | const animation::text_field& field = anim->text_clock; |
126 | 145 | ||
127 | if (field.font == nullptr || field.font->char_width == 0 || | 146 | if (!graphics_available || field.font == nullptr || field.font->char_width == 0 || |
128 | field.font->char_height == 0) | 147 | field.font->char_height == 0) |
129 | return; | 148 | return; |
130 | 149 | ||
131 | time_t rawtime; | 150 | time_t rawtime; |
132 | time(&rawtime); | 151 | time(&rawtime); |
133 | tm* time_info = localtime(&rawtime); | 152 | tm* time_info = localtime(&rawtime); |
134 | 153 | ||
135 | char clock_str[CLOCK_LENGTH]; | 154 | char clock_str[CLOCK_LENGTH]; |
136 | size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); | 155 | size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); |
137 | if (length != CLOCK_LENGTH - 1) { | 156 | if (length != CLOCK_LENGTH - 1) { |
138 | LOGE("Could not format time\n"); | 157 | LOGE("Could not format time\n"); |
139 | return; | 158 | return; |
140 | } | 159 | } |
141 | 160 | ||
142 | int x, y; | 161 | int x, y; |
143 | determine_xy(field, length, &x, &y); | 162 | determine_xy(field, length, &x, &y); |
144 | 163 | ||
145 | LOGV("drawing clock %s %d %d\n", clock_str, x, y); | 164 | LOGV("drawing clock %s %d %d\n", clock_str, x, y); |
146 | gr_color(field.color_r, field.color_g, field.color_b, field.color_a); | 165 | gr_color(field.color_r, field.color_g, field.color_b, field.color_a); |
147 | draw_text(field.font, x, y, clock_str); | 166 | draw_text(field.font, x, y, clock_str); |
148 | } | 167 | } |
149 | 168 | ||
150 | void HealthdDraw::draw_percent(const animation* anim) { | 169 | void HealthdDraw::draw_percent(const animation* anim) { |
151 | int cur_level = anim->cur_level; | 170 | if (!graphics_available) return; |
152 | if (anim->cur_status == BATTERY_STATUS_FULL) { | 171 | int cur_level = anim->cur_level; |
153 | cur_level = 100; | 172 | if (anim->cur_status == BATTERY_STATUS_FULL) { |
154 | } | 173 | cur_level = 100; |
174 | } | ||
155 | 175 | ||
156 | if (cur_level <= 0) return; | 176 | if (cur_level <= 0) return; |
157 | 177 | ||
158 | const animation::text_field& field = anim->text_percent; | 178 | const animation::text_field& field = anim->text_percent; |
159 | if (field.font == nullptr || field.font->char_width == 0 || | 179 | if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) { |
160 | field.font->char_height == 0) { | 180 | return; |
161 | return; | 181 | } |
162 | } | ||
163 | 182 | ||
164 | std::string str = base::StringPrintf("%d%%", cur_level); | 183 | std::string str = base::StringPrintf("%d%%", cur_level); |
165 | 184 | ||
166 | int x, y; | 185 | int x, y; |
167 | determine_xy(field, str.size(), &x, &y); | 186 | determine_xy(field, str.size(), &x, &y); |
168 | 187 | ||
169 | LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); | 188 | LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); |
170 | gr_color(field.color_r, field.color_g, field.color_b, field.color_a); | 189 | gr_color(field.color_r, field.color_g, field.color_b, field.color_a); |
171 | draw_text(field.font, x, y, str.c_str()); | 190 | draw_text(field.font, x, y, str.c_str()); |
172 | } | 191 | } |
173 | 192 | ||
174 | void HealthdDraw::draw_battery(const animation* anim) { | 193 | void HealthdDraw::draw_battery(const animation* anim) { |
175 | const animation::frame& frame = anim->frames[anim->cur_frame]; | 194 | if (!graphics_available) return; |
176 | 195 | const animation::frame& frame = anim->frames[anim->cur_frame]; | |
177 | if (anim->num_frames != 0) { | 196 | |
178 | draw_surface_centered(frame.surface); | 197 | if (anim->num_frames != 0) { |
179 | LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, | 198 | draw_surface_centered(frame.surface); |
180 | frame.min_level, frame.disp_time); | 199 | LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, frame.min_level, |
181 | } | 200 | frame.disp_time); |
182 | draw_clock(anim); | 201 | } |
183 | draw_percent(anim); | 202 | draw_clock(anim); |
203 | draw_percent(anim); | ||
184 | } | 204 | } |
185 | 205 | ||
186 | void HealthdDraw::draw_unknown(GRSurface* surf_unknown) { | 206 | void HealthdDraw::draw_unknown(GRSurface* surf_unknown) { |
187 | int y; | 207 | int y; |
188 | if (surf_unknown) { | 208 | if (surf_unknown) { |
189 | draw_surface_centered(surf_unknown); | 209 | draw_surface_centered(surf_unknown); |
210 | } else if (sys_font) { | ||
211 | gr_color(0xa4, 0xc6, 0x39, 255); | ||
212 | y = draw_text(sys_font, -1, -1, "Charging!"); | ||
213 | draw_text(sys_font, -1, y + 25, "?\?/100"); | ||
190 | } else { | 214 | } else { |
191 | gr_color(0xa4, 0xc6, 0x39, 255); | 215 | LOGW("Charging, level unknown\n"); |
192 | y = draw_text(gr_sys_font(), -1, -1, "Charging!"); | ||
193 | draw_text(gr_sys_font(), -1, y + 25, "?\?/100"); | ||
194 | } | 216 | } |
195 | } | 217 | } |