jcs
/wallops
/amendments
/39
util/focusable: Import newer versions from other projects
jcs made amendment 39 about 1 year ago
--- chatter.c Tue Sep 6 14:21:35 2022
+++ chatter.c Wed Nov 30 23:20:30 2022
@@ -215,7 +215,7 @@ chatter_close(struct focusable *focusable, EventRecord
if (chatter->irc_state < IRC_STATE_CONNECTED) {
irc_abort(chatter);
- close_focusable(focusable);
+ destroy_focusable(focusable);
} else
hide_focusable(focusable);
}
@@ -230,7 +230,7 @@ chatter_quit(struct focusable *focusable)
else
irc_close(chatter);
- close_focusable(focusable);
+ destroy_focusable(focusable);
return true;
}
--- chatter.h Tue Sep 6 12:23:50 2022
+++ chatter.h Wed Nov 30 23:19:19 2022
@@ -19,6 +19,7 @@
#include <stdio.h>
+#include "focusable.h"
#include "irc.h"
#include "tcp.h"
#include "util.h"
@@ -72,25 +73,6 @@
#define WAIT_TYPE_FOREGROUND (1 << 2)
#define WAIT_TYPE_URGENT (1 << 3)
-struct focusable {
- WindowPtr win;
- bool visible;
- void *cookie;
- short (*wait_type)(struct focusable *focusable);
- void (*idle)(struct focusable *focusable, EventRecord *event);
- void (*update)(struct focusable *focusable, EventRecord *event);
- void (*key_down)(struct focusable *focusable, EventRecord *event);
- void (*mouse_down)(struct focusable *focusable, EventRecord *event);
- bool (*menu)(struct focusable *focusable, short menu, short item);
- void (*close)(struct focusable *focusable, EventRecord *event);
- void (*suspend)(struct focusable *focusable, EventRecord *event);
- void (*resume)(struct focusable *focusable, EventRecord *event);
- bool (*quit)(struct focusable *focusable);
- void (*atexit)(struct focusable *focusable);
-};
-extern struct focusable **focusables;
-extern short nfocusables;
-
struct chatter {
struct focusable *focusable;
WindowPtr win;
@@ -123,11 +105,6 @@ struct chatter {
void notify(void);
void cancel_notification(void);
-
-void add_focusable(struct focusable *focusable);
-void show_focusable(struct focusable *focusable);
-void close_focusable(struct focusable *focusable);
-void hide_focusable(struct focusable *focusable);
void chatter_init(const char *server, const unsigned short port,
const char *nick, const char *password, const char *ident,
--- focusable.c Tue Aug 2 15:34:47 2022
+++ focusable.c Tue Aug 2 15:34:47 2022
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2021-2022 joshua stein <jcs@jcs.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "focusable.h"
+#include "util.h"
+
+struct focusable **focusables = NULL;
+short nfocusables = 0;
+
+struct focusable *
+find_focusable(GrafPtr win)
+{
+ short n;
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n]->win == win)
+ return focusables[n];
+ }
+
+ return NULL;
+}
+
+void
+add_focusable(struct focusable *focusable)
+{
+ short n;
+
+ nfocusables++;
+ focusables = xreallocarray(focusables, sizeof(struct focusable *),
+ nfocusables);
+
+ if (nfocusables > 1)
+ for (n = nfocusables - 1; n > 0; n--)
+ focusables[n] = focusables[n - 1];
+
+ focusables[0] = focusable;
+
+ show_focusable(focusable);
+}
+
+void
+show_focusable(struct focusable *focusable)
+{
+ struct focusable *last, *tmp;
+ short n;
+
+ if (nfocusables > 1 && focusables[0] != focusable) {
+ last = focusables[0];
+ focusables[0] = focusable;
+ for (n = 1; n < nfocusables; n++) {
+ tmp = focusables[n];
+ focusables[n] = last;
+ last = tmp;
+ if (last == focusable)
+ break;
+ }
+ }
+
+ focusable->visible = true;
+ ShowWindow(focusable->win);
+ SelectWindow(focusable->win);
+}
+
+void
+destroy_focusable(struct focusable *focusable)
+{
+ short n;
+
+ if (focusable->visible)
+ CloseWindow(focusable->win);
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n] == focusable) {
+ for (; n < nfocusables - 1; n++)
+ focusables[n] = focusables[n + 1];
+ break;
+ }
+ }
+
+ nfocusables--;
+ if (nfocusables)
+ focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
+ else {
+ xfree(&focusables);
+ focusables = NULL;
+ }
+
+ if (nfocusables && focusables[0]->visible)
+ SelectWindow(focusables[0]->win);
+
+ /* focusable is now bogus */
+}
+
+void
+hide_focusable(struct focusable *focusable)
+{
+ short n;
+
+ HideWindow(focusable->win);
+ focusable->visible = false;
+
+ for (n = 0; n < nfocusables; n++) {
+ if (focusables[n] == focusable) {
+ for (; n < nfocusables - 1; n++)
+ focusables[n] = focusables[n + 1];
+ break;
+ }
+ }
+ focusables[nfocusables - 1] = focusable;
+}
--- focusable.h Fri Nov 18 13:30:48 2022
+++ focusable.h Fri Nov 18 13:30:48 2022
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021-2022 joshua stein <jcs@jcs.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __FOCUSABLE_H__
+#define __FOCUSABLE_H__
+
+#include "util.h"
+
+struct focusable {
+ WindowPtr win;
+ bool visible;
+ void *cookie;
+ short (*wait_type)(struct focusable *focusable);
+ void (*idle)(struct focusable *focusable, EventRecord *event);
+ void (*update)(struct focusable *focusable, EventRecord *event);
+ void (*key_down)(struct focusable *focusable, EventRecord *event);
+ void (*mouse_down)(struct focusable *focusable, EventRecord *event);
+ void (*resize)(struct focusable *focusable, EventRecord *event);
+ bool (*menu)(struct focusable *focusable, short menu, short item);
+ void (*close)(struct focusable *focusable, EventRecord *event);
+ void (*suspend)(struct focusable *focusable, EventRecord *event);
+ void (*resume)(struct focusable *focusable, EventRecord *event);
+ bool (*quit)(struct focusable *focusable);
+ void (*atexit)(struct focusable *focusable);
+};
+extern struct focusable **focusables;
+extern short nfocusables;
+
+struct focusable * find_focusable(GrafPtr win);
+void add_focusable(struct focusable *focusable);
+void show_focusable(struct focusable *focusable);
+void destroy_focusable(struct focusable *focusable);
+void hide_focusable(struct focusable *focusable);
+
+#endif
--- main.c Tue Sep 6 16:30:52 2022
+++ main.c Wed Nov 30 23:22:52 2022
@@ -21,8 +21,6 @@
#include "util.h"
MenuHandle apple_menu, file_menu;
-struct focusable **focusables = NULL;
-short nfocusables = 0;
NMRec notification = { 0 };
enum {
@@ -88,6 +86,7 @@ main(void)
InitCursor();
MaxApplZone();
+ util_init();
_atexit(handle_exit);
if (!(mbar = GetNewMBar(MBAR_ID)))
@@ -167,8 +166,10 @@ main(void)
break;
case inContent:
if (event_win != FrontWindow()) {
- if (found_focusable)
+ if (found_focusable) {
+ cancel_notification();
show_focusable(found_focusable);
+ }
}
if (found_focusable && found_focusable->mouse_down)
found_focusable->mouse_down(found_focusable, &event);
@@ -388,15 +389,10 @@ handle_menu(long menu_id)
switch (HiWord(menu_id)) {
case APPLE_MENU_ID:
switch (LoWord(menu_id)) {
- case APPLE_MENU_ABOUT_ID: {
- char vers_s[255];
-
- sprintf(vers_s, "%s %s", PROGRAM_NAME, get_version(true));
- note("%s", vers_s);
-
+ case APPLE_MENU_ABOUT_ID:
+ about(PROGRAM_NAME);
ret = true;
break;
- }
default: {
Str255 da;
GrafPtr save_port;
@@ -456,90 +452,6 @@ handle_exit(void)
if (focusables[n]->atexit)
focusables[n]->atexit(focusables[n]);
}
-}
-
-void
-add_focusable(struct focusable *focusable)
-{
- nfocusables++;
- focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
-
- if (nfocusables > 1)
- memmove(focusables + sizeof(Ptr), focusables,
- sizeof(Ptr) * (nfocusables - 1));
-
- focusables[0] = focusable;
-
- show_focusable(focusable);
-}
-
-void
-show_focusable(struct focusable *focusable)
-{
- struct focusable *last, *tmp;
- short n;
-
- if (nfocusables > 1 && focusables[0] != focusable) {
- last = focusables[0];
- focusables[0] = focusable;
- for (n = 1; n < nfocusables; n++) {
- tmp = focusables[n];
- focusables[n] = last;
- last = tmp;
- if (last == focusable)
- break;
- }
- }
-
- focusable->visible = true;
- ShowWindow(focusable->win);
- SelectWindow(focusable->win);
-
- cancel_notification();
-}
-
-void
-close_focusable(struct focusable *focusable)
-{
- short n;
-
- if (focusable->visible)
- CloseWindow(focusable->win);
-
- for (n = 0; n < nfocusables; n++) {
- if (focusables[n] == focusable) {
- for (; n < nfocusables - 1; n++)
- focusables[n] = focusables[n + 1];
- break;
- }
- }
-
- nfocusables--;
- if (nfocusables)
- focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
- else
- xfree(&focusables);
-
- if (nfocusables && focusables[0]->visible)
- SelectWindow(focusables[0]->win);
-}
-
-void
-hide_focusable(struct focusable *focusable)
-{
- short n;
-
- HideWindow(focusable->win);
- focusable->visible = false;
-
- for (n = 0; n < nfocusables; n++) {
- if (focusables[n] == focusable) {
- for (; n < nfocusables - 1; n++)
- focusables[n] = focusables[n + 1];
- break;
- }
- }
- focusables[nfocusables - 1] = focusable;
}
void
--- util.c Tue Sep 6 15:57:57 2022
+++ util.c Wed Nov 30 23:07:36 2022
@@ -28,25 +28,26 @@
#include <SetUpA4.h>
#include "util.h"
-/* ALRT resources */
-#define ASK_ALERT_ID 130
-
#define ERROR_STRING_SIZE 1024
static char err_str[ERROR_STRING_SIZE];
/* basic DITL with an ok button (1), text area (2), and icon (3) */
+#define ALERT_DITL_OK 1
#define ALERT_DITL_ICON 3
static const char alert_ditl[] = {
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0xE6, 0x00, 0x5A, 0x01, 0x20, 0x04, 0x02,
- 0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
- 0x00, 0x32, 0x00, 0x40, 0x01, 0x21, 0x08, 0x02,
- 0x5E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
- 0x00, 0x0A, 0x00, 0x2A, 0x00, 0x2A, 0xA0, 0x02,
- 0x00, 0x02
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E,
+ 0x00, 0xFA, 0x00, 0x64, 0x01, 0x34, 0x04, 0x02,
+ 0x4F, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
+ 0x00, 0x4E, 0x00, 0x41, 0x01, 0x36, 0x08, 0x02,
+ 0x5E, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
+ 0x00, 0x17, 0x00, 0x2D, 0x00, 0x37, 0xA0, 0x02,
+ 0x00, 0x01
};
static Handle alert_ditl_h = NULL;
+/* ICN# to show for APPICON_ALERT */
+#define APPICON_ICN_ID 128
+
/* DITL with a Yes button (1), No button (2), text (3), and icon (4) */
static const char ask_ditl[] = {
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
@@ -75,7 +76,8 @@ static TEHandle track_control_te = NULL;
enum {
STOP_ALERT,
CAUTION_ALERT,
- NOTE_ALERT
+ NOTE_ALERT,
+ APPICON_ALERT
};
/*
@@ -198,10 +200,19 @@ void
xfree(void *ptrptr)
{
unsigned long *addr = (unsigned long *)ptrptr;
- void *ptr = (void *)*addr;
+ void *ptr;
#ifdef MALLOC_DEBUG
unsigned long n;
+#endif
+ if (ptrptr == NULL)
+ panic("xfree(NULL)");
+
+ ptr = (void *)*addr;
+ if (ptr == NULL)
+ panic("xfree(&NULL) likely a double-free");
+
+#ifdef MALLOC_DEBUG
for (n = 0; n <= malloc_map_size; n++) {
if (n == malloc_map_size)
panic("xfree(0x%lx): can't find in alloc map, likely "
@@ -440,21 +451,21 @@ void
vwarn(short alert_func, const char *format, va_list ap)
{
Rect bounds;
- short hit;
+ short hit, itype;
WindowPtr win, dialog;
-
+ Handle ihandle;
+ Rect irect;
+
GetPort(&win);
vsnprintf(err_str, ERROR_STRING_SIZE, format, ap);
ParamText(CtoPstr(err_str), "\p", "\p", "\p");
- center_in_screen(300, 100, false, &bounds);
+ center_in_screen(320, 110, false, &bounds);
dialog = NewDialog(nil, &bounds, "\p", false, dBoxProc,
(WindowPtr)-1L, false, 0, alert_ditl_h);
-#if 0
- /* XXX: why doesn't changing this work? */
GetDItem(dialog, ALERT_DITL_ICON, &itype, &ihandle, &irect);
switch (alert_func) {
case CAUTION_ALERT:
@@ -463,19 +474,23 @@ vwarn(short alert_func, const char *format, va_list ap
case NOTE_ALERT:
ihandle = GetIcon(noteIcon);
break;
+ case APPICON_ALERT:
+ ihandle = GetResource('ICN#', APPICON_ICN_ID);
+ if (ihandle)
+ break;
default:
ihandle = GetIcon(stopIcon);
}
- ihandle = GetIcon(cautionIcon);
SetDItem(dialog, ALERT_DITL_ICON, itype, ihandle, &irect);
-#endif
-
+
ShowWindow(dialog);
+
for (;;) {
ModalDialog(0, &hit);
if (hit == ok)
break;
}
+ ReleaseResource(ihandle);
DisposDialog(dialog);
/*
@@ -548,6 +563,16 @@ note(const char *format, ...)
va_end(ap);
}
+void
+appicon_note(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vwarn(APPICON_ALERT, format, ap);
+ va_end(ap);
+}
+
short
ask(const char *format, ...)
{
@@ -585,6 +610,38 @@ ask(const char *format, ...)
SetPort(win);
return (hit == 1);
+}
+
+void
+about(char *program_name)
+{
+ VersRecHndl vers;
+ char vers_s[255];
+ char short_vers[255] = { 0 };
+ short vlen, n;
+
+ if ((vers = (VersRecHndl)GetResource('vers', 1))) {
+ /*
+ * vers "long version string" is a pascal string after the
+ * short version pascal string
+ */
+ HLock(vers);
+ vlen = (*vers)->shortVersion[0];
+ memcpy(short_vers, (*vers)->shortVersion + vlen + 1,
+ sizeof((*vers)->shortVersion) - vlen - 1);
+ PtoCstr(short_vers);
+ snprintf(vers_s, sizeof(vers_s), "%s %s", program_name,
+ short_vers);
+ for (n = 0; n < sizeof(vers_s); n++) {
+ if (vers_s[n] == '©') {
+ vers_s[n - 1] = '\r';
+ break;
+ }
+ }
+ ReleaseResource(vers);
+ appicon_note("%s", vers_s);
+ } else
+ warnx("Can't find version number!");
}
void
--- util.h Tue Sep 6 15:53:02 2022
+++ util.h Fri Nov 11 16:57:46 2022
@@ -34,6 +34,11 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define BOUND(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a)))
+/*
+ * If var of var_size (of which used_size is used) is not big enough to
+ * hold add, expand it by grow_amount (to give headroom for subsequent
+ * expansion).
+ */
#define EXPAND_TO_FIT(var, var_size, used_size, add, grow_amount) { \
if ((used_size) + (add) >= (var_size)) { \
while ((used_size) + (add) >= (var_size)) { \
@@ -112,9 +117,11 @@ void err(short ret, const char *format, ...);
void warnx(const char *format, ...);
void warn(const char *format, ...);
void note(const char *format, ...);
+void appicon_note(const char *format, ...);
short ask(const char *format, ...);
#define ASK_YES 1
#define ASK_NO 2
+void about(char *program_name);
void progress(char *format, ...);
void window_rect(WindowPtr win, Rect *ret);
void center_in_screen(short width, short height, bool titlebar, Rect *b);