1/* 2 * lws abstract display 3 * 4 * Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25#include <libwebsockets.h> 26 27static void 28sul_autodim_cb(lws_sorted_usec_list_t *sul) 29{ 30 lws_display_state_t *lds = lws_container_of(sul, lws_display_state_t, 31 sul_autodim); 32 int next_ms = -1; 33 34 /* we fire both to dim and to blank... if already in dim state, blank */ 35 36 switch (lds->state) { 37 case LWSDISPS_BECOMING_ACTIVE: 38 lws_display_state_set_brightness(lds, lds->disp->bl_active); 39 lds->state = LWSDISPS_ACTIVE; 40 next_ms = lds->autodim_ms; 41 break; 42 43 case LWSDISPS_ACTIVE: 44 /* active -> autodimmed */ 45 lds->state = LWSDISPS_AUTODIMMED; 46 next_ms = lds->off_ms; 47 lws_display_state_set_brightness(lds, lds->disp->bl_dim); 48 break; 49 50 case LWSDISPS_AUTODIMMED: 51 /* dimmed -> OFF */ 52 lws_display_state_set_brightness(lds, &lws_pwmseq_static_off); 53 lds->state = LWSDISPS_GOING_OFF; 54 next_ms = 600; 55 break; 56 57 case LWSDISPS_GOING_OFF: 58 /* off dimming completed, actual display OFF */ 59 lws_display_state_off(lds); 60 return; 61 62 default: 63 return; 64 } 65 66 if (next_ms >= 0) 67 lws_sul_schedule(lds->ctx, 0, &lds->sul_autodim, sul_autodim_cb, 68 next_ms * LWS_US_PER_MS); 69} 70 71void 72lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx, 73 int dim_ms, int off_ms, struct lws_led_state *bl_lcs, 74 const lws_display_t *disp) 75{ 76 memset(lds, 0, sizeof(*lds)); 77 78 lds->disp = disp; 79 lds->ctx = ctx; 80 lds->autodim_ms = dim_ms; 81 lds->off_ms = off_ms; 82 lds->bl_lcs = bl_lcs; 83 lds->state = LWSDISPS_OFF; 84 85 lws_led_transition(lds->bl_lcs, "backlight", &lws_pwmseq_static_off, 86 &lws_pwmseq_static_on); 87 88 disp->init(disp); 89} 90 91void 92lws_display_state_set_brightness(lws_display_state_t *lds, 93 const lws_led_sequence_def_t *pwmseq) 94{ 95 lws_led_transition(lds->bl_lcs, "backlight", pwmseq, 96 lds->disp->bl_transition); 97} 98 99void 100lws_display_state_active(lws_display_state_t *lds) 101{ 102 int waiting_ms; 103 104 if (lds->state == LWSDISPS_OFF) { 105 /* power us up */ 106 lds->disp->power(lds->disp, 1); 107 lds->state = LWSDISPS_BECOMING_ACTIVE; 108 waiting_ms = lds->disp->latency_wake_ms; 109 } else { 110 111 if (lds->state != LWSDISPS_ACTIVE) 112 lws_display_state_set_brightness(lds, 113 lds->disp->bl_active); 114 115 lds->state = LWSDISPS_ACTIVE; 116 waiting_ms = lds->autodim_ms; 117 } 118 119 /* reset the autodim timer */ 120 if (waiting_ms >= 0) 121 lws_sul_schedule(lds->ctx, 0, &lds->sul_autodim, sul_autodim_cb, 122 waiting_ms * LWS_US_PER_MS); 123 124} 125 126void 127lws_display_state_off(lws_display_state_t *lds) 128{ 129 lds->disp->power(lds->disp, 0); 130 lws_sul_cancel(&lds->sul_autodim); 131 lds->state = LWSDISPS_OFF; 132} 133