add locks and missing comments

This commit is contained in:
Siyuan Miao 2025-09-25 09:51:59 +00:00 committed by Siyuan
parent 2e939c918f
commit 8123900f26
13 changed files with 311 additions and 83 deletions

View File

@ -10,7 +10,7 @@ KVM_PKG_NAME := github.com/jetkvm/kvm
BUILDKIT_FLAVOR := arm-rockchip830-linux-uclibcgnueabihf
BUILDKIT_PATH ?= /opt/jetkvm-native-buildkit
SKIP_NATIVE_IF_EXISTS ?= 1
SKIP_NATIVE_IF_EXISTS ?= 0
GO_BUILD_ARGS := -tags netgo -tags timetzdata
@ -111,7 +111,7 @@ dev_release: frontend build_dev
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION_DEV)/jetkvm_app.sha256
build_release: frontend
build_release: frontend build_native
@echo "Building release..."
$(GO_CMD) build \
-ldflags="$(GO_LDFLAGS) -X $(KVM_PKG_NAME).builtAppVersion=$(VERSION)" \

View File

@ -104,7 +104,8 @@ if [ -z "$REMOTE_HOST" ]; then
fi
# Build the development version on the host
if [ "$SKIP_UI_BUILD" = false ]; then
# When using `make build_release`, the frontend will be built regardless of the `SKIP_UI_BUILD` flag
if [[ "$SKIP_UI_BUILD" = false && "$INSTALL_APP" = false ]]; then
msg_info "▶ Building frontend"
make frontend
fi

View File

@ -173,7 +173,7 @@ const char *videoc_log_status()
}
else
{
log_error("Failed to read kernel log\n");
log_error("Failed to read kernel log");
return NULL;
}

View File

@ -2,8 +2,25 @@
#define LOG_HANDLER_H
typedef void (jetkvm_log_handler_t)(int level, const char *filename, const char *funcname, const int line, const char *message);
/**
* @brief Log a message
*
* @param level The level of the message
* @param filename The filename of the message
* @param funcname The function name of the message
* @param line The line number of the message
* @param message The message to log
* @return void
*/
void log_message(int level, const char *filename, const char *funcname, const int line, const char *message);
/**
* @brief Set the log handler
*
* @param handler The handler to set
* @return void
*/
void log_set_handler(jetkvm_log_handler_t *handler);
#endif

View File

@ -188,7 +188,7 @@ lv_img_dsc_t *ui_get_image(const char *name) {
void ui_set_text(const char *name, const char *text) {
lv_obj_t *obj = ui_get_obj(name);
if(obj == NULL) {
log_error("ui_set_text %s %s, obj not found\n", name, text);
log_error("ui_set_text %s %s, obj not found", name, text);
return;
}
lv_label_set_text(obj, text);

View File

@ -12,10 +12,37 @@ void lvgl_tick(void);
void lvgl_set_rotation(lv_display_t *disp, u_int16_t rotation);
/**
* @brief Set the text of an object
*
* @param name The name of the object
* @param text The text to set
* @return void
*/
void ui_set_text(const char *name, const char *text);
/**
* @brief Get the object with the given name
*
* @param name The name of the object
* @return lv_obj_t* The object with the given name
*/
lv_obj_t *ui_get_obj(const char *name);
/**
* @brief Get the style with the given name
*
* @param name The name of the style
* @return lv_style_t* The style with the given name
*/
lv_style_t *ui_get_style(const char *name);
/**
* @brief Get the image with the given name
*
* @param name The name of the image
* @return lv_img_dsc_t* The image with the given name
*/
lv_img_dsc_t *ui_get_image(const char *name);
#endif // SCREEN_H

View File

@ -268,12 +268,12 @@ static void *venc_read_stream(void *arg)
stFrame.pstPack = malloc(sizeof(VENC_PACK_S));
while (venc_running)
{
log_trace("RK_MPI_VENC_GetStream\n");
log_trace("RK_MPI_VENC_GetStream");
s32Ret = RK_MPI_VENC_GetStream(VENC_CHANNEL, &stFrame, 200); // blocks max 200ms
if (s32Ret == RK_SUCCESS)
{
RK_U64 nowUs = get_us();
log_trace("chn:0, loopCount:%d enc->seq:%d wd:%d pts=%llu delay=%lldus\n",
log_trace("chn:0, loopCount:%d enc->seq:%d wd:%d pts=%llu delay=%lldus",
loopCount, stFrame.u32Seq, stFrame.pstPack->u32Len,
stFrame.pstPack->u64PTS, nowUs - stFrame.pstPack->u64PTS);
pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
@ -348,7 +348,7 @@ void *run_video_stream(void *arg)
if (ioctl(video_dev_fd, VIDIOC_S_FMT, &fmt) < 0)
{
log_error("Set format fail");
log_error("Set format fail: %s", strerror(errno));
usleep(100000); // Sleep for 100 milliseconds
close(video_dev_fd);
continue;
@ -363,7 +363,8 @@ void *run_video_stream(void *arg)
if (ioctl(video_dev_fd, VIDIOC_REQBUFS, &req) < 0)
{
log_error("VIDIOC_REQBUFS failed");
log_error("VIDIOC_REQBUFS failed: %s", strerror(errno));
close(video_dev_fd);
return errno;
}
log_info("VIDIOC_REQBUFS successful");
@ -385,22 +386,24 @@ void *run_video_stream(void *arg)
if (-1 == ioctl(video_dev_fd, VIDIOC_QUERYBUF, &buf))
{
log_error("VIDIOC_QUERYBUF failed");
log_error("VIDIOC_QUERYBUF failed: %s", strerror(errno));
req.count = i;
close(video_dev_fd);
return errno;
}
log_info("VIDIOC_QUERYBUF successful for buffer %d\n", i);
log_info("VIDIOC_QUERYBUF successful for buffer %d", i);
log_info("plane: length = %d\n", planes_buffer->length);
log_info("plane: offset = %d\n", planes_buffer->m.mem_offset);
log_info("plane: length = %d", planes_buffer->length);
log_info("plane: offset = %d", planes_buffer->m.mem_offset);
MB_BLK blk = RK_MPI_MB_GetMB(memPool, (planes_buffer)->length, RK_TRUE);
if (blk == NULL)
{
log_error("get mb blk failed!");
close(video_dev_fd);
return -1;
}
log_info("Got memory block for buffer %d\n", i);
log_info("Got memory block for buffer %d", i);
buffers[i].mb_blk = blk;
@ -408,9 +411,10 @@ void *run_video_stream(void *arg)
if (buf_fd < 0)
{
log_error("RK_MPI_MB_Handle2Fd failed!");
close(video_dev_fd);
return -1;
}
log_info("Converted memory block to file descriptor for buffer %d\n", i);
log_info("Converted memory block to file descriptor for buffer %d", i);
planes_buffer->m.fd = buf_fd;
}
@ -425,15 +429,16 @@ void *run_video_stream(void *arg)
buf.m.planes = &buffers[i].plane_buffer;
if (ioctl(video_dev_fd, VIDIOC_QBUF, &buf) < 0)
{
log_error("VIDIOC_QBUF failed");
log_error("VIDIOC_QBUF failed: %s", strerror(errno));
close(video_dev_fd);
return errno;
}
log_info("VIDIOC_QBUF successful for buffer %d\n", i);
log_info("VIDIOC_QBUF successful for buffer %d", i);
}
if (ioctl(video_dev_fd, VIDIOC_STREAMON, &type) < 0)
{
log_error("VIDIOC_STREAMON failed");
log_error("VIDIOC_STREAMON failed: %s", strerror(errno));
goto cleanup;
}
@ -464,7 +469,7 @@ void *run_video_stream(void *arg)
r = select(video_dev_fd + 1, &fds, NULL, NULL, &tv);
if (r == 0)
{
log_info("select timeout \n");
log_info("select timeout");
break;
}
if (r == -1)
@ -483,10 +488,10 @@ void *run_video_stream(void *arg)
buf.length = 1;
if (ioctl(video_dev_fd, VIDIOC_DQBUF, &buf) < 0)
{
log_error("VIDIOC_DQBUF failed");
log_error("VIDIOC_DQBUF failed: %s", strerror(errno));
break;
}
log_trace("got frame, bytesused = %d\n", tmp_plane.bytesused);
log_trace("got frame, bytesused = %d", tmp_plane.bytesused);
memset(&stFrame, 0, sizeof(VIDEO_FRAME_INFO_S));
MB_BLK blk = RK_NULL;
blk = RK_MPI_MMZ_Fd2Handle(tmp_plane.m.fd);
@ -504,16 +509,6 @@ void *run_video_stream(void *arg)
stFrame.stVFrame.u32FrameFlag |= 0;
stFrame.stVFrame.enCompressMode = COMPRESS_MODE_NONE;
bool retried = false;
// if (num == 100) {
// RK_VOID *pData = RK_MPI_MB_Handle2VirAddr(stFrame.stVFrame.pMbBlk);
// if (pData) {
// size_t frameSize = tmp_plane.bytesused; // Use the actual size reported by the driver
// write_buffer_to_file(pData, frameSize, "/userdata/banana.raw");
// log_trace("Frame 100 written to /userdata/banana.raw\n");
// } else {
// log_trace("Failed to get virtual address for frame 100\n");
// }
// }
retry_send_frame:
if (RK_MPI_VENC_SendFrame(VENC_CHANNEL, &stFrame, 2000) != RK_SUCCESS)
{
@ -533,12 +528,13 @@ void *run_video_stream(void *arg)
num++;
if (ioctl(video_dev_fd, VIDIOC_QBUF, &buf) < 0)
log_error("failture VIDIOC_QBUF\n");
log_error("failure VIDIOC_QBUF: %s", strerror(errno));
}
cleanup:
log_info("cleaning up video capture device %s", VIDEO_DEV);
if (ioctl(video_dev_fd, VIDIOC_STREAMOFF, &type) < 0)
{
log_error("VIDIOC_STREAMOFF failed");
log_error("VIDIOC_STREAMOFF failed: %s", strerror(errno));
}
venc_stop();
@ -551,9 +547,11 @@ void *run_video_stream(void *arg)
}
}
log_info("closing video capture device %s", VIDEO_DEV);
close(video_dev_fd);
}
log_info("video stream thread exiting");
return NULL;
}
@ -561,41 +559,26 @@ void video_shutdown()
{
if (should_exit == true)
{
log_info("shutting down in progress already\n");
log_info("shutting down in progress already");
return;
}
video_stop_streaming();
// if (buffers != NULL) {
// for (int i = 0; i < input_buffer_count; i++) {
// if ((buffers + i)->mb_blk != NULL) {
// RK_MPI_MB_ReleaseMB((buffers + i)->mb_blk);
// }
// free((buffers + i)->planes_buffer);
// }
// free(buffers);
// }
should_exit = true;
if (sub_dev_fd > 0)
{
shutdown(sub_dev_fd, SHUT_RDWR);
// close(sub_dev_fd);
log_info("Closed sub_dev_fd\n");
log_info("Closed sub_dev_fd");
}
if (memPool != MB_INVALID_POOLID)
{
RK_MPI_MB_DestroyPool(memPool);
}
log_info("Destroyed memory pool\n");
log_info("Destroyed memory pool");
pthread_mutex_destroy(&streaming_mutex);
log_info("Destroyed streaming mutex\n");
// if (format_thread != NULL) {
// pthread_join(*format_thread, NULL);
// free(format_thread);
// format_thread = NULL;
// }
// printf("Joined format detection thread\n");
log_info("Destroyed streaming mutex");
}
@ -605,14 +588,31 @@ void video_start_streaming()
if (streaming_thread != NULL)
{
log_warn("video streaming already started");
pthread_mutex_unlock(&streaming_mutex);
return;
goto cleanup;
}
streaming_thread = malloc(sizeof(pthread_t));
assert(streaming_thread != NULL);
pthread_t *new_thread = malloc(sizeof(pthread_t));
if (new_thread == NULL)
{
log_error("Failed to allocate memory for streaming thread");
goto cleanup;
}
streaming_flag = true;
pthread_create(streaming_thread, NULL, run_video_stream, NULL);
int result = pthread_create(new_thread, NULL, run_video_stream, NULL);
if (result != 0)
{
log_error("Failed to create streaming thread: %s", strerror(result));
streaming_flag = false;
free(new_thread);
goto cleanup;
}
// Only set streaming_thread after successful creation, and before unlocking the mutex
streaming_thread = new_thread;
cleanup:
pthread_mutex_unlock(&streaming_mutex);
return;
}
void video_stop_streaming()
@ -621,6 +621,10 @@ void video_stop_streaming()
if (streaming_thread != NULL)
{
streaming_flag = false;
log_info("stopping video streaming");
// wait 100ms for the thread to exit
usleep(1000000);
log_info("waiting for video streaming thread to exit");
pthread_join(*streaming_thread, NULL);
free(streaming_thread);
streaming_thread = NULL;
@ -640,7 +644,6 @@ void *run_detect_format(void *arg)
if (ioctl(sub_dev_fd, VIDIOC_SUBSCRIBE_EVENT, &sub) == -1)
{
log_error("cannot subscribe to event");
log_error("Cannot subscribe to event");
goto exit;
}
@ -665,12 +668,12 @@ void *run_detect_format(void *arg)
else if (errno == ERANGE)
{
// Timings were found, but they are out of range of the hardware capabilities.
log_warn("HDMI status: out of range\n");
log_warn("HDMI status: out of range");
video_report_format(false, "out_of_range", 0, 0, 0);
}
else
{
log_error("error VIDIOC_QUERY_DV_TIMINGS");
log_error("error VIDIOC_QUERY_DV_TIMINGS: %s", strerror(errno));
sleep(1);
continue;
}
@ -706,7 +709,7 @@ void *run_detect_format(void *arg)
memset(&ev, 0, sizeof(ev));
if (ioctl(sub_dev_fd, VIDIOC_DQEVENT, &ev) != 0)
{
log_error("failed to VIDIOC_DQEVENT");
log_error("failed to VIDIOC_DQEVENT: %s", strerror(errno));
break;
}
log_info("New event of type %u", ev.type);

View File

@ -1,13 +1,48 @@
#ifndef VIDEO_DAEMON_VIDEO_H
#define VIDEO_DAEMON_VIDEO_H
/**
* @brief Initialize the video subsystem
*
* @return int 0 on success, -1 on failure
*/
int video_init();
/**
* @brief Shutdown the video subsystem
*/
void video_shutdown();
/**
* @brief Run the detect format thread
*
* @param arg The argument to pass to the thread
* @return void* The result of the thread
*/
void *run_detect_format(void *arg);
/**
* @brief Start the video streaming
*/
void video_start_streaming();
/**
* @brief Stop the video streaming
*/
void video_stop_streaming();
/**
* @brief Set the quality factor of the video
*
* @param factor The quality factor to set
*/
void video_set_quality_factor(float factor);
/**
* @brief Get the quality factor of the video
*
* @return float The quality factor of the video
*/
float video_get_quality_factor();
#endif //VIDEO_DAEMON_VIDEO_H

View File

@ -48,7 +48,7 @@
{
"objID": "58af3ebb-96b3-494c-f4e3-9c23852e3e42",
"fileName": "actions.c",
"template": "#include \"actions.h\"\n#include \"screens.h\"\n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}"
"template": "#include \"actions.h\"\n#include \"screens.h\"\n\nint handle_gesture_screen_switch(lv_event_t *e, lv_dir_t direction, int screenId) {\n lv_event_code_t event_code = lv_event_get_code(e);\n if (event_code != LV_EVENT_GESTURE) {\n return 0;\n }\n\n if (lv_indev_get_gesture_dir(lv_indev_get_act()) != direction) {\n return 0;\n }\n lv_indev_wait_release(lv_indev_get_act());\n loadScreen(screenId);\n return 1;\n}\n\nvoid action_switch_to_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_switch_to_advanced_menu(lv_event_t *e) {\n loadScreen(SCREEN_ID_MENU_ADVANCED_SCREEN);\n}\n\nvoid action_switch_to_status(lv_event_t *e) {\n loadScreen(SCREEN_ID_STATUS_SCREEN);\n}\n\nvoid action_switch_to_about(lv_event_t *e) {\n loadScreen(SCREEN_ID_ABOUT_SCREEN);\n}\n\nvoid action_menu_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_HOME_SCREEN);\n}\n\nvoid action_menu_advanced_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_reset_config_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_home_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_LEFT, SCREEN_ID_MENU_SCREEN);\n}\n\nvoid action_about_screen_gesture(lv_event_t * e) {\n handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);\n}\n\nstatic const int RESET_LONG_PRESS_DURATION = 1000 * 20; // 20 seconds\n\nvoid action_reset_config(lv_event_t * e) \n lv_event_code_t event_code = lv_event_get_code(e);\n lv_obj_t *obj = lv_event_get_target(e);\n \n if (event_code == LV_EVENT_PRESSED) {\n // Button pressed - start timing\n reset_press_start_time = lv_tick_get();\n lv_obj_set_user_data(obj, (uint32_t) reset_press_start_time);\n }\n else if (event_code == LV_EVENT_PRESSING) {\n uint32_t reset_press_start_time = (uint32_t) lv_obj_get_user_data(obj);\n if (reset_press_start_time == 0) {\n return;\n }\n\n uint32_t current_time = lv_tick_get();\n if (current_time - reset_press_start_time >= RESET_LONG_PRESS_DURATION) {\n \n lv_obj_add_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN);\n }\n }\n}"
},
{
"objID": "1dbd1b7e-7270-47f0-ee02-e80bdae287cf",
@ -6452,7 +6452,7 @@
},
"timeline": [],
"eventHandlers": [],
"identifier": "AboutHeaderContainer_1",
"identifier": "ResetConfigHeader",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
@ -6634,7 +6634,7 @@
},
"timeline": [],
"eventHandlers": [],
"identifier": "AboutItemsContainer_1",
"identifier": "ResetConfigContainer",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
@ -6679,7 +6679,7 @@
},
"timeline": [],
"eventHandlers": [],
"identifier": "systemVersionContainer_1",
"identifier": "ResetConfigLabel",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
@ -6702,7 +6702,7 @@
},
"timeline": [],
"eventHandlers": [],
"identifier": "systemVersion_1",
"identifier": "",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
@ -6766,6 +6766,97 @@
"group": "",
"groupIndex": 0
},
{
"objID": "cbac637a-7b3f-450b-c962-2ceca07a0a43",
"type": "LVGLContainerWidget",
"left": 0,
"top": 0,
"width": 100,
"height": 80,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "5c719542-cd7f-4b66-c0b4-3b2812132e3f",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"hiddenInEditor": true,
"timeline": [],
"eventHandlers": [],
"identifier": "ResetConfigSpinner",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
"heightUnit": "content",
"children": [
{
"objID": "abf38156-7bc2-4c4e-93fc-e08d9ee999e7",
"type": "LVGLSpinnerWidget",
"left": 0,
"top": 0,
"width": 80,
"height": 80,
"customInputs": [],
"customOutputs": [],
"style": {
"objID": "8f4f24d3-5bd6-433f-bac5-e15c05820742",
"useStyle": "default",
"conditionalStyles": [],
"childStyles": []
},
"hiddenInEditor": true,
"timeline": [],
"eventHandlers": [],
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "px",
"heightUnit": "px",
"children": [],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"localStyles": {
"objID": "e8d49d0f-a7e9-44df-afa0-db6cde72f306"
},
"group": "",
"groupIndex": 0
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
"hiddenFlagType": "literal",
"clickableFlag": true,
"clickableFlagType": "literal",
"flagScrollbarMode": "",
"flagScrollDirection": "",
"scrollSnapX": "",
"scrollSnapY": "",
"checkedStateType": "literal",
"disabledStateType": "literal",
"states": "",
"useStyle": "FlexColumnStart",
"localStyles": {
"objID": "46a10ecd-c85a-4dfa-a7a8-412a90c09ee1",
"definition": {
"MAIN": {
"DEFAULT": {
"flex_main_place": "CENTER",
"flex_cross_place": "CENTER",
"flex_track_place": "CENTER"
}
}
}
},
"group": "",
"groupIndex": 0
},
{
"objID": "e3c027f5-a51d-49ee-c7d6-74eca94fbf6a",
"type": "LVGLContainerWidget",
@ -6781,9 +6872,10 @@
"conditionalStyles": [],
"childStyles": []
},
"hiddenInEditor": false,
"timeline": [],
"eventHandlers": [],
"identifier": "appVersionContainer_1",
"identifier": "ResetConfigButton",
"leftUnit": "px",
"topUnit": "px",
"widthUnit": "%",
@ -6804,6 +6896,7 @@
"conditionalStyles": [],
"childStyles": []
},
"hiddenInEditor": false,
"timeline": [],
"eventHandlers": [
{
@ -6834,6 +6927,7 @@
"conditionalStyles": [],
"childStyles": []
},
"hiddenInEditor": false,
"timeline": [],
"eventHandlers": [],
"leftUnit": "px",

View File

@ -49,4 +49,29 @@ void action_home_screen_gesture(lv_event_t * e) {
void action_about_screen_gesture(lv_event_t * e) {
handle_gesture_screen_switch(e, LV_DIR_RIGHT, SCREEN_ID_MENU_SCREEN);
}
static const int RESET_LONG_PRESS_DURATION = 1000 * 20; // 20 seconds
void action_reset_config(lv_event_t * e) {
lv_event_code_t event_code = lv_event_get_code(e);
lv_obj_t *obj = lv_event_get_target(e);
if (event_code == LV_EVENT_PRESSED) {
// Button pressed - start timing
uint32_t reset_press_start_time = lv_tick_get();
lv_obj_set_user_data(obj, (uint32_t) reset_press_start_time);
}
else if (event_code == LV_EVENT_PRESSING) {
uint32_t reset_press_start_time = (uint32_t) lv_obj_get_user_data(obj);
if (reset_press_start_time == 0) {
return;
}
uint32_t current_time = lv_tick_get();
if (current_time - reset_press_start_time >= RESET_LONG_PRESS_DURATION) {
lv_obj_add_flag(objects.reset_config_button, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(objects.reset_config_spinner, LV_OBJ_FLAG_HIDDEN);
}
}
}

View File

@ -1744,9 +1744,9 @@ void create_screen_reset_config_screen() {
{
lv_obj_t *parent_obj = obj;
{
// AboutHeaderContainer_1
// ResetConfigHeader
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.about_header_container_1 = obj;
objects.reset_config_header = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
@ -1785,9 +1785,9 @@ void create_screen_reset_config_screen() {
}
}
{
// AboutItemsContainer_1
// ResetConfigContainer
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.about_items_container_1 = obj;
objects.reset_config_container = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_PCT(80));
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
@ -1819,9 +1819,9 @@ void create_screen_reset_config_screen() {
{
lv_obj_t *parent_obj = obj;
{
// systemVersionContainer_1
// ResetConfigLabel
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.system_version_container_1 = obj;
objects.reset_config_label = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
@ -1836,9 +1836,7 @@ void create_screen_reset_config_screen() {
{
lv_obj_t *parent_obj = obj;
{
// systemVersion_1
lv_obj_t *obj = lv_label_create(parent_obj);
objects.system_version_1 = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
add_style_info_content_label(obj);
@ -1848,9 +1846,37 @@ void create_screen_reset_config_screen() {
}
}
{
// appVersionContainer_1
// ResetConfigSpinner
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.app_version_container_1 = obj;
objects.reset_config_spinner = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
add_style_flex_column_start(obj);
lv_obj_set_style_flex_main_place(obj, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_flex_cross_place(obj, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_flex_track_place(obj, LV_FLEX_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_spinner_create(parent_obj);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 80, 80);
lv_spinner_set_anim_params(obj, 1000, 60);
}
}
}
{
// ResetConfigButton
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.reset_config_button = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);

View File

@ -84,11 +84,11 @@ typedef struct _objects_t {
lv_obj_t *app_version_1;
lv_obj_t *cloud_domain_container;
lv_obj_t *cloud_domain;
lv_obj_t *about_header_container_1;
lv_obj_t *about_items_container_1;
lv_obj_t *system_version_container_1;
lv_obj_t *system_version_1;
lv_obj_t *app_version_container_1;
lv_obj_t *reset_config_header;
lv_obj_t *reset_config_container;
lv_obj_t *reset_config_label;
lv_obj_t *reset_config_spinner;
lv_obj_t *reset_config_button;
lv_obj_t *obj0;
} objects_t;

Binary file not shown.