/* power_menu.c — MeowOS launcher 拆分模块(LAUNCHER_SPLIT_PLAN 拆分)。*/ /* 本文件由拆分工具从 meow_launcherd.c 按职责搬移;逻辑与原文 0-diff(仅 static 可见性按跨模块需求调整)。*/ #include "meow_launcher_internal.h" static const int pm_cy[PM_NUM] = { 250, 250, 390, 390, 530 }; /* 圆心 y(行距 140) */ static const char *pm_labels_cn[PM_NUM] = { "关机", "重启", "回HiBy", "升级", "取消" }; static const char *pm_labels_en[PM_NUM] = { "POWER OFF", "RESTART", "HIBYOS", "UPGRADE", "CANCEL" }; /* 电源菜单圆钮图标:从 pm_icons.h 的 56×56 alpha 位图 blit 到 fb(以圆钮中心 cx,cy 为锚居中)。 * alpha 按 col(RGB565)映射:图标前景色随选中/未选中主题色变化(日夜间由 pm_theme_* 提供)。 * dst_px 为 fb16bpp 写入:新像素 = col 前景与背景(btn bg)按 alpha 混合。 */ static void blit_pm_icon(int idx, int cx, int cy, uint16_t col) { const unsigned char *src = pm_icons[idx].data; int S = PM_ICON_SIZE; int x0 = cx - S / 2, y0 = cy - S / 2; for (int y = 0; y < S; y++) { int yy = y0 + y; if (yy < 0 || yy >= fb_yres) continue; uint16_t *row = (uint16_t *)fb + yy * (fb_line / 2); for (int x = 0; x < S; x++) { int a = src[y * S + x]; if (a < 8) continue; /* 透明像素跳过 */ int xx = x0 + x; if (xx < 0 || xx >= fb_xres) continue; /* 前景 col 已含所需亮度;此处仅做软边 alpha 混合到背景,避免锯齿 */ uint16_t bg = row[xx]; if (a >= 240) { row[xx] = col; continue; } int a4 = a >> 4; /* 0..15 */ int r = ((col >> 11) * a4 + ((bg >> 11) & 0x1F) * (16 - a4)) >> 4; int g = (((col >> 5) & 0x3F) * a4 + ((bg >> 5) & 0x3F) * (16 - a4)) >> 4; int b = ((col & 0x1F) * a4 + (bg & 0x1F) * (16 - a4)) >> 4; row[xx] = (uint16_t)((r << 11) | (g << 5) | b); } } } /* 绘制电源菜单圆钮 i(MD3 圆形:外描边+内填充+圆内 Material 图标;选中高亮)。 * 圆内放 Material Symbols 位图,文字标签放圆下(Android 12 式:icon 上、label 下)。 */ static void draw_pm_button(int i, int selected) { int cx = pm_cx[i], cy = pm_cy[i]; /* 主题(日夜间由 pm_theme_* 决定;默认取 dark,后续接设置) */ const pm_theme_t *th = &pm_theme_dark; /* 先铺一块比任何选中圈都大的卡片底色圆,盖掉上一态残留的选中描边(问题3: * 焦点移走后 PM_R+2..PM_R+6 之间残留亮圈。以 0x1C2438 卡片色清底)。 */ fill_circle(cx, cy, PM_R + 10, 0x1C2438); /* MD3 无边框高亮:选中=未选中底色稍亮填充(无描边圈),仅底色区分焦点;避免圆形描边残留。 */ if (selected) fill_circle(cx, cy, PM_R, th->btn_sel_bg); else fill_circle(cx, cy, PM_R, th->btn_nor_bg); /* 圆内 Material 图标(alpha 位图 + 主题前景色) */ blit_pm_icon(i, cx, cy, selected ? th->icon_sel : th->icon_nor); uint32_t col = selected ? 0xFFFFFF : 0xC8D0E8; /* 圆下文字标签(真字体/中文 或 点阵 ASCII 回退) */ int ly = cy + PM_R + 8; if (mfont_ready) { const char *lab = pm_labels_cn[i]; int lw = meow_font_width_text(lab, 18); meow_font_drawtext((uint16_t *)fb, cx - lw / 2, ly, lab, rgb565(col), 18); } else { const char *lab = pm_labels_en[i]; int lw = (int)strlen(lab) * 5; draw_text(cx - lw / 2, ly + 1, lab, 1, col); } } void sys_do_reboot(int cmd) { /* M2a:正常电源事件(关机/重启)触发清除板载通知数据之前,先转储所有未上卡通知 * (NOTIFICATION_SYSTEM.md §8)。meow_notif_before_poweroff 幂等安全(未 init 直接返回)。 */ meow_notif_before_poweroff(); sync(); /* 先落盘,避免数据丢失 */ logmsg("sys_do_reboot cmd=0x%x", cmd); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, NULL); logmsg("sys_do_reboot returned: %s", strerror(errno)); /* 正常不会返回 */ for (;;) usleep(1000); /* 防御:永不返回 */ } /* 回HibyOS:写板载 /data/meow_boot_default=1(开机默认权威标记,O_TRUNC 单值、不写 TF 卡), * 再 reboot 回选单并默认 HibyOS。meow.conf 不再写/承载 boot_default(bootmenu 以板载标记为准)。 */ static void set_boot_default_hiby(void) { int fd = open("/data/meow_boot_default", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd >= 0) { write(fd, "1\n", 2); close(fd); logmsg("pm: /data/meow_boot_default=1"); } } /* 电源菜单(M2.6):2×2 网格,dirty 绘制消频闪;输入修复: * - 触摸按下捕获坐标、抬起命中按钮即确认(同 run_menu MT 防抖); * - 音量上/下导航;播放=确认;电源新按(松开长按后)=确认当前钮(非取消); * - 取消=选「取消」钮;8s 持续按住=强制关机(绕过)。 * 返回 1=采取动作,0=取消。 */ int show_power_menu(void) { int fbfd = open(FB_DEV, O_RDWR); if (fbfd >= 0) { ioctl(fbfd, FBIOBLANK, 0); close(fbfd); } /* 亮起面板 */ pm_capture_app_frame(); /* A-0:菜单背景 = app 当前帧(fb0 buffer0),再压暗绘制其上 */ dim_screen(); /* M2.8 Bug 3-residual:若电源菜单是在「息屏」态打开(按住 3s),此处 FBIOBLANK(0) * 刚上电,LCDC 扫描地址可能非 buffer0;强制 re-pan 让压暗的应用列表 + 菜单落在被显示的 * 缓冲,否则菜单画在非显示缓冲上不可见。 */ fb_pan_buf0_force(); meow_screen_on = 1; /* 菜单打开即视为亮屏 */ /* M2.11 B:默认光标 = 「取消」(安全项,index 4)。用户打开菜单后未导航就按电源/播放, * 只会取消关菜单,绝不因「按电源键」本身关机/重启。要真关机必须先导航到「关机」再确认。 */ int sel = PM_NUM - 1; /* 默认取消(安全) */ /* M2.30 MD3:居中圆角卡片背景 + 标题居中 + 圆钮网格。卡片白色柔和描边/深色底。 */ fill_round_rect(PM_CARD_X0, PM_CARD_Y0, PM_CARD_W, PM_CARD_H, PM_CARD_R, 0x141824); fill_round_rect(PM_CARD_X0 + 2, PM_CARD_Y0 + 2, PM_CARD_W - 4, PM_CARD_H - 4, PM_CARD_R - 2, 0x1C2438); /* 卡片顶部标题,水平居中 */ char title[32]; snprintf(title, sizeof title, "POWER MENU"); int title_y = PM_CARD_Y0 + 26; /* 标题在卡片内顶部(卡片顶 115,标题基线 ~141) */ if (mfont_ready) meow_font_drawtext((uint16_t *)fb, (fb_xres - meow_font_width_text(title, 20)) / 2, title_y, title, rgb565(0xFFFFFF), 20); else draw_text((fb_xres - (int)strlen(title) * 6) / 2, title_y, title, 2, 0xFFFFFF); /* 底部提示行(卡片下方,非圆钮所需) */ int hint_y = PM_CARD_Y0 + PM_CARD_H + 10; if (mfont_ready) meow_font_drawtext((uint16_t *)fb, (fb_xres - meow_font_width_text("音量导航 电源确认", 18)) / 2, hint_y, "音量导航 电源确认", rgb565(0x777799), 18); else draw_text((fb_xres - (int)strlen("VOLUME NAV POWER OK") * 5) / 2, hint_y + 1, "VOLUME NAV POWER OK", 1, 0x777799); meow_dirty_full(); /* M2.16:把压暗列表+卡片+标题+(下方圆钮)作为一整帧呈现 */ /* 触摸状态(按下→抬起):统一 meow_touch 接口(goodix 时序免疫,原点由首个有效 ABS 锁) */ meow_touch mt; mt_reset(&mt); int tfd = open(DEV_TOUCH, O_RDONLY | O_NONBLOCK); struct keypoll kp_power, kp_keys; kp_open(&kp_power, DEV_POWER); kp_open(&kp_keys, DEV_KEYS); int prev_vold = 0, prev_volu = 0, prev_play = 0, prev_pwr = 0; kp_poll(&kp_power, NULL, NULL); kp_poll(&kp_keys, NULL, NULL); prev_pwr = kp_is_down(&kp_power, KEY_POWER) ? 1 : 0; prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN) ? 1 : 0; prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP) ? 1 : 0; prev_play = kp_is_down(&kp_keys, KEY_PLAYPAUSE) ? 1 : 0; int act = -1; unsigned long long pm_t0 = now_ms(); unsigned long long pm_last_interact = pm_t0; /* M2.33:菜单空闲自动关闭基准(任何互动刷新) */ int pm_init = 0, last_sel = -1; /* M2.10 Bug:电源菜单 8s 强关(按住电源≥8s=绕过强关)会覆盖用户的菜单操作 —— 用户按住 * 电源打开菜单后(尤其仍按着电源)点选「回到HibyOS/重启」等按钮,8s 一到先触发强关 → 关机 * 而非执行所选动作。修法:一旦用户与菜单互动(音量导航/触摸/播放/电源确认),置 pm_interacted=1 * 取消 8s 强关,让所选动作(如「回到HibyOS」→ reboot RESTART)生效。仅当全程未互动才保留「按住 * 8s=强关」。*/ int pm_interacted = 0; for (;;) { /* dirty 绘制:首次全画;此后仅选中变化才重画受影响两钮(消频闪)→ 标脏 + present。 */ if (!pm_init) { for (int i = 0; i < PM_NUM; i++) draw_pm_button(i, i == sel); pm_init = 1; last_sel = sel; meow_ui_flush(); /* A-1/A-2:SDK present(vsync+帧率门控+blit 脏=全帧,含压暗列表+标题+按钮) */ } else if (sel != last_sel) { draw_pm_button(last_sel, 0); draw_pm_button(sel, 1); /* M2.30 圆形:dirty 区 = 圆(圆心±半径)+ 圆下文字(半径+偏移+行高),四周留 10px */ int dr = (PM_R + 6) + 10, dtxt = PM_R + 26 + 10; meow_dirty_add(pm_cx[last_sel] - dr, pm_cy[last_sel] - dr, dr * 2, dr + dtxt); meow_dirty_add(pm_cx[sel] - dr, pm_cy[sel] - dr, dr * 2, dr + dtxt); last_sel = sel; meow_ui_flush(); /* A-1/A-2:SDK present,blit 两钮区 */ } if (sim_power_pick >= 0 && now_ms() - pm_t0 >= 2000) act = sim_power_pick; int vold = 0, volu = 0, play = 0, pwr = 0; if (kp_keys.ok) { kp_poll(&kp_keys, NULL, NULL); vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN); volu = kp_is_down(&kp_keys, KEY_VOLUMEUP); play = kp_is_down(&kp_keys, KEY_PLAYPAUSE); } if (kp_power.ok) { kp_poll(&kp_power, NULL, NULL); pwr = kp_is_down(&kp_power, KEY_POWER); } if (vold && !prev_vold) { sel = (sel + 1) % PM_NUM; pm_interacted = 1; pm_last_interact = now_ms(); } if (volu && !prev_volu) { sel = (sel - 1 + PM_NUM) % PM_NUM; pm_interacted = 1; pm_last_interact = now_ms(); } /* M2.19:播放键不再作确认(让位给全局媒体控制)。电源菜单的物理确认 * 已由电源键负责(下行),播放键删除,重复确认移除。 */ (void)play; if (pwr && !prev_pwr) { act = sel; pm_interacted = 1; pm_last_interact = now_ms(); } /* 电源新按=确认(非取消) */ prev_vold = vold; prev_volu = volu; prev_play = play; prev_pwr = pwr; /* 触摸:按下(meow_touch 原点锁定,goodix 时序免疫),抬起按按钮命中确认 */ if (tfd >= 0) { struct pollfd pfd = { tfd, POLLIN, 0 }; if (poll(&pfd, 1, 0) > 0) { unsigned char ev[16]; while (read(tfd, ev, sizeof ev) == (ssize_t)sizeof ev) { uint16_t type = *(uint16_t *)(ev + 8), code = *(uint16_t *)(ev + 10); int32_t val = *(int32_t *)(ev + 12); if (type == EV_ABS) { if (code == ABS_X || code == ABS_MT_POSITION_X) mt_abs(&mt, val, mt.last_y); else if (code == ABS_Y || code == ABS_MT_POSITION_Y) mt_abs(&mt, mt.last_x, val); } else if (type == EV_KEY && code == BTN_TOUCH) { if (val && !mt.down) { mt_down(&mt); pm_interacted = 1; pm_last_interact = now_ms(); } else if (!val && mt.down) { pm_interacted = 1; pm_last_interact = now_ms(); int dx, dy; /* M2.25:抬手位移 >= MEOW_TOUCH_SWIPE_THRESH 判滑动(返回0), * 不做确认;否则有效 tap,按下原点命中的按钮即确认。 */ if (mt_up(&mt, &dx, &dy)) { /* M2.30 圆形命中:按下原点距圆心 <= PM_R+6 即命中 */ for (int i = 0; i < PM_NUM; i++) { int ddx = mt.down_x - pm_cx[i], ddy = mt.down_y - pm_cy[i]; int rr = (PM_R + 6) * (PM_R + 6); if (ddx * ddx + ddy * ddy <= rr) { sel = i; act = i; break; } } } } } } } } /* 8s 强关(绕过):仅当电源持续按住、且用户全程未与菜单互动才触发 —— 放在触摸/按键处理 * 之后,避免「用户已点选按钮」的同一轮被强关抢先(M2.10 Bug)。 */ if (pwr && !pm_interacted && now_ms() - pm_t0 >= 5000) { if (sim_no_exec) { logmsg("pm: [sim-no-exec] POWER HOLD 8s -> would force poweroff"); } else { logmsg("pm: POWER HOLD 8s -> force poweroff"); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); } return 1; } /* M2.33 菜单空闲超时自动关闭:菜单受 MeowOS screen_off_timeout 管理(系统界面不豁免)。 * 超过超时无任何互动 → 关闭菜单(视为取消)并自动息屏。目的是:息屏后单击电源亮屏时, * 电源按下信号不会命中菜单按钮(菜单已关),杜绝误触关机/执行菜单动作。 */ if (screen_off_timeout > 0 && (unsigned long long)(now_ms() - pm_last_interact) >= (unsigned long long)screen_off_timeout * 1000) { logmsg("pm: idle %ds -> close menu + auto screen-off (act=cancel)", screen_off_timeout); meow_panel_off(); meow_auto_slept = 1; act = 4; /* 取消(关菜单) */ break; } if (act >= 0) break; usleep(POLL_MS * 1000); } if (tfd >= 0) close(tfd); /* M2.11 B:电源键在菜单 = 按当前项确认。act 与 syscall 类型逐项核对: * act==4(取消) -> 只关菜单,绝不关机(return 0,永不到 reboot); * act==0(关机) -> 才 poweroff;act==1(重启)/act==2(回HibyOS)/act==3(升级模式) -> 才 reboot。 * 只有 act 为 0/1/2/3 才可能执行 sys_do_reboot;power 键本身绝不触发关机。 */ logmsg("pm: act=%d -> %s", act, act == 0 ? "关机" : act == 1 ? "重启" : act == 2 ? "回HibyOS" : act == 3 ? "升级模式" : "取消"); if (act == 4) { logmsg("pm: cancel (close menu only)"); return 0; } if (act == 0) { logmsg("pm: POWER OFF"); if (!sim_no_exec) { /* 先显关机 logo(cmd_jpeg_display 是独立二进制,能正常显图),再直连 poweroff */ system("PATH=/bin:/sbin:/usr/bin:/usr/sbin cmd_jpeg_display /etc/shutdown_logo.jpeg >/dev/null 2>&1"); sys_do_reboot(LINUX_REBOOT_CMD_POWER_OFF); } } else if (act == 1) { logmsg("pm: REBOOT"); if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART); } else if (act == 2) { logmsg("pm: RETURN TO HIBYOS"); set_boot_default_hiby(); if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART); } else if (act == 3) { /* M2.29 升级模式:写 mtd5=ota:kernel2(bootmode.sh Recovery = flash_erase + nandwrite) * 再 reboot —— uboot 读 mtd5=ota:kernel2 引导 kernel2(升级模式,自动刷 TF 卡 * r3proii.upt,双进度条,跑完重启进新固件)。已验证此链路可靠。 */ logmsg("pm: ENTER UPGRADE"); if (!sim_no_exec) { system("PATH=/bin:/sbin:/usr/bin:/usr/sbin /usr/bin/bootmode.sh Recovery >/dev/null 2>&1"); sys_do_reboot(LINUX_REBOOT_CMD_RESTART); } } return 1; } /* M2.6 G「Reboot to player」:MeowOS 常驻模式点「返回播放器」时,播放器已死,弹确认框 * 「返回播放器需重启,现在重启?[是/否]」。是=写选单默认 HibyOS + reboot;否=留在 MeowOS。 * VOL=是/否 切换;PLAY=确认;POWER=取消;触摸点 是/否 确认。风格同电源菜单。 * 返回 1=是(已 reboot,通常不回),0=否/取消(调用方重绘应用列表)。 */ /* 「返回播放器」确认框「是/否」按钮(左右),选中高亮。 * M2.9 Bug 4:改为 dirty 绘制 —— 仅 sel 变化时重画两钮(旧钮取消高亮 + 新钮高亮), * 不随主循环每 10ms 全刷(原实现每帧重画同一内容,与 LCD 刷新竞争产生频闪)。 */ static void draw_cr_button(int sel, int i) { int x0 = (i == 0) ? 80 : 280, y0 = 420, w = 120, h = 60; fill_round_rect(x0, y0, w, h, 12, (i == sel) ? 0x2A3A6A : 0x1A1A2A); const char *lbl = (i == 0) ? "是" : "否"; if (mfont_ready) { int lw = meow_font_width_text(lbl, 20); meow_font_drawtext((uint16_t *)fb, x0 + w / 2 - lw / 2, y0 + 30 - meow_font_line_height(20) / 2, lbl, rgb565((i == sel) ? 0xFFFFFF : 0xC8D0E8), 20); } else { draw_text(x0 + w / 2 - 6, y0 + 24, (i == 0) ? "YES" : "NO", 2, (i == sel) ? 0xFFFFFF : 0xC8D0E8); } } int confirm_reboot_player(void) { dim_screen(); /* M2.8 Bug 3-residual:确认框同电源菜单 —— 若打开前刚经历息屏/blank,LCDC 扫描地址可能 * 非 buffer0;强制 re-pan 让「压暗列表 + 是/否」落在被显示的缓冲。 */ fb_pan_buf0_force(); if (mfont_ready) meow_font_drawtext((uint16_t *)fb, 20, 320, "返回播放器需重启,现在重启?", rgb565(0xFFFFFF), 20); else draw_text(20, 322, "REBOOT TO RETURN TO PLAYER?", 2, 0xFFFFFF); meow_touch mt; mt_reset(&mt); int tfd = open(DEV_TOUCH, O_RDONLY | O_NONBLOCK); struct keypoll kp_power, kp_keys; kp_open(&kp_power, DEV_POWER); kp_open(&kp_keys, DEV_KEYS); int prev_vold = 0, prev_volu = 0, prev_play = 0, prev_pwr = 0; kp_poll(&kp_power, NULL, NULL); kp_poll(&kp_keys, NULL, NULL); prev_pwr = kp_is_down(&kp_power, KEY_POWER) ? 1 : 0; prev_vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN) ? 1 : 0; prev_volu = kp_is_down(&kp_keys, KEY_VOLUMEUP) ? 1 : 0; prev_play = kp_is_down(&kp_keys, KEY_PLAYPAUSE) ? 1 : 0; int sel = 1; /* 默认「否」:不误重启 */ int act = -1; int cr_init = 0, cr_last_sel = -1; /* M2.9 Bug 4:dirty——仅 sel 变化才重画两钮 */ /* 标题/按键提示:打开时画一次(原实现把它们放主循环每 10ms 全刷,与 LCD 刷新竞争 → * 「是/否」钮频闪;改为只在打开/状态变化时绘制)。标题在前面已画一次,这里画提示行。 */ if (mfont_ready) meow_font_drawtext((uint16_t *)fb, 20, 560, "音量切换 电源取消", rgb565(0x666688), 20); else draw_text(20, 562, "VOL NAV POWER EXIT", 1, 0x666688); meow_dirty_full(); /* M2.16:压暗列表+标题+提示作为一整帧呈现 */ for (;;) { /* dirty 绘制:首次全画两钮;此后仅 sel 变化才重画(消频闪)→ 标脏 + present。 */ if (!cr_init) { for (int i = 0; i < 2; i++) draw_cr_button(sel, i); cr_init = 1; cr_last_sel = sel; meow_ui_flush(); } else if (sel != cr_last_sel) { draw_cr_button(sel, cr_last_sel); /* 旧选中:取消高亮 */ draw_cr_button(sel, sel); /* 新选中:高亮 */ meow_dirty_add((cr_last_sel == 0 ? 80 : 280) - 10, 412, 140, 76); meow_dirty_add((sel == 0 ? 80 : 280) - 10, 412, 140, 76); cr_last_sel = sel; meow_ui_flush(); } int vold = 0, volu = 0, play = 0, pwr = 0; if (kp_keys.ok) { kp_poll(&kp_keys, NULL, NULL); vold = kp_is_down(&kp_keys, KEY_VOLUMEDOWN); volu = kp_is_down(&kp_keys, KEY_VOLUMEUP); play = kp_is_down(&kp_keys, KEY_PLAYPAUSE); } if (kp_power.ok) { kp_poll(&kp_power, NULL, NULL); pwr = kp_is_down(&kp_power, KEY_POWER); } if (vold && !prev_vold) sel = (sel + 1) % 2; if (volu && !prev_volu) sel = (sel - 1 + 2) % 2; /* M2.19:播放键不再作「是/确认」(让位给全局媒体控制)。确认框的确认 * 走触摸点选(下方 tfd 命中),电源键=取消(下行);播放键删除。 */ (void)play; if (pwr && !prev_pwr) act = 3; /* 电源=取消 */ prev_vold = vold; prev_volu = volu; prev_play = play; prev_pwr = pwr; if (tfd >= 0) { struct pollfd pfd = { tfd, POLLIN, 0 }; if (poll(&pfd, 1, 0) > 0) { unsigned char ev[16]; while (read(tfd, ev, sizeof ev) == (ssize_t)sizeof ev) { uint16_t type = *(uint16_t *)(ev + 8), code = *(uint16_t *)(ev + 10); int32_t val = *(int32_t *)(ev + 12); if (type == EV_ABS) { if (code == ABS_X || code == ABS_MT_POSITION_X) mt_abs(&mt, val, mt.last_y); else if (code == ABS_Y || code == ABS_MT_POSITION_Y) mt_abs(&mt, mt.last_x, val); } else if (type == EV_KEY && code == BTN_TOUCH) { if (val && !mt.down) { mt_down(&mt); } else if (!val && mt.down) { int dx, dy; if (mt_up(&mt, &dx, &dy)) { for (int i = 0; i < 2; i++) { int x0 = (i == 0) ? 80 : 280; /* 命中「是/否」钮:x∈[x0-8, x0+128], y∈[412, 488](含端点) */ if (mt_in(&mt, x0 - 8, 412, 137, 77)) { sel = i; act = i; break; } } } } } } } } if (act >= 0) break; usleep(POLL_MS * 1000); } if (tfd >= 0) close(tfd); if (act == 0) { logmsg("reboot-to-player: YES -> default HibyOS + reboot"); set_boot_default_hiby(); if (!sim_no_exec) sys_do_reboot(LINUX_REBOOT_CMD_RESTART); return 1; } logmsg("reboot-to-player: cancel"); return 0; }