From dab91fe9ec6ecddea2e3f6f46d207263b58d7982 Mon Sep 17 00:00:00 2001 From: Anton Staaf Date: Wed, 10 Sep 2014 12:33:58 -0700 Subject: extra: Move lightbar simulator into subdirectory This clears the top level extra directory for additional extras. Signed-off-by: Anton Staaf BRANCH=None BUG=None TEST=cd extra/lightbar; make; lightbar Change-Id: If05a768e4d33cbf21b2ce47a056c960a95728558 Reviewed-on: https://chromium-review.googlesource.com/217537 Tested-by: Anton Staaf Reviewed-by: Bill Richardson Commit-Queue: Anton Staaf --- extra/lightbar/.gitignore | 1 + extra/lightbar/Makefile | 28 +++++ extra/lightbar/README | 39 ++++++ extra/lightbar/input.c | 80 ++++++++++++ extra/lightbar/main.c | 292 +++++++++++++++++++++++++++++++++++++++++++ extra/lightbar/simulation.h | 114 +++++++++++++++++ extra/lightbar/windows.c | 294 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 848 insertions(+) create mode 100644 extra/lightbar/.gitignore create mode 100644 extra/lightbar/Makefile create mode 100644 extra/lightbar/README create mode 100644 extra/lightbar/input.c create mode 100644 extra/lightbar/main.c create mode 100644 extra/lightbar/simulation.h create mode 100644 extra/lightbar/windows.c (limited to 'extra/lightbar') diff --git a/extra/lightbar/.gitignore b/extra/lightbar/.gitignore new file mode 100644 index 0000000000..964154302a --- /dev/null +++ b/extra/lightbar/.gitignore @@ -0,0 +1 @@ +lightbar diff --git a/extra/lightbar/Makefile b/extra/lightbar/Makefile new file mode 100644 index 0000000000..920483b781 --- /dev/null +++ b/extra/lightbar/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +PROG= lightbar +HEADERS= simulation.h +SRCS= main.c windows.c input.c ../../common/lightbar.c + +# comment this out if you don't have libreadline installed +HAS_GNU_READLINE=1 + +INCLUDE= -I. -I../../include +CFLAGS= -g -Wall -Werror -pthread ${INCLUDE} -DLIGHTBAR_SIMULATION +LDFLAGS = -lX11 -lxcb -lrt + +ifneq ($(HAS_GNU_READLINE),) +CFLAGS += -DHAS_GNU_READLINE +LDFLAGS += -lreadline +endif + +all: ${PROG} + +${PROG} : ${SRCS} ${HEADERS} Makefile + gcc ${CFLAGS} ${SRCS} ${LDFLAGS} -o ${PROG} + +.PHONY: clean +clean: + rm -f ${PROG} diff --git a/extra/lightbar/README b/extra/lightbar/README new file mode 100644 index 0000000000..1862f922e4 --- /dev/null +++ b/extra/lightbar/README @@ -0,0 +1,39 @@ +Lightbar simulator +------------------------------------------------------------------------------ + +Build with "make lightbar". The executable is "./lightbar". + +You may need to install libxcb1-dev or similar. + +This provides a simulation environment for the lightbar task, compiling +common/lightbar.c from the EC source, but faking the rest of the EC. + +The EC console is on stdin/stdout, delivering all input to the lightbar's +console command handler (so it prefixes any input with "lightbar"). The +lightbar itself is displayed in an X window. You can click in that window to +emulate changes to the battery level, AC connection, and brightness, all of +which are normally outside the lightbar task's direct control. + +The initial sequence is "S5". Try issuing the command "seq s3s0" to see +something more familiar. + + +Note: the Pixel lightbar circuitry has three modes of operation: + +Unpowered + + When the host CPU is off (S5/G3), all power to the lightbar and its + controller circuitry is lost. + +On + + When the host CPU is on (S0) or suspended (S3), the lightbar is powered + again. After every power loss, it will need to be reinitialized by calling + lb_init() before it can be used. + +Standby + + The lightbar controller ICs can turn off all the LED outputs to conserve + power. This is the initial state when power is applied. You can turn the + LEDs off manually by calling lb_off(). When suspended, the controller will + respond to commands, but the LEDs aren't lit. Turn them on with lb_on(). diff --git a/extra/lightbar/input.c b/extra/lightbar/input.c new file mode 100644 index 0000000000..fe4f7cd19f --- /dev/null +++ b/extra/lightbar/input.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include +#include +#include +#include +#include + +#include "simulation.h" + +#ifdef HAS_GNU_READLINE +#include +#include + +char *get_input(const char *prompt) +{ + static char *line; + + if (line) { + free(line); + line = 0; + } + + line = readline(prompt); + + if (line && *line) + add_history(line); + + return line; +} + +#else /* no readline */ + +char *get_input(const char *prompt) +{ + static char mybuf[80]; + char *got; + printf("%s", prompt); + got = fgets(mybuf, sizeof(mybuf), stdin); + return got; +} + +#endif /* HAS_GNU_READLINE */ + +void *entry_input(void *ptr) +{ + char *got, buf[80]; + char *str, *word, *saveptr; + int argc; + char *argv[40]; + int ret; + + do { + got = get_input("lightbar% "); + if (got) { + strcpy(buf, got); + argc = 0; + argv[argc++] = "lightbar"; + word = str = buf; + while (word && argc < ARRAY_SIZE(argv)) { + word = strtok_r(str, " \t\r\n", &saveptr); + if (word) + argv[argc++] = word; + str = 0; + } + argv[argc] = 0; + ret = fake_consolecmd_lightbar(argc, argv); + if (ret) + printf("ERROR %d\n", ret); + } + + } while (got); + + exit(0); + + return 0; +} diff --git a/extra/lightbar/main.c b/extra/lightbar/main.c new file mode 100644 index 0000000000..38234e743c --- /dev/null +++ b/extra/lightbar/main.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "simulation.h" + +static void *(*thread_fns[])(void *) = { + entry_windows, + entry_lightbar, + entry_input, +}; + +int main(int argc, char *argv[]) +{ + int i; + pthread_t thread[ARRAY_SIZE(thread_fns)]; + + printf("\nLook at the README file.\n"); + printf("Click in the window.\n"); + printf("Type \"help\" for commands.\n\n"); + fflush(stdout); + + init_windows(); + + for (i = 0; i < ARRAY_SIZE(thread_fns); i++) + assert(0 == pthread_create(&thread[i], NULL, thread_fns[i], 0)); + + for (i = 0; i < ARRAY_SIZE(thread_fns); i++) + pthread_join(thread[i], NULL); + + return 0; +} + +void *entry_lightbar(void *ptr) +{ + lightbar_task(); + return 0; +} + +/****************************************************************************/ +/* Fake functions. We only have to implement enough for lightbar.c */ + +/* timespec uses nanoseconds */ +#define TS_USEC 1000L +#define TS_MSEC 1000000L +#define TS_SEC 1000000000L + +static void timespec_incr(struct timespec *v, time_t secs, long nsecs) +{ + v->tv_sec += secs; + /* The nanosecond sum won't overflow, but might have a carry. */ + v->tv_nsec += nsecs; + v->tv_sec += v->tv_nsec / TS_SEC; + v->tv_nsec %= TS_SEC; +} + + +static pthread_mutex_t task_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t task_cond = PTHREAD_COND_INITIALIZER; +static uint32_t task_event; + +uint32_t task_wait_event(int timeout_us) +{ + struct timespec t; + uint32_t event; + + pthread_mutex_lock(&task_mutex); + + if (timeout_us > 0) { + clock_gettime(CLOCK_REALTIME, &t); + timespec_incr(&t, timeout_us / SECOND, timeout_us * TS_USEC); + + if (ETIMEDOUT == pthread_cond_timedwait(&task_cond, + &task_mutex, &t)) + task_event |= TASK_EVENT_TIMER; + } else { + pthread_cond_wait(&task_cond, &task_mutex); + } + + pthread_mutex_unlock(&task_mutex); + event = task_event; + task_event = 0; + return event; +} + +uint32_t task_set_event(task_id_t tskid, /* always LIGHTBAR */ + uint32_t event, + int wait_for_reply) /* always 0 */ +{ + pthread_mutex_lock(&task_mutex); + task_event = event; + pthread_cond_signal(&task_cond); + pthread_mutex_unlock(&task_mutex); + return 0; +} + + + +/* Stubbed functions */ + +void cprintf(int zero, const char *fmt, ...) +{ + va_list ap; + char *s; + char *newfmt = strdup(fmt); + + for (s = newfmt; *s; s++) + if (*s == '%' && s[1] == 'T') + *s = 'T'; + + va_start(ap, fmt); + vprintf(newfmt, ap); + va_end(ap); + + free(newfmt); +} + +void cprints(int zero, const char *fmt, ...) +{ + va_list ap; + + printf("[TT "); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("]\n"); +} + +timestamp_t get_time(void) +{ + static struct timespec t_start; + struct timespec t; + timestamp_t ret; + + if (!t_start.tv_sec) + clock_gettime(CLOCK_REALTIME, &t_start); + clock_gettime(CLOCK_REALTIME, &t); + ret.val = (t.tv_sec - t_start.tv_sec) * SECOND + + (t.tv_nsec - t_start.tv_nsec) / TS_USEC; + return ret; +} + +/* We could implement these if we wanted to test their usage. */ +int system_add_jump_tag(uint16_t tag, int version, int size, const void *data) +{ + return 0; +} + +uint8_t *system_get_jump_tag(uint16_t tag, int *version, int *size) +{ + return 0; +} + +/* Copied from util/ectool.c */ +int lb_read_params_from_file(const char *filename, + struct lightbar_params_v1 *p) +{ + FILE *fp; + char buf[80]; + int val[4]; + int r = 1; + int line = 0; + int want, got; + int i; + + fp = fopen(filename, "rb"); + if (!fp) { + fprintf(stderr, "Can't open %s: %s\n", + filename, strerror(errno)); + return 1; + } + + /* We must read the correct number of params from each line */ +#define READ(N) do { \ + line++; \ + want = (N); \ + got = -1; \ + if (!fgets(buf, sizeof(buf), fp)) \ + goto done; \ + got = sscanf(buf, "%i %i %i %i", \ + &val[0], &val[1], &val[2], &val[3]); \ + if (want != got) \ + goto done; \ + } while (0) + + + /* Do it */ + READ(1); p->google_ramp_up = val[0]; + READ(1); p->google_ramp_down = val[0]; + READ(1); p->s3s0_ramp_up = val[0]; + READ(1); p->s0_tick_delay[0] = val[0]; + READ(1); p->s0_tick_delay[1] = val[0]; + READ(1); p->s0a_tick_delay[0] = val[0]; + READ(1); p->s0a_tick_delay[1] = val[0]; + READ(1); p->s0s3_ramp_down = val[0]; + READ(1); p->s3_sleep_for = val[0]; + READ(1); p->s3_ramp_up = val[0]; + READ(1); p->s3_ramp_down = val[0]; + READ(1); p->tap_tick_delay = val[0]; + READ(1); p->tap_display_time = val[0]; + + READ(1); p->tap_pct_red = val[0]; + READ(1); p->tap_pct_green = val[0]; + READ(1); p->tap_seg_min_on = val[0]; + READ(1); p->tap_seg_max_on = val[0]; + READ(1); p->tap_seg_osc = val[0]; + READ(3); + p->tap_idx[0] = val[0]; + p->tap_idx[1] = val[1]; + p->tap_idx[2] = val[2]; + + READ(2); + p->osc_min[0] = val[0]; + p->osc_min[1] = val[1]; + READ(2); + p->osc_max[0] = val[0]; + p->osc_max[1] = val[1]; + READ(2); + p->w_ofs[0] = val[0]; + p->w_ofs[1] = val[1]; + + READ(2); + p->bright_bl_off_fixed[0] = val[0]; + p->bright_bl_off_fixed[1] = val[1]; + + READ(2); + p->bright_bl_on_min[0] = val[0]; + p->bright_bl_on_min[1] = val[1]; + + READ(2); + p->bright_bl_on_max[0] = val[0]; + p->bright_bl_on_max[1] = val[1]; + + READ(3); + p->battery_threshold[0] = val[0]; + p->battery_threshold[1] = val[1]; + p->battery_threshold[2] = val[2]; + + READ(4); + p->s0_idx[0][0] = val[0]; + p->s0_idx[0][1] = val[1]; + p->s0_idx[0][2] = val[2]; + p->s0_idx[0][3] = val[3]; + + READ(4); + p->s0_idx[1][0] = val[0]; + p->s0_idx[1][1] = val[1]; + p->s0_idx[1][2] = val[2]; + p->s0_idx[1][3] = val[3]; + + READ(4); + p->s3_idx[0][0] = val[0]; + p->s3_idx[0][1] = val[1]; + p->s3_idx[0][2] = val[2]; + p->s3_idx[0][3] = val[3]; + + READ(4); + p->s3_idx[1][0] = val[0]; + p->s3_idx[1][1] = val[1]; + p->s3_idx[1][2] = val[2]; + p->s3_idx[1][3] = val[3]; + + for (i = 0; i < ARRAY_SIZE(p->color); i++) { + READ(3); + p->color[i].r = val[0]; + p->color[i].g = val[1]; + p->color[i].b = val[2]; + } + +#undef READ + + /* Yay */ + r = 0; +done: + if (r) + fprintf(stderr, "problem with line %d: wanted %d, got %d\n", + line, want, got); + fclose(fp); + return r; +} diff --git a/extra/lightbar/simulation.h b/extra/lightbar/simulation.h new file mode 100644 index 0000000000..569107023b --- /dev/null +++ b/extra/lightbar/simulation.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef _SIMULATION_H +#define _SIMULATION_H + +#include +#include +#include +#include +#include +#include + +#include "lb_common.h" +#include "lightbar.h" + +/* Functions specific to our simulation environment */ +void *entry_windows(void *); +void *entry_input(void *); +void *entry_lightbar(void *); +void init_windows(void); +int lb_read_params_from_file(const char *filename, + struct lightbar_params_v1 *p); +/* Interfaces to the EC code that we're encapsulating */ +void lightbar_task(void); +int fake_consolecmd_lightbar(int argc, char *argv[]); + +/* EC-specific configuration */ +#undef DEMO_MODE_DEFAULT +#define DEMO_MODE_DEFAULT 1 +#ifndef CONFIG_CONSOLE_CMDHELP +#define CONFIG_CONSOLE_CMDHELP +#endif +#ifndef CONFIG_LIGHTBAR_POWER_RAILS +#define CONFIG_LIGHTBAR_POWER_RAILS +#endif + + +/* Stuff that's too interleaved with the rest of the EC to just include */ + +/* Test an important condition at compile time, not run time */ +#define _BA1_(cond, line) \ + extern int __build_assertion_ ## line[1 - 2*!(cond)] \ + __attribute__ ((unused)) +#define _BA0_(c, x) _BA1_(c, x) +#define BUILD_ASSERT(cond) _BA0_(cond, __LINE__) + +/* Number of elements in an array */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* Non-standard standard library functions */ +void cprintf(int zero, const char *fmt, ...); +void cprints(int zero, const char *fmt, ...); +#define ccprintf(fmt...) cprintf(0, fmt) +#define strtoi strtol + +/* Task events */ +#define TASK_EVENT_CUSTOM(x) (x & 0x0fffffff) +#define TASK_EVENT_I2C_IDLE 0x10000000 +#define TASK_EVENT_WAKE 0x20000000 +#define TASK_EVENT_MUTEX 0x40000000 +#define TASK_EVENT_TIMER 0x80000000 + +/* Time units in usecs */ +#define MSEC 1000 +#define SECOND 1000000 + +#define TASK_ID_LIGHTBAR 0 +#define CC_LIGHTBAR 0 + +/* Other definitions and structs */ +#define EC_SUCCESS 0 +#define EC_ERROR_INVAL 5 +#define EC_ERROR_PARAM1 11 +#define EC_ERROR_PARAM2 12 + +typedef int task_id_t; + +typedef union { + uint64_t val; + struct { + uint32_t lo; + uint32_t hi; + } le /* little endian words */; +} timestamp_t; + +struct host_cmd_handler_args { + const void *params; + void *response; + int response_size; +}; + +/* EC functions that we have to provide */ +uint32_t task_wait_event(int timeout_us); +uint32_t task_set_event(task_id_t tskid, uint32_t event, int wait_for_reply); +timestamp_t get_time(void); +int system_add_jump_tag(uint16_t tag, int version, int size, const void *data); +uint8_t *system_get_jump_tag(uint16_t tag, int *version, int *size); + +/* Export unused static functions to avoid compiler warnings. */ +#define DECLARE_HOOK(X, fn, Y) \ + void fake_hook_##fn(void) { fn(); } + +#define DECLARE_HOST_COMMAND(X, fn, Y) \ + int fake_hostcmd_##fn(struct host_cmd_handler_args *args) \ + { return fn(args); } + +#define DECLARE_CONSOLE_COMMAND(X, fn, Y...) \ + int fake_consolecmd_##X(int argc, char *argv[]) \ + { return fn(argc, argv); } + +#endif /* _SIMULATION_H */ diff --git a/extra/lightbar/windows.c b/extra/lightbar/windows.c new file mode 100644 index 0000000000..20b3a5780c --- /dev/null +++ b/extra/lightbar/windows.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "simulation.h" + +/*****************************************************************************/ +/* Window drawing stuff */ + +/* Dimensions - may change */ +static int win_w = 1024; +static int win_h = 32; + +static xcb_connection_t *c; +static xcb_screen_t *screen; +static xcb_drawable_t win; +static xcb_gcontext_t foreground; +static xcb_colormap_t colormap_id; + +static int fake_power; + +void init_windows(void) +{ + uint32_t mask = 0; + uint32_t values[2]; + + /* Open the connection to the X server */ + c = xcb_connect(NULL, NULL); + + /* Get the first screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; + + /* Get a colormap */ + colormap_id = xcb_generate_id(c); + xcb_create_colormap(c, XCB_COLORMAP_ALLOC_NONE, + colormap_id, screen->root, screen->root_visual); + + /* Create foreground GC */ + foreground = xcb_generate_id(c); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; + values[0] = screen->white_pixel; + values[1] = 0; + xcb_create_gc(c, foreground, screen->root, mask, values); + + /* Create the window */ + win = xcb_generate_id(c); + mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + values[0] = screen->black_pixel; + values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS; + xcb_create_window(c, /* Connection */ + XCB_COPY_FROM_PARENT, /* depth */ + win, /* window Id */ + screen->root, /* parent window */ + 0, 0, /* x, y */ + win_w, win_h, /* width, height */ + 10, /* border_width */ + XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ + screen->root_visual, /* visual */ + mask, values); /* masks */ + + /* Map the window on the screen */ + xcb_map_window(c, win); + + /* We flush the request */ + xcb_flush(c); +} + +void cleanup(void) +{ + xcb_destroy_window(c, win); + xcb_free_gc(c, foreground); + xcb_free_colormap(c, colormap_id); + xcb_disconnect(c); +} + +/*****************************************************************************/ +/* Draw the lightbar elements */ + +/* xcb likes 16-bit colors */ +uint16_t leds[NUM_LEDS][3] = { + {0xffff, 0x0000, 0x0000}, + {0x0000, 0xffff, 0x0000}, + {0x0000, 0x0000, 0xffff}, + {0xffff, 0xffff, 0x0000}, +}; +pthread_mutex_t leds_mutex = PTHREAD_MUTEX_INITIALIZER; + +void change_gc_color(uint16_t red, uint16_t green, uint16_t blue) +{ + uint32_t mask = 0; + uint32_t values[2]; + xcb_alloc_color_reply_t *reply; + + reply = xcb_alloc_color_reply(c, + xcb_alloc_color(c, colormap_id, + red, green, blue), + NULL); + assert(reply); + + mask = XCB_GC_FOREGROUND; + values[0] = reply->pixel; + xcb_change_gc(c, foreground, mask, values); + free(reply); +} + +void update_window(void) +{ + xcb_segment_t segments[] = { + {0, 0, win_w, win_h}, + {0, win_h, win_w, 0}, + }; + xcb_rectangle_t rect; + int w = win_w / NUM_LEDS; + int i; + uint16_t copyleds[NUM_LEDS][3]; + + if (fake_power) { + pthread_mutex_lock(&leds_mutex); + memcpy(copyleds, leds, sizeof(leds)); + pthread_mutex_unlock(&leds_mutex); + + for (i = 0; i < NUM_LEDS; i++) { + rect.x = i * w; + rect.y = 0; + rect.width = w; + rect.height = win_h; + + change_gc_color(copyleds[i][0], + copyleds[i][1], + copyleds[i][2]); + + xcb_poly_fill_rectangle(c, win, foreground, 1, &rect); + } + } else { + rect.x = 0; + rect.y = 0; + rect.width = win_w; + rect.height = win_h; + + change_gc_color(0, 0, 0); + xcb_poly_fill_rectangle(c, win, foreground, 1, &rect); + + change_gc_color(0x8080, 0, 0); + + for (i = 0; i < NUM_LEDS; i++) { + segments[0].x1 = i * w; + segments[0].y1 = 0; + segments[0].x2 = segments[0].x1 + w; + segments[0].y2 = win_h; + segments[1].x1 = segments[0].x1; + segments[1].y1 = win_h; + segments[1].x2 = segments[0].x2; + segments[1].y2 = 0; + xcb_poly_segment(c, win, foreground, 2, segments); + } + } + + xcb_flush(c); +} + +void setrgb(int led, int red, int green, int blue) +{ + led %= NUM_LEDS; + + pthread_mutex_lock(&leds_mutex); + leds[led][0] = red << 8 | red; + leds[led][1] = green << 8 | green; + leds[led][2] = blue << 8 | blue; + pthread_mutex_unlock(&leds_mutex); + + update_window(); +} + +/*****************************************************************************/ +/* lb_common stubs */ + + + +/* Brightness serves no purpose here. It's automatic on the Chromebook. */ +static int brightness = 0xc0; +void lb_set_brightness(unsigned int newval) +{ + brightness = newval; +} +uint8_t lb_get_brightness(void) +{ + return brightness; +} + +void lb_set_rgb(unsigned int led, int red, int green, int blue) +{ + int i; + if (led >= NUM_LEDS) + for (i = 0; i < NUM_LEDS; i++) + setrgb(i, red, green, blue); + else + setrgb(led, red, green, blue); +} + +int lb_get_rgb(unsigned int led, uint8_t *red, uint8_t *green, uint8_t *blue) +{ + led %= NUM_LEDS; + pthread_mutex_lock(&leds_mutex); + *red = leds[led][0]; + *green = leds[led][1]; + *blue = leds[led][2]; + pthread_mutex_unlock(&leds_mutex); + return 0; +} + +void lb_init(void) +{ + if (fake_power) + lb_set_rgb(NUM_LEDS, 0, 0, 0); +}; +void lb_off(void) +{ + fake_power = 0; + update_window(); +}; +void lb_on(void) +{ + fake_power = 1; + update_window(); +}; +void lb_start_builtin_cycle(void) { }; +void lb_hc_cmd_dump(struct ec_response_lightbar *out) +{ + printf("lightbar is %s\n", fake_power ? "on" : "off"); + memset(out, fake_power, sizeof(*out)); +}; +void lb_hc_cmd_reg(const struct ec_params_lightbar *in) { }; + +int lb_power(int enabled) +{ + return fake_power; +} + + +/*****************************************************************************/ +/* Event handling stuff */ + +void *entry_windows(void *ptr) +{ + xcb_generic_event_t *e; + xcb_expose_event_t *ev; + xcb_button_press_event_t *bv; + int chg = 1; + + while ((e = xcb_wait_for_event(c))) { + + switch (e->response_type & ~0x80) { + case XCB_EXPOSE: + ev = (xcb_expose_event_t *)e; + if (win_w != ev->width || win_h != ev->height) { + win_w = ev->width; + win_h = ev->height; + } + update_window(); + break; + case XCB_BUTTON_PRESS: + bv = (xcb_button_press_event_t *)e; + switch (bv->detail) { + case 1: + demo_battery_level(-1); + break; + case 3: + demo_battery_level(+1); + break; + case 2: + chg = !chg; + demo_is_charging(chg); + break; + } + break; + } + + free(e); + } + + cleanup(); + exit(0); + return 0; +} -- cgit v1.2.1