AmendHub

Download:

jcs

/

subtext

/

amendments

/

55

focusable: Introduce focusable objects

Instead of tracking a current console, track a focusable object that
has callbacks to window-specific functions for things like keyboard
input, mouse input, updating, etc. This lets the main loop not care
about which window is getting input and lets each type of window
(console, settings, etc.) deal with input as it needs to, in its own
file.

jcs made amendment 55 over 2 years ago
--- console.c Sun Jan 2 10:15:25 2022 +++ console.c Mon Jan 17 21:25:13 2022 @@ -30,6 +30,14 @@ #define CONSOLE_PADDING 6 #define CONSOLE_SMOOTH_SCROLLING 0 +void console_idle(struct focusable *focusable, EventRecord *event); +void console_close(struct focusable *focusable, EventRecord *event); +void console_suspend(struct focusable *focusable, EventRecord *event); +void console_resume(struct focusable *focusable, EventRecord *event); +void console_update(struct focusable *focusable, EventRecord *event); +void console_mouse_down(struct focusable *focusable, EventRecord *event); +void console_key_down(struct focusable *focusable, EventRecord *event); + void console_setup(struct session *session); void console_redraw(struct console *console, short force); short console_bound(struct console *console); @@ -42,19 +50,19 @@ struct node_funcs console_node_funcs = { console_setup, console_input, console_output, - console_close + console_close_from_session }; struct console * -console_init(struct console **cur_console) +console_init(void) { char title[64]; struct console *console; + struct focusable *focusable; Rect bounds; short width, height; console = xmalloczero(sizeof(struct console)); - console->cur_console = cur_console; memset(console->chars, ' ', sizeof(console->chars)); console->ncolumns = DEFAULT_TERMINAL_COLUMNS; console->nlines = DEFAULT_TERMINAL_LINES; @@ -66,7 +74,7 @@ console_init(struct console **cur_console) bounds.left = (screenBits.bounds.right - width) / 2; bounds.right = bounds.left + width; - bounds.top = MENUBAR_HEIGHT + + bounds.top = GetMBarHeight() + ((screenBits.bounds.bottom - height) / 2); bounds.bottom = bounds.top + height; @@ -78,9 +86,17 @@ console_init(struct console **cur_console) (WindowPtr)-1L, true, 0); if (!console->win) panic("Can't create window"); + + focusable = xmalloczero(sizeof(struct focusable)); + focusable->win = console->win; + focusable->cookie = console; + focusable->update = console_update; + focusable->key_down = console_key_down; + focusable->close = console_close; + console->focusable = focusable; + SetPort(console->win); - - ShowWindow(console->win); + show_focusable(focusable); console->session = session_create("console", "console", &console_node_funcs); @@ -91,8 +107,6 @@ console_init(struct console **cur_console) strlcpy(console->session->autologin_username, "sysop", sizeof(console->session->autologin_username)); - *cur_console = console; - TextFont(monaco); TextSize(9); @@ -100,26 +114,9 @@ console_init(struct console **cur_console) } void -console_setup(struct session *session) +console_idle(struct focusable *focusable, EventRecord *event) { - struct console *console = (struct console *)session->cookie; - session->terminal_columns = console->ncolumns; - session->terminal_lines = console->nlines; -} - -void -console_close(struct session *session) -{ - struct console *console = (struct console *)session->cookie; - - *(console->cur_console) = NULL; - DisposeWindow(console->win); - free(console); -} - -void -console_idle(struct console *console) -{ + struct console *console = (struct console *)focusable->cookie; struct session *session = console->session; short n, len, cursor, iac = 0; @@ -193,18 +190,19 @@ output_done: } void -console_suspend(struct console *console) +console_suspend(struct focusable *focusable, EventRecord *event) { } void -console_resume(struct console *console) +console_resume(struct focusable *focusable, EventRecord *event) { } void -console_update(struct console *console, EventRecord *event) +console_update(struct focusable *focusable, EventRecord *event) { + struct console *console = (struct console *)focusable->cookie; Rect r; short what = -1; @@ -222,13 +220,14 @@ console_update(struct console *console, EventRecord *e } void -console_mouse_down(struct console *console, EventRecord *event) +console_mouse_down(struct focusable *focusable, EventRecord *event) { } void -console_key_down(struct console *console, EventRecord *event) +console_key_down(struct focusable *focusable, EventRecord *event) { + struct console *console = (struct console *)focusable->cookie; unsigned char k; short km, option_mask, control_mask; @@ -249,11 +248,29 @@ console_key_down(struct console *console, EventRecord } } +void +console_close(struct focusable *focusable, EventRecord *event) +{ + struct console *console = (struct console *)focusable->cookie; + session_close(console->session); + /* session_close will call back to console_close_from_session */ +} + +/* session API */ + +void +console_setup(struct session *session) +{ + struct console *console = (struct console *)session->cookie; + session->terminal_columns = console->ncolumns; + session->terminal_lines = console->nlines; +} + short console_output(struct session *session) { struct console *console = (struct console *)session->cookie; - console_idle(console); + console_idle(console->focusable, NULL); return 0; } @@ -262,6 +279,15 @@ console_input(struct session *session) { /* nothing to do here, input is fed from main loop */ return 0; +} + +void +console_close_from_session(struct session *session) +{ + struct console *console = (struct console *)session->cookie; + close_focusable(console->focusable); + free(console->focusable); + free(console); } short --- console.h Tue Dec 28 17:45:29 2021 +++ console.h Mon Jan 17 20:50:00 2022 @@ -21,7 +21,6 @@ struct console { short state; - struct console **cur_console; WindowPtr win; ControlHandle scroller; short nlines; @@ -42,17 +41,12 @@ struct console { short csilen; char csi[32]; struct session *session; + struct focusable *focusable; }; -struct console *console_init(struct console **cur_console); -void console_idle(struct console *console); -void console_suspend(struct console *console); -void console_resume(struct console *console); -void console_update(struct console *console, EventRecord *event); -void console_mouse_down(struct console *console, EventRecord *event); -void console_key_down(struct console *console, EventRecord *event); +struct console *console_init(void); -void console_close(struct session *session); +void console_close_from_session(struct session *session); short console_output(struct session *session); short console_input(struct session *session); short console_read(struct session *session); --- main.c Sat Jan 15 20:18:37 2022 +++ main.c Tue Jan 18 16:55:58 2022 @@ -21,15 +21,16 @@ #include "console.h" #include "db.h" #include "session.h" +#include "settings.h" #include "telnet.h" #include "uthread.h" #include "util.h" MenuHandle file_menu; short quitting = 0; -struct console *cur_console = NULL; struct db *db = NULL; -short mainResFile; +struct focusable *cur_focusable = NULL; +struct focusable *last_focusable = NULL; void handle_menu(long menu_id); void update_menu(void); @@ -87,8 +88,6 @@ main(void) if (db->config.telnet_port) telnet_init(); - console_init(&cur_console); - iters = 0; while (!quitting) { if (db->config.telnet_port) @@ -105,8 +104,8 @@ main(void) key = event.message & charCodeMask; if ((event.modifiers & cmdKey) != 0) handle_menu(MenuKey(key)); - else if (cur_console) - console_key_down(cur_console, &event); + else if (cur_focusable && cur_focusable->key_down) + cur_focusable->key_down(cur_focusable, &event); break; case mouseDown: event_in = FindWindow(event.where, &event_win); @@ -122,12 +121,21 @@ main(void) DragWindow(event_win, event.where, &screenBits.bounds); break; case inGoAway: - if (TrackGoAway(event_win, event.where) && cur_console) - cur_console->session->ending = 1; + if (TrackGoAway(event_win, event.where) && cur_focusable && + cur_focusable->close) + cur_focusable->close(cur_focusable, &event); break; case inContent: - if (event_win != FrontWindow()) + if (event_win != FrontWindow()) { SelectWindow(event_win); + if (last_focusable && + last_focusable->win == event_win) { + struct focusable *fcur; + fcur = cur_focusable; + cur_focusable = last_focusable; + last_focusable = fcur; + } + } break; } break; @@ -141,8 +149,8 @@ main(void) BeginUpdate(event_win); } - if (cur_console) - console_update(cur_console, &event); + if (cur_focusable && cur_focusable->update) + cur_focusable->update(cur_focusable, &event); if (event.what == updateEvt) { EndUpdate(event_win); @@ -155,13 +163,13 @@ main(void) switch (event.message & (1 << 0)) { case 0: /* suspend */ - if (cur_console) - console_suspend(cur_console); + if (cur_focusable && cur_focusable->suspend) + cur_focusable->suspend(cur_focusable, &event); break; case 1: /* resume */ - if (cur_console) - console_resume(cur_console); + if (cur_focusable && cur_focusable->resume) + cur_focusable->resume(cur_focusable, &event); break; } } @@ -212,6 +220,19 @@ handle_menu(long menu_id) break; } break; + case BBS_MENU_ID: + switch (LoWord(menu_id)) { + case BBS_MENU_VIEWS_ID: + view_editor_show(DB_TEXT_MENU_ID, "Edit: Main menu"); + break; + case BBS_MENU_SETTINGS_ID: + settings_edit(); + break; + case BBS_MENU_OPEN_CONSOLE_ID: + console_init(); + break; + } + break; } HiliteMenu(0); @@ -220,4 +241,27 @@ handle_menu(long menu_id) void update_menu(void) { +} + +void +show_focusable(struct focusable *focusable) +{ + if (cur_focusable) + last_focusable = cur_focusable; + cur_focusable = focusable; + + ShowWindow(focusable->win); +} + +void +close_focusable(struct focusable *focusable) +{ + if (cur_focusable == focusable) { + cur_focusable = NULL; + if (last_focusable) + cur_focusable = last_focusable; + } else if (last_focusable == focusable) + last_focusable = NULL; + + CloseWindow(focusable->win); } --- session.c Wed Jan 5 13:43:19 2022 +++ session.c Mon Jan 17 20:53:34 2022 @@ -94,7 +94,7 @@ session_run(struct uthread *uthread, void *arg) session_flush(s); if (session_login(s) != AUTH_USER_OK) { - session_close(&s); + session_close(s); return; } @@ -166,29 +166,29 @@ get_another_char: } } - session_close(&s); + session_close(s); } void -session_close(struct session **session) +session_close(struct session *session) { struct session **newsessions; unsigned long now; short newnsessions, n; - if (!(*session)->ending) { + if (!session->ending) { /* give 1 second to flush output */ now = Ticks; - while ((*session)->obuflen && (Ticks - now) < 60) { - (*session)->node_funcs->output(*session); + while (session->obuflen && (Ticks - now) < 60) { + session->node_funcs->output(session); uthread_yield(); } - (*session)->ending = 1; + session->ending = 1; } /* close the node */ - (*session)->node_funcs->close(*session); + session->node_funcs->close(session); /* remove session from sessions */ newnsessions = nsessions - 1; @@ -196,7 +196,7 @@ session_close(struct session **session) newsessions = xmallocarray(newnsessions, sizeof(struct session)); nsessions = 0; for (n = 0; n < newnsessions; n++) { - if (sessions[n] == *session) + if (sessions[n] == session) continue; newsessions[nsessions++] = sessions[n]; } @@ -207,8 +207,7 @@ session_close(struct session **session) free(sessions); sessions = newsessions; - free(*session); - *session = NULL; + free(session); } size_t @@ -574,24 +573,21 @@ session_load_view(struct session *session, short id, c char curvar[64]; struct tm *now; size_t retsize = 1024, retpos = 0; - size_t hsize, vallen; - Handle h; + size_t vsize, vallen; short n, j, invar = 0, varlen = 0, valsize, count, pad; + char *view; char c; - h = Get1Resource(DB_TEXT_TYPE, id); - if (!h) + vsize = bile_read_alloc(db->bile, DB_TEXT_TYPE, id, &view); + if (vsize == 0) return 0; - hsize = GetHandleSize(h); - - *ret = xmalloc(retsize); + retpos = 0; - HLock(h); - for (n = 0; n < hsize; n++) { - c = (*h)[n]; + for (n = 0; n < vsize; n++) { + c = view[n]; - if (c == '%' && (*h)[n + 1] == '%') { + if (c == '%' && view[n + 1] == '%') { n++; if (!invar) { invar = 1; @@ -647,7 +643,7 @@ session_load_view(struct session *session, short id, c } else if (invar) { if (varlen < sizeof(curvar) - 2) curvar[varlen++] = c; - } else if (c == '\r' && (*h)[n + 1] != '\n') { + } else if (c == '\r' && view[n + 1] != '\n') { EXPAND_TO_FIT(*ret, retsize, retpos, 2); (*ret)[retpos++] = '\r'; (*ret)[retpos++] = '\n'; --- session.h Wed Jan 5 12:34:53 2022 +++ session.h Mon Jan 17 21:01:23 2022 @@ -85,7 +85,7 @@ extern short nsessions; struct session *session_create(char *node, char *via, struct node_funcs *node_funcs); -void session_close(struct session **session); +void session_close(struct session *session); void session_idle(struct session *session); char session_input_char(struct session *session); void session_flush(struct session *session); --- subtext.h Sun Dec 5 22:16:23 2021 +++ subtext.h Tue Jan 18 16:55:36 2022 @@ -17,8 +17,6 @@ #ifndef __SUBTEXT_H__ #define __SUBTEXT_H__ -#include "db.h" - #define PROGRAM_NAME "Subtext" #define MBAR_ID 128 @@ -29,10 +27,44 @@ #define FILE_MENU_ID 129 #define FILE_MENU_QUIT_ID 1 +#define BBS_MENU_ID 130 +#define BBS_MENU_BOARDS_ID 1 +#define BBS_MENU_FILES_ID 2 +#define BBS_MENU_USERS_ID 3 +#define BBS_MENU_VIEWS_ID 4 +#define BBS_MENU_SETTINGS_ID 5 +#define BBS_MENU_OPEN_CONSOLE_ID 7 + #define STR_LAST_DB 128 +#define SETTINGS_DLOG_ID 130 +#define SETTINGS_BBS_NAME_ID 3 +#define SETTINGS_PHONE_ID 4 +#define SETTINGS_LOCATION_ID 5 +#define SETTINGS_HOSTNAME_ID 6 +#define SETTINGS_TELNET_PORT_ID 7 + +#define SETTINGS_EDIT_VIEW_DLOG_ID 131 + +#include "db.h" + extern struct db *db; -extern short mainResFile; extern MenuHandle file_menu; + +struct focusable { + WindowPtr win; + void *cookie; + void (*update)(struct focusable *focusable, EventRecord *event); + void (*key_down)(struct focusable *focusable, EventRecord *event); + void (*mouse_down)(struct focusable *focusable, EventRecord *event); + void (*close)(struct focusable *focusable, EventRecord *event); + void (*suspend)(struct focusable *focusable, EventRecord *event); + void (*resume)(struct focusable *focusable, EventRecord *event); +}; +extern struct focusable *cur_focusable; +extern struct focusable *last_focusable; + +void show_focusable(struct focusable *focusable); +void close_focusable(struct focusable *focusable); #endif /* __SUBTEXT_H__ */