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 over 2 years 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