AmendHub

jcs

/

subtext

/

amendments

/

159

blanker: Add a simple screen blanker

This will trigger after the configured number of idle seconds, when
there are no active sessions. A mouse click or key press will unblank
right away, otherwise it will unblank automatically after the
configured number of runtime seconds.
This is a more CPU-friendly alternative to a normal screen saver, and
it will only run for a short amount of time to do its job of blanking
the screen to prevent burn-in.

jcs made amendment 159 about 1 month ago
--- db.c Fri Jun 17 13:49:25 2022 +++ db.c Tue Jun 21 16:16:07 2022 @@ -59,6 +59,12 @@ struct struct_field config_fields[] = { { "Allow Open Signup", CONFIG_TYPE_BOOLEAN, offsetof(struct config, open_signup), 0, 0 }, + { "Screen Blanker Idle Seconds", CONFIG_TYPE_SHORT, + offsetof(struct config, blanker_idle_seconds), + 1, USHRT_MAX }, + { "Screen Blanker Runtime Seconds", CONFIG_TYPE_SHORT, + offsetof(struct config, blanker_runtime_seconds), + 1, USHRT_MAX }, }; size_t nconfig_fields = nitems(config_fields); @@ -245,6 +251,8 @@ db_migrate(struct db *tdb, short is_new) sprintf(tdb->config.modem_init, "ATQ0V1S0=2"); tdb->config.max_idle_minutes = 5; tdb->config.max_login_seconds = 90; + tdb->config.blanker_idle_seconds = (60 * 60); + tdb->config.blanker_runtime_seconds = 30; db_config_save(tdb); /* create a default sysop user */ @@ -316,6 +324,20 @@ db_migrate(struct db *tdb, short is_new) bile_write(tdb->bile, DB_CONFIG_RTYPE, 1, &new_config, sizeof(new_config)); + break; + } + case 4: { + /* 4->5, added blanker fields */ + struct config new_config = { 0 }; + + bile_read(tdb->bile, DB_CONFIG_RTYPE, 1, (char *)&new_config, + sizeof(new_config)); + new_config.blanker_idle_seconds = (60 * 60); + new_config.blanker_runtime_seconds = 30; + + bile_write(tdb->bile, DB_CONFIG_RTYPE, 1, &new_config, + sizeof(new_config)); + break; } } --- db.h Sun Jun 12 21:05:26 2022 +++ db.h Tue Jun 21 15:43:59 2022 @@ -23,7 +23,7 @@ #define DB_TYPE 'STDB' -#define DB_CUR_VERS 4 +#define DB_CUR_VERS 5 #define DB_TRUE 0x100 #define DB_FALSE 0x000 @@ -70,6 +70,8 @@ struct config { char timezone[8]; short open_signup; short max_login_seconds; + short blanker_idle_seconds; + short blanker_runtime_seconds; }; extern struct struct_field config_fields[]; --- logger.c Thu Jun 16 09:43:41 2022 +++ logger.c Tue Jun 21 15:43:14 2022 @@ -252,6 +252,7 @@ logger_vprintf(struct logger *logger, const char *form if (!logger) return 0; + blanker_unblank(); len = 0; if ((*(logger->messages_te))->teLength > 0) { --- main.c Thu Jun 16 13:39:27 2022 +++ main.c Tue Jun 21 16:12:17 2022 @@ -34,8 +34,13 @@ MenuHandle file_menu; short quitting = 0; struct db *db = NULL; struct logger *logger = NULL; +bool blanker_on = false; +unsigned long blanker_last_blank = 0; +WindowPtr blanker_win = NULL; + bool handle_menu(long menu_id); void handle_exit(void); +void blanker_idle(void); int main(void) @@ -50,7 +55,6 @@ main(void) short event_in, n, finder_action, finder_count; char key; - util_init(); uthread_init(); InitGraf(&thePort); @@ -63,6 +67,8 @@ main(void) InitCursor(); MaxApplZone(); + util_init(); + if (!(mbar = GetNewMBar(MBAR_ID))) panic("no mbar"); SetMenuBar(mbar); @@ -100,17 +106,21 @@ main(void) if (db->config.modem_port) serial_init(); + blanker_last_blank = Time; + while (!quitting) { if (db->config.telnet_port) telnet_idle(); if (db->config.modem_port) serial_idle(); - + uthread_coordinate(); SystemTask(); - if (!GetNextEvent(everyEvent, &event)) + if (!GetNextEvent(everyEvent, &event)) { + blanker_idle(); continue; + } switch (event.what) { case nullEvent: @@ -121,11 +131,15 @@ main(void) break; case keyDown: case autoKey: + if (blanker_on) { + blanker_unblank(); + break; + } key = event.message & charCodeMask; if ((event.modifiers & cmdKey) != 0 && handle_menu(MenuKey(key)) == true) break; - if (nfocusables && focusables[0]->visible && + else if (nfocusables && focusables[0]->visible && focusables[0]->key_down) focusables[0]->key_down(focusables[0], &event); break; @@ -151,6 +165,10 @@ main(void) } break; case inContent: + if (blanker_on) { + blanker_unblank(); + break; + } found_focusable = find_focusable(event_win); if (event_win != FrontWindow()) { if (found_focusable) @@ -214,6 +232,8 @@ handle_exit(void) focusables[n]->atexit(focusables[n]); } + RestoreHiddenMenuBar(); + if (db->config.telnet_port) telnet_atexit(); if (db->config.modem_port) @@ -310,4 +330,45 @@ handle_menu(long menu_id) HiliteMenu(0); return ret; +} + +void +blanker_idle(void) +{ + unsigned long t; + + if (!blanker_on && + (Time - blanker_last_blank > db->config.blanker_idle_seconds)) { + HideMenuBar(); + + blanker_win = NewWindow(0L, &screenBits.bounds, "\p", false, + plainDBox, (WindowPtr)-1L, true, 0); + if (!blanker_win) + panic("NewWindow failed"); + ShowWindow(blanker_win); + SetPort(blanker_win); + HideCursor(); + FillRect(&screenBits.bounds, black); + blanker_last_blank = Time; + blanker_on = true; + return; + } + + if (blanker_on && (nsessions || + (Time - blanker_last_blank > db->config.blanker_runtime_seconds))) + blanker_unblank(); +} + +void +blanker_unblank(void) +{ + if (!blanker_on || !blanker_win) + return; + + ShowCursor(); + DisposeWindow(blanker_win); + blanker_win = NULL; + RestoreHiddenMenuBar(); + blanker_last_blank = Time; + blanker_on = false; } --- subtext.h Tue Jun 7 21:46:23 2022 +++ subtext.h Tue Jun 21 15:42:02 2022 @@ -72,6 +72,8 @@ extern struct db *db; extern MenuHandle file_menu; extern struct logger *logger; +void blanker_unblank(void); + short strcasecmp(const char *s1, const char *s2); short strncasecmp(const char *s1, const char *s2, size_t n); --- util.c Wed Jun 15 13:30:55 2022 +++ util.c Tue Jun 21 15:17:17 2022 @@ -1281,3 +1281,59 @@ NullCaretHook(void) rts } } + +static bool menu_bar_hidden = false; +static short old_mbar_height; +static Rect mbar_rect; +static RgnHandle mbar_save_region; + +void +HideMenuBar(void) +{ + RgnHandle mbar_region; + WindowPeek win; + + old_mbar_height = GetMBarHeight(); + SetRect(&mbar_rect, screenBits.bounds.left, screenBits.bounds.top, + screenBits.bounds.right, screenBits.bounds.top + old_mbar_height); + + mbar_save_region = NewRgn(); + mbar_region = NewRgn(); + + MBarHeight = 0; + CopyRgn(GetGrayRgn(), mbar_save_region); + RectRgn(mbar_region, &mbar_rect); + UnionRgn(GetGrayRgn(), mbar_region, GetGrayRgn()); + + win = (WindowPeek)FrontWindow(); + PaintOne(win, mbar_region); + PaintBehind(win, mbar_region); + CalcVis(win); + CalcVisBehind(win, mbar_region); + DisposeRgn(mbar_region); + + menu_bar_hidden = true; +} + +void +RestoreHiddenMenuBar(void) +{ + WindowPeek win; + + if (!menu_bar_hidden) + return; + + CopyRgn(mbar_save_region, GetGrayRgn()); + MBarHeight = old_mbar_height; + + RectRgn(mbar_save_region, &mbar_rect); + win = (WindowPeek)FrontWindow(); + CalcVis(win); + CalcVisBehind(win, mbar_save_region); + DisposeRgn(mbar_save_region); + + menu_bar_hidden = false; + + HiliteMenu(0); + DrawMenuBar(); +} --- util.h Wed Jun 1 13:12:07 2022 +++ util.h Tue Jun 21 14:29:38 2022 @@ -132,5 +132,7 @@ pascal bool PasswordDialogFieldFilter(DialogPtr dlg, E short *hit); void PasswordDialogFieldFinish(void); pascal void NullCaretHook(void); +void HideMenuBar(void); +void RestoreHiddenMenuBar(void); #endif