Add backlight_invert, config/time, screenshot isDirty

This commit is contained in:
fvanroie 2022-04-03 01:43:20 +02:00
parent 143abc212d
commit df4e287a11
3 changed files with 81 additions and 11 deletions

View File

@ -74,6 +74,8 @@ lv_obj_t* cursor;
uint16_t tft_width = TFT_WIDTH;
uint16_t tft_height = TFT_HEIGHT;
bool screenshotIsDirty = true;
static lv_disp_buf_t disp_buf;
// #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
@ -174,6 +176,7 @@ void gui_hide_pointer(bool hidden)
IRAM_ATTR void gui_flush_cb(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p)
{
haspTft.flush_pixels(disp, area, color_p);
screenshotIsDirty = true;
}
IRAM_ATTR bool gui_touch_read(lv_indev_drv_t* indev_driver, lv_indev_data_t* data)
@ -461,7 +464,8 @@ void guiStop()
#if HASP_USE_CONFIG > 0
bool guiGetConfig(const JsonObject& settings)
{
bool changed = false;
bool changed = false;
bool backlight_invert = haspDevice.get_backlight_invert();
uint16_t guiSleepTime1;
uint16_t guiSleepTime2;
hasp_get_sleep_time(guiSleepTime1, guiSleepTime2);
@ -478,6 +482,9 @@ bool guiGetConfig(const JsonObject& settings)
if(gui_settings.backlight_pin != settings[FPSTR(FP_GUI_BACKLIGHTPIN)].as<int8_t>()) changed = true;
settings[FPSTR(FP_GUI_BACKLIGHTPIN)] = gui_settings.backlight_pin;
if(backlight_invert != settings[FPSTR(FP_GUI_BACKLIGHTINVERT)].as<bool>()) changed = true;
settings[FPSTR(FP_GUI_BACKLIGHTINVERT)] = (uint8_t)backlight_invert;
if(gui_settings.rotation != settings[FPSTR(FP_GUI_ROTATION)].as<uint8_t>()) changed = true;
settings[FPSTR(FP_GUI_ROTATION)] = gui_settings.rotation;
@ -535,7 +542,8 @@ bool guiGetConfig(const JsonObject& settings)
bool guiSetConfig(const JsonObject& settings)
{
configOutput(settings, TAG_GUI);
bool changed = false;
bool changed = false;
uint8_t backlight_invert = haspDevice.get_backlight_invert();
uint16_t guiSleepTime1;
uint16_t guiSleepTime2;
@ -543,12 +551,14 @@ bool guiSetConfig(const JsonObject& settings)
// changed |= configSet(guiTickPeriod, settings[FPSTR(FP_GUI_TICKPERIOD)], F("guiTickPeriod"));
changed |= configSet(gui_settings.backlight_pin, settings[FPSTR(FP_GUI_BACKLIGHTPIN)], F("guiBacklightPin"));
changed |= configSet(backlight_invert, settings[FPSTR(FP_GUI_BACKLIGHTINVERT)], F("guiBacklightInvert"));
changed |= configSet(guiSleepTime1, settings[FPSTR(FP_GUI_IDLEPERIOD1)], F("guiSleepTime1"));
changed |= configSet(guiSleepTime2, settings[FPSTR(FP_GUI_IDLEPERIOD2)], F("guiSleepTime2"));
changed |= configSet(gui_settings.rotation, settings[FPSTR(FP_GUI_ROTATION)], F("gui_settings.rotation"));
changed |= configSet(gui_settings.invert_display, settings[FPSTR(FP_GUI_INVERT)], F("guiInvertDisplay"));
hasp_set_sleep_time(guiSleepTime1, guiSleepTime2);
haspDevice.set_backlight_invert(backlight_invert); // Update if changed
if(!settings[FPSTR(FP_GUI_POINTER)].isNull()) {
if(gui_settings.show_pointer != settings[FPSTR(FP_GUI_POINTER)].as<bool>()) {
@ -746,10 +756,16 @@ void guiTakeScreenshot()
lv_obj_invalidate(lv_scr_act());
lv_refr_now(NULL); /* Will call our disp_drv.disp_flush function */
disp->driver.flush_cb = flush_cb; /* restore callback */
screenshotIsDirty = false;
LOG_VERBOSE(TAG_GUI, F("Bitmap data flushed to webclient"));
} else {
LOG_ERROR(TAG_GUI, F("Data sent does not match header size"));
}
}
bool guiScreenshotIsDirty()
{
return screenshotIsDirty;
}
#endif

View File

@ -49,6 +49,7 @@ void gui_hide_pointer(bool hidden);
void guiCalibrate(void);
void guiTakeScreenshot(const char* pFileName); // to file
void guiTakeScreenshot(void); // webclient
bool guiScreenshotIsDirty();
/* ===== Read/Write Configuration ===== */
#if HASP_USE_CONFIG > 0

View File

@ -22,6 +22,7 @@
#if HASP_USE_HTTP > 0
#include "sys/net/hasp_network.h"
#include "sys/net/hasp_time.h"
#if(HASP_USE_CAPTIVE_PORTAL > 0) && (HASP_USE_WIFI > 0)
#include <DNSServer.h>
@ -322,9 +323,10 @@ bool saveConfig()
#endif
} else if(save == String(PSTR("gui"))) {
settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cursor"));
settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("invert"));
updated = guiSetConfig(settings.as<JsonObject>());
settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cursor"));
settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("invert"));
settings[FPSTR(FP_GUI_BACKLIGHTINVERT)] = webServer.hasArg(PSTR("bcklinv"));
updated = guiSetConfig(settings.as<JsonObject>());
} else if(save == String(PSTR("debug"))) {
settings[FPSTR(FP_DEBUG_ANSI)] = webServer.hasArg(PSTR("ansi"));
@ -427,6 +429,16 @@ static void webHandleScreenshot()
}
}
// Check if screenshot bitmap is dirty
if(webServer.hasArg(F("d"))) {
if(guiScreenshotIsDirty())
webServer.send(200, F("text/text"), "1");
else
webServer.send(304, F("text/text"), "0");
return;
}
// Send bitmap
if(webServer.hasArg(F("q"))) {
lv_disp_t* disp = lv_disp_get_default();
webServer.setContentLength(66 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
@ -447,9 +459,9 @@ static void webHandleScreenshot()
httpMessage += F("<p class='c'><img id='bmp' src='?q=0'");
httpMessage += F(" onload=\"aref(5)\" onerror=\"aref(15)\"/></p>"); // Automatic refresh
httpMessage += F("<div class=\"dist\"><a href='#' onclick=\"return ref('prev')\">" D_HTTP_PREV_PAGE "</a>");
httpMessage += F("<a href='#' onclick=\"return ref('')\">" D_HTTP_REFRESH "</a>");
httpMessage += F("<a href='#' onclick=\"return ref('next')\">" D_HTTP_NEXT_PAGE "</a></div>");
httpMessage += F("<div class=\"dist\"><a href='#' onclick=\"return upd('prev')\">" D_HTTP_PREV_PAGE "</a>");
httpMessage += F("<a href='#' onclick=\"return upd('')\">" D_HTTP_REFRESH "</a>");
httpMessage += F("<a href='#' onclick=\"return upd('next')\">" D_HTTP_NEXT_PAGE "</a></div>");
httpMessage += FPSTR(MAIN_MENU_BUTTON);
webSendHeader(haspDevice.get_hostname(), httpMessage.length(), false);
@ -512,12 +524,33 @@ static void webHandleApiConfig()
{ // http://plate01/about
if(!httpIsAuthenticated(F("api"))) return;
if(webServer.method() != HTTP_GET && webServer.method() != HTTP_POST) {
return;
}
DynamicJsonDocument doc(800);
JsonObject settings;
String contentType = getContentType(F(".json"));
String endpoint((char*)0);
endpoint = webServer.pathArg(0);
JsonObject settings = doc.to<JsonObject>(); // Settings are invalid, force creation of an empty JsonObject
String postBody = webServer.arg("plain");
if(webServer.method() == HTTP_GET) {
// Make sure we have a valid JsonObject to start from
settings = doc.to<JsonObject>();
} else if(webServer.method() == HTTP_POST) {
DeserializationError jsonError = deserializeJson(doc, postBody);
if(jsonError) { // Couldn't parse incoming JSON command
dispatch_json_error(TAG_HTTP, jsonError);
return;
}
settings = doc.as<JsonObject>();
} else {
webServer.send(400, contentType, "Bad Request");
return;
}
if(!strcasecmp_P(endpoint.c_str(), PSTR("wifi"))) {
wifiGetConfig(settings);
@ -529,22 +562,38 @@ static void webHandleApiConfig()
guiGetConfig(settings);
} else if(!strcasecmp_P(endpoint.c_str(), PSTR("debug"))) {
debugGetConfig(settings);
} else if(!strcasecmp_P(endpoint.c_str(), PSTR("time"))) {
if(webServer.method() == HTTP_POST) {
configOutput(settings, TAG_HTTP);
timeSetConfig(settings);
}
settings = doc.to<JsonObject>();
timeGetConfig(settings);
configOutput(settings, TAG_HTTP);
} else {
webServer.send(400, contentType, "Bad Request");
return;
}
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
// Mask non-blank passwords
if(!settings[FPSTR(FP_CONFIG_PASS)].isNull() && settings[FPSTR(FP_CONFIG_PASS)].as<String>().length() != 0) {
settings[FPSTR(FP_CONFIG_PASS)] = D_PASSWORD_MASK;
}
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
doc.shrinkToFit();
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
const size_t size = measureJson(doc) + 1;
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
char jsondata[size];
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
memset(jsondata, 0, size);
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
serializeJson(doc, jsondata, size);
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
webServer.send(200, contentType, jsondata);
LOG_WARNING(TAG_HTTP, "%s - %d", __FILE__, __LINE__);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1185,7 +1234,7 @@ static void webHandleGuiConfig()
// if(settings[FPSTR(FP_GUI_POINTER)].as<bool>()) httpMessage += F(" checked");
httpMessage += F(">Show Pointer</div></div>");
// Backlight
// Backlight Pin
int8_t bcklpin = settings[FPSTR(FP_GUI_BACKLIGHTPIN)].as<int8_t>();
httpMessage += F("<div class='row'><div class='col-25'><label for='group'>Backlight Control</label></div>");
httpMessage += F("<div class='col-75'><select id='bckl' name='bckl'>");
@ -1207,6 +1256,11 @@ static void webHandleGuiConfig()
#endif
httpMessage += F("</select></div></div>");
// Backlight Invert
httpMessage += F("<div class='row'><div class='col-25'><label for='bcklinv'></label></div>");
httpMessage += F("<div class='col-75'><input type='checkbox' id='bcklinv' name='bcklinv' value='1'");
httpMessage += F(">Invert Backlight</div></div>");
// Submit & End Form
httpMessage += F("<button type='submit' name='save' value='gui'>" D_HTTP_SAVE_SETTINGS "</button>");
httpMessage += F("</form></div>");
@ -2177,7 +2231,6 @@ static void webSendCssVars()
webSendCached(200, PSTR("text/css"), HTTP_CSS.c_str(), HTTP_CSS.length());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
static inline void webStartConfigPortal()
{