source: mainline/uspace/app/barber/barber.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2014 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup barber
30 * @{
31 */
32/** @file
33 */
34
35#include <stdbool.h>
36#include <errno.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <task.h>
40#include <loc.h>
41#include <stats.h>
42#include <fibril_synch.h>
43#include <io/pixel.h>
44#include <device/led_dev.h>
45#include <window.h>
46#include <canvas.h>
47#include <surface.h>
48#include <codec/tga.gz.h>
49#include "images.h"
50
51#define NAME "barber"
52
53#define FRAMES IMAGES
54
55#define MIN_FPS 1
56#define MAX_FPS 25
57
58#define MIN_LOAD (LOAD_UNIT / 4)
59#define MAX_LOAD (LOAD_UNIT / 3)
60
61#define FRAME_WIDTH 59
62#define FRAME_HEIGHT 192
63
64#define LED_PERIOD 1000000
65#define LED_COLORS 7
66
67typedef struct {
68 link_t link;
69 service_id_t svc_id;
70 async_sess_t *sess;
71} led_dev_t;
72
73static char *winreg = NULL;
74
75static fibril_timer_t *led_timer = NULL;
76static list_t led_devs;
77static unsigned int led_color = 0;
78
79static pixel_t led_colors[LED_COLORS] = {
80 PIXEL(0xff, 0xff, 0x00, 0x00),
81 PIXEL(0xff, 0x00, 0xff, 0x00),
82 PIXEL(0xff, 0x00, 0x00, 0xff),
83 PIXEL(0xff, 0xff, 0xff, 0x00),
84 PIXEL(0xff, 0xff, 0x00, 0xff),
85 PIXEL(0xff, 0x00, 0xff, 0xff),
86 PIXEL(0xff, 0xff, 0xff, 0xff)
87};
88
89static fibril_timer_t *frame_timer = NULL;
90static canvas_t *frame_canvas;
91static surface_t *frames[FRAMES];
92
93static unsigned int frame = 0;
94static unsigned int fps = MIN_FPS;
95
96static void led_timer_callback(void *);
97static void frame_timer_callback(void *);
98
99static bool decode_frames(void)
100{
101 for (unsigned int i = 0; i < FRAMES; i++) {
102 frames[i] = decode_tga_gz(images[i].addr, images[i].size, 0);
103 if (frames[i] == NULL) {
104 printf("Unable to decode frame %u.\n", i);
105 return false;
106 }
107 }
108
109 return true;
110}
111
112static void plan_led_timer(void)
113{
114 fibril_timer_set(led_timer, LED_PERIOD, led_timer_callback, NULL);
115}
116
117static load_t get_load(void)
118{
119 size_t count;
120 load_t *load = stats_get_load(&count);
121 load_t load_val;
122
123 if ((load != NULL) && (count > 0)) {
124 load_val = load[0];
125 free(load);
126 } else
127 load_val = 0;
128
129 return load_val;
130}
131
132static void plan_frame_timer(suseconds_t render_time)
133{
134 /*
135 * Crank up the FPS unless we lack
136 * behind with the rendering and
137 * unless the load is not above
138 * a lower threshold.
139 */
140
141 suseconds_t delta = 1000000 / fps;
142 load_t load = get_load();
143
144 if ((delta >= render_time) && (load < MIN_LOAD))
145 fps++;
146
147 if (fps > MAX_FPS)
148 fps = MAX_FPS;
149
150 /*
151 * If we lack behind then immediately
152 * go to the lowest FPS.
153 */
154
155 if (delta < render_time)
156 fps = MIN_FPS;
157
158 /*
159 * Crank down the FPS if the current
160 * load is above an upper threshold.
161 */
162
163 if (load > MAX_LOAD)
164 fps--;
165
166 if (fps < MIN_FPS)
167 fps = MIN_FPS;
168
169 delta = 1000000 / fps;
170
171 fibril_timer_set(frame_timer, delta, frame_timer_callback, NULL);
172}
173
174static void led_timer_callback(void *data)
175{
176 pixel_t next_led_color = led_colors[led_color];
177
178 led_color++;
179 if (led_color >= LED_COLORS)
180 led_color = 0;
181
182 list_foreach(led_devs, link, led_dev_t, dev) {
183 if (dev->sess)
184 led_dev_color_set(dev->sess, next_led_color);
185 }
186
187 plan_led_timer();
188}
189
190static void frame_timer_callback(void *data)
191{
192 struct timeval prev;
193 getuptime(&prev);
194
195 frame++;
196 if (frame >= FRAMES)
197 frame = 0;
198
199 update_canvas(frame_canvas, frames[frame]);
200
201 struct timeval cur;
202 getuptime(&cur);
203
204 plan_frame_timer(tv_sub_diff(&cur, &prev));
205}
206
207static void loc_callback(void)
208{
209 category_id_t led_cat;
210 errno_t rc = loc_category_get_id("led", &led_cat, IPC_FLAG_BLOCKING);
211 if (rc != EOK)
212 return;
213
214 service_id_t *svcs;
215 size_t count;
216 rc = loc_category_get_svcs(led_cat, &svcs, &count);
217 if (rc != EOK)
218 return;
219
220 for (size_t i = 0; i < count; i++) {
221 bool known = false;
222
223 /* Determine whether we already know this device. */
224 list_foreach(led_devs, link, led_dev_t, dev) {
225 if (dev->svc_id == svcs[i]) {
226 known = true;
227 break;
228 }
229 }
230
231 if (!known) {
232 led_dev_t *dev = (led_dev_t *) calloc(1, sizeof(led_dev_t));
233 if (!dev)
234 continue;
235
236 link_initialize(&dev->link);
237 dev->svc_id = svcs[i];
238 dev->sess = loc_service_connect(svcs[i], INTERFACE_DDF, 0);
239
240 list_append(&dev->link, &led_devs);
241 }
242 }
243
244 // FIXME: Handle LED device removal
245
246 free(svcs);
247}
248
249int main(int argc, char *argv[])
250{
251 if (argc < 2) {
252 printf("Compositor server not specified.\n");
253 return 1;
254 }
255
256 list_initialize(&led_devs);
257 errno_t rc = loc_register_cat_change_cb(loc_callback);
258 if (rc != EOK) {
259 printf("Unable to register callback for device discovery.\n");
260 return 1;
261 }
262
263 led_timer = fibril_timer_create(NULL);
264 if (!led_timer) {
265 printf("Unable to create LED timer.\n");
266 return 1;
267 }
268
269 frame_timer = fibril_timer_create(NULL);
270 if (!frame_timer) {
271 printf("Unable to create frame timer.\n");
272 return 1;
273 }
274
275 if (!decode_frames())
276 return 1;
277
278 winreg = argv[1];
279 window_t *main_window = window_open(argv[1], NULL,
280 WINDOW_MAIN | WINDOW_DECORATED, "barber");
281 if (!main_window) {
282 printf("Cannot open main window.\n");
283 return 1;
284 }
285
286 frame_canvas = create_canvas(window_root(main_window), NULL,
287 FRAME_WIDTH, FRAME_HEIGHT, frames[frame]);
288
289 if (!frame_canvas) {
290 window_close(main_window);
291 printf("Cannot create widgets.\n");
292 return 1;
293 }
294
295 window_resize(main_window, 0, 0, FRAME_WIDTH + 8, FRAME_HEIGHT + 28,
296 WINDOW_PLACEMENT_RIGHT | WINDOW_PLACEMENT_BOTTOM);
297 window_exec(main_window);
298
299 plan_led_timer();
300 plan_frame_timer(0);
301
302 task_retval(0);
303 async_manager();
304
305 return 0;
306}
307
308/** @}
309 */
Note: See TracBrowser for help on using the repository browser.