From 192aa666ca2d7da6d60e4cd44c3536296daac65c Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 14 Nov 2023 00:18:51 -0500 Subject: [PATCH] Refactor replicant system a bit --- libXmd/include/Xmd/Replicant.h | 11 ++-- libXmd/src/Replicant.c | 103 +++++++++++++++++---------------- replicants/Launcher/src/main.c | 7 ++- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/libXmd/include/Xmd/Replicant.h b/libXmd/include/Xmd/Replicant.h index 6158c86..4570380 100644 --- a/libXmd/include/Xmd/Replicant.h +++ b/libXmd/include/Xmd/Replicant.h @@ -15,7 +15,7 @@ typedef int (*XmdReplicantFnVersion) (); typedef void (*XmdReplicantFnConstruct) (); typedef void (*XmdReplicantFnDestruct) (); typedef Widget (*XmdReplicantFnCreate) ( - Widget parent, XmdReplicantState *state); + XtAppContext application, Widget parent, XmdReplicantState *state); /* XmdReplicantOpen opens a replicant from the file located at path. Replicant files hold state and point to shared object files containing their code. @@ -41,15 +41,16 @@ typedef Widget (*XmdReplicantFnCreate) ( different API version will refuse to load it. void NAME_XmdReplicantConstruct (); - Construct is called when the shared object is loaded. + Optional. Construct is called when the shared object is loaded. void NAME_XmdReplicantDestruct (); - Descruct is called before the shared object is unloaded. + Optional. Descruct is called before the shared object is unloaded. - Widget NAME_XmdReplicantCreate (Widget parent, XmdReplicantState *state); + Widget NAME_XmdReplicantCreate ( + XtAppContext application, Widget parent, XmdReplicantState *state); Create instantiates a new widget representing the replicant given by state. */ -Widget XmdReplicantOpen (Widget parent, ConstString path); +Widget XmdReplicantOpen (XtAppContext app, Widget parent, ConstString path); /* XmdReplicantResolveName returns the file path of the given replicant shared object name according to $XMD_REPLICANT_PATH. The returned string must be diff --git a/libXmd/src/Replicant.c b/libXmd/src/Replicant.c index 32a8785..413817c 100644 --- a/libXmd/src/Replicant.c +++ b/libXmd/src/Replicant.c @@ -21,80 +21,81 @@ typedef struct { XmdReplicantFnDestruct destruct; XmdReplicantFnCreate create; } symbols; -} XmdReplicantSource; +} replicantSource; struct _XmdReplicantState { String file; String sourceName; - XmdReplicantSource *source; + replicantSource *source; XmdStringMap *map; }; -static void XmdReplicantHandleDestroy ( - Widget replicant, - XtPointer clientData, - XtPointer callData); -static XmdError XmdReplicantStateSave (XmdReplicantState *state); -static XmdError XmdReplicantStateLoad (XmdReplicantState *state); -static XmdReplicantState *XmdReplicantStateNew (); -static void XmdReplicantStateFree (XmdReplicantState *state); -static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name); -static void XmdReplicantSourceClose (XmdReplicantSource *source); -static XmdReplicantSource *XmdReplicantSourceGet (ConstString name); -static String XmdReplicantScanDir ( - ConstString path, - ConstString name); -static void XmdReplicantEnsure (); +/* internal function prototypes */ +static void handleDestroy (Widget, XtPointer, XtPointer); +static XmdError stateSave (XmdReplicantState *state); +static XmdError stateLoad (XmdReplicantState *state); +static XmdReplicantState *stateNew (); +static void stateFree (XmdReplicantState *state); +static replicantSource *sourceOpen (ConstString name); +static void sourceClose (replicantSource *source); +static replicantSource *sourceGet (ConstString name); +static String scanDir (ConstString path, ConstString name); +static void ensure (); +static String readEscapedMapString (FILE *, char); +static void writeEscapedMapString (FILE *, ConstString); +static Bool freeMapValue (XmdStringMap *, ConstString, void *, void *); +static Bool writeMapValue (XmdStringMap *, ConstString, void *, void *); +/* resident maps source names to source structs */ +static XmdStringMap *resident = NULL; static const String defaultReplicantPath = - "/usr/lib/Xmd/replicants:" - "/usr/local/lib/Xmd/replicants"; -static XmdStringMap *resident = NULL; /* source names to source structs */ + "/usr/local/lib/Xmd/replicants:" + "/usr/lib/Xmd/replicants"; -Widget XmdReplicantOpen (Widget parent, ConstString path) { +Widget XmdReplicantOpen (XtAppContext app, Widget parent, ConstString path) { /* create and load the state */ - XmdReplicantState *state = XmdReplicantStateNew(); + XmdReplicantState *state = stateNew(); if (state == NULL) goto fail; state->file = XtNewString(path); if (state->file == NULL) goto fail; - XmdReplicantStateLoad(state); + stateLoad(state); /* retrieve the replicant's source */ - XmdReplicantSource *source = XmdReplicantSourceGet(state->sourceName); + replicantSource *source = sourceGet(state->sourceName); if (source == NULL) goto fail; source->references ++; state->source = source; /* create replicant and bind its state */ - Widget replicant = source->symbols.create(parent, state); + Widget replicant = source->symbols.create(app, parent, state); XtAddCallback ( replicant, XmNdestroyCallback, - XmdReplicantHandleDestroy, state); + handleDestroy, state); return replicant; fail: - XmdReplicantStateFree(state); + stateFree(state); return NULL; } -static void XmdReplicantHandleDestroy ( +static void handleDestroy ( Widget replicant, XtPointer clientData, XtPointer callData ) { (void)(replicant); (void)(callData); - XmdReplicantEnsure(); + ensure(); XmdReplicantState *state = clientData; if (state == NULL) return; state->source->references --; if (state->source->references < 1) { - XmdReplicantSourceClose ( + sourceClose ( XmdStringMapSet(resident, state->sourceName, NULL)); } - XmdReplicantStateFree(state); + stateFree(state); } String XmdReplicantResolveName (ConstString rawName) { @@ -114,7 +115,7 @@ String XmdReplicantResolveName (ConstString rawName) { XmdBufferPush(dirBuffer, &null); String dir = XmdBufferBreak(dirBuffer); dirBuffer = NULL; - file = XmdReplicantScanDir(dir, name); + file = scanDir(dir, name); XtFree(dir); } else { XmdBufferPush(dirBuffer, &ch); @@ -135,7 +136,7 @@ void XmdReplicantStateStore ( ) { String old = XmdStringMapSet(state->map, name, XtNewString(value)); XtFree(old); - XmdReplicantStateSave(state); + stateSave(state); } static void writeEscapedMapString (FILE *file, ConstString string) { @@ -180,7 +181,7 @@ static Bool writeMapValue ( return True; } -static XmdError XmdReplicantStateSave (XmdReplicantState *state) { +static XmdError stateSave (XmdReplicantState *state) { FILE *file = fopen(state->file, "w"); if (file == NULL) return XmdErrorCantOpenFile; fprintf(file, "[%s]\n", state->sourceName); @@ -217,7 +218,7 @@ static String readEscapedMapString (FILE *file, char delimiter) { return XmdBufferBreak(string); } -static XmdError XmdReplicantStateLoad (XmdReplicantState *state) { +static XmdError stateLoad (XmdReplicantState *state) { if (state->sourceName != NULL) XtFree(state->sourceName); state->sourceName = NULL; @@ -256,7 +257,7 @@ static XmdError XmdReplicantStateLoad (XmdReplicantState *state) { } } -static XmdReplicantState *XmdReplicantStateNew () { +static XmdReplicantState *stateNew () { XmdReplicantState *state = XtNew(XmdReplicantState); if (state == NULL) return NULL; @@ -266,7 +267,7 @@ static XmdReplicantState *XmdReplicantStateNew () { return state; fail: - XmdReplicantStateFree(state); + stateFree(state); return NULL; } @@ -282,7 +283,7 @@ static Bool freeMapValue ( return True; } -static void XmdReplicantStateFree (XmdReplicantState *state) { +static void stateFree (XmdReplicantState *state) { if (state == NULL) return; XtFree(state->file); XtFree(state->sourceName); @@ -291,11 +292,11 @@ static void XmdReplicantStateFree (XmdReplicantState *state) { XtFree((char *)(state)); } -static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name) { +static replicantSource *sourceOpen (ConstString name) { /* allocate */ - XmdReplicantSource *source = XtNew(XmdReplicantSource); + replicantSource *source = XtNew(replicantSource); if (source == NULL) goto fail; - memset(source, 0, sizeof(XmdReplicantSource)); + memset(source, 0, sizeof(replicantSource)); /* open library */ String path = XmdReplicantResolveName(name); @@ -316,13 +317,11 @@ static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name) { source->symbols.construct = (XmdReplicantFnConstruct) ( dlsym(source->handle, symbolName)); XtFree(symbolName); - if (source->symbols.construct == NULL) goto fail; XtAsprintf(&symbolName, "%s_XmdReplicantDestruct", name); source->symbols.destruct = (XmdReplicantFnDestruct) ( dlsym(source->handle, symbolName)); XtFree(symbolName); - if (source->symbols.destruct == NULL) goto fail; XtAsprintf(&symbolName, "%s_XmdReplicantCreate", name); source->symbols.create = (XmdReplicantFnCreate) ( @@ -333,31 +332,33 @@ static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name) { /* check if the version matches */ if (source->symbols.version() != XmdREPLICANT_VERSION) goto fail; + if (source->symbols.construct != NULL) source->symbols.construct(); return source; fail: - XmdReplicantSourceClose(source); + sourceClose(source); return NULL; } -static void XmdReplicantSourceClose (XmdReplicantSource *source) { +static void sourceClose (replicantSource *source) { if (source == NULL) return; + if (source->symbols.destruct != NULL) source->symbols.destruct(); if (source->handle != NULL) dlclose(source->handle); XtFree((char *)(source)); } -static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) { - XmdReplicantEnsure(); +static replicantSource *sourceGet (ConstString name) { + ensure(); /* check to see if it has already been loaded */ - XmdReplicantSource *source = XmdStringMapGet(resident, name); + replicantSource *source = XmdStringMapGet(resident, name); if (source != NULL) return source; /* open the source */ - return XmdReplicantSourceOpen(name); + return sourceOpen(name); } -static String XmdReplicantScanDir (ConstString path, ConstString name) { +static String scanDir (ConstString path, ConstString name) { DIR *dir = opendir(path); if (dir == NULL) return NULL; @@ -375,7 +376,7 @@ static String XmdReplicantScanDir (ConstString path, ConstString name) { return result; } -static void XmdReplicantEnsure () { +static void ensure () { if (resident == NULL) { resident = XmdStringMapNew(); } diff --git a/replicants/Launcher/src/main.c b/replicants/Launcher/src/main.c index 95082a2..3b75ad7 100644 --- a/replicants/Launcher/src/main.c +++ b/replicants/Launcher/src/main.c @@ -47,7 +47,11 @@ void handleDestroyFreePixmap ( XFreePixmap(XtDisplay(replicant), (Pixmap)(clientData)); } -Widget Launcher_XmdReplicantCreate (Widget parent, XmdReplicantState *state) { +Widget Launcher_XmdReplicantCreate ( + XtAppContext application, + Widget parent, + XmdReplicantState *state, +) { String iconName = XmdReplicantStateQuery(state, "Icon"); Pixmap icon; #define iconCase(name) if (strcmp(#name, iconName) == 0) {\ @@ -61,6 +65,7 @@ Widget Launcher_XmdReplicantCreate (Widget parent, XmdReplicantState *state) { iconCase(WebBrowser) iconCase(Music) icon = XmdLoadBitmapIcon(parent, unknown); + #undef iconCase XtFree(iconName);