First replicant yay
This commit is contained in:
parent
55dfca6341
commit
a6fa746ef3
10
libXmd/include/Xmd/Dir.h
Normal file
10
libXmd/include/Xmd/Dir.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _XmdDir_h
|
||||||
|
#define _XmdDir_h
|
||||||
|
|
||||||
|
#include <X11/Intrinsic.h>
|
||||||
|
|
||||||
|
/* XmdDirGetUser returns the location of the Xmd user directory, which is
|
||||||
|
located at $HOME/.Xmd */
|
||||||
|
String XmdDirGetUser ();
|
||||||
|
|
||||||
|
#endif
|
12
libXmd/include/Xmd/Error.h
Normal file
12
libXmd/include/Xmd/Error.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _XmdError_h
|
||||||
|
#define _XmdError_h
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
XmdErrorNone,
|
||||||
|
XmdErrorOutOfMemory,
|
||||||
|
XmdErrorFileNotFound,
|
||||||
|
XmdErrorCantOpenFile,
|
||||||
|
XmdErrorBadSyntax
|
||||||
|
} XmdError;
|
||||||
|
|
||||||
|
#endif
|
@ -11,8 +11,11 @@
|
|||||||
/* XmdReplicantState contains state information for a replicant instance. */
|
/* XmdReplicantState contains state information for a replicant instance. */
|
||||||
typedef struct _XmdReplicantState XmdReplicantState;
|
typedef struct _XmdReplicantState XmdReplicantState;
|
||||||
|
|
||||||
typedef int (*XmdReplicantVersion) ();
|
typedef int (*XmdReplicantFnVersion) ();
|
||||||
typedef Widget (*XmdReplicantCreate) (Widget parent, XmdReplicantState *state);
|
typedef void (*XmdReplicantFnConstruct) ();
|
||||||
|
typedef void (*XmdReplicantFnDestruct) ();
|
||||||
|
typedef Widget (*XmdReplicantFnCreate) (
|
||||||
|
Widget parent, XmdReplicantState *state);
|
||||||
|
|
||||||
/* XmdReplicantOpen opens a replicant from the file located at path. Replicant
|
/* XmdReplicantOpen opens a replicant from the file located at path. Replicant
|
||||||
files hold state and point to shared object files containing their code.
|
files hold state and point to shared object files containing their code.
|
||||||
@ -36,6 +39,12 @@ typedef Widget (*XmdReplicantCreate) (Widget parent, XmdReplicantState *state);
|
|||||||
Version must return the value of XmdREPLICANT_VERSION. This is used to detect
|
Version must return the value of XmdREPLICANT_VERSION. This is used to detect
|
||||||
the API version that the replicant was compiled with, and applications with a
|
the API version that the replicant was compiled with, and applications with a
|
||||||
different API version will refuse to load it.
|
different API version will refuse to load it.
|
||||||
|
|
||||||
|
void NAME_XmdReplicantConstruct ();
|
||||||
|
Construct is called when the shared object is loaded.
|
||||||
|
|
||||||
|
void NAME_XmdReplicantDestruct ();
|
||||||
|
Descruct is called before the shared object is unloaded.
|
||||||
|
|
||||||
Widget NAME_XmdReplicantCreate (Widget parent, XmdReplicantState *state);
|
Widget NAME_XmdReplicantCreate (Widget parent, XmdReplicantState *state);
|
||||||
Create instantiates a new widget representing the replicant given by state.
|
Create instantiates a new widget representing the replicant given by state.
|
||||||
|
8
libXmd/src/Dir.c
Normal file
8
libXmd/src/Dir.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include <Xmd/Dir.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
String XmdDirGetUser () {
|
||||||
|
String dir = NULL;
|
||||||
|
XtAsprintf(&dir, "%s/.Xmd", getenv("HOME"));
|
||||||
|
return dir;
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#include <Xmd/StringMap.h>
|
#include <Xmd/StringMap.h>
|
||||||
#include <Xmd/Map.h>
|
#include <Xmd/Map.h>
|
||||||
#include <Xmd/Buffer.h>
|
#include <Xmd/Buffer.h>
|
||||||
|
#include <Xmd/Error.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -15,8 +16,10 @@ typedef struct {
|
|||||||
int references;
|
int references;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
XmdReplicantVersion version;
|
XmdReplicantFnVersion version;
|
||||||
XmdReplicantCreate create;
|
XmdReplicantFnConstruct construct;
|
||||||
|
XmdReplicantFnDestruct destruct;
|
||||||
|
XmdReplicantFnCreate create;
|
||||||
} symbols;
|
} symbols;
|
||||||
} XmdReplicantSource;
|
} XmdReplicantSource;
|
||||||
|
|
||||||
@ -31,8 +34,8 @@ static void XmdReplicantHandleDestroy (
|
|||||||
Widget replicant,
|
Widget replicant,
|
||||||
XtPointer clientData,
|
XtPointer clientData,
|
||||||
XtPointer callData);
|
XtPointer callData);
|
||||||
static void XmdReplicantStateSave (XmdReplicantState *state);
|
static XmdError XmdReplicantStateSave (XmdReplicantState *state);
|
||||||
static void XmdReplicantStateLoad (XmdReplicantState *state);
|
static XmdError XmdReplicantStateLoad (XmdReplicantState *state);
|
||||||
static XmdReplicantState *XmdReplicantStateNew ();
|
static XmdReplicantState *XmdReplicantStateNew ();
|
||||||
static void XmdReplicantStateFree (XmdReplicantState *state);
|
static void XmdReplicantStateFree (XmdReplicantState *state);
|
||||||
static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name);
|
static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name);
|
||||||
@ -41,6 +44,7 @@ static XmdReplicantSource *XmdReplicantSourceGet (ConstString name);
|
|||||||
static String XmdReplicantScanDir (
|
static String XmdReplicantScanDir (
|
||||||
ConstString path,
|
ConstString path,
|
||||||
ConstString name);
|
ConstString name);
|
||||||
|
static void XmdReplicantEnsure ();
|
||||||
|
|
||||||
static const String defaultReplicantPath =
|
static const String defaultReplicantPath =
|
||||||
"/usr/lib/Xmd/replicants:"
|
"/usr/lib/Xmd/replicants:"
|
||||||
@ -80,6 +84,7 @@ static void XmdReplicantHandleDestroy (
|
|||||||
) {
|
) {
|
||||||
(void)(replicant);
|
(void)(replicant);
|
||||||
(void)(callData);
|
(void)(callData);
|
||||||
|
XmdReplicantEnsure();
|
||||||
|
|
||||||
XmdReplicantState *state = clientData;
|
XmdReplicantState *state = clientData;
|
||||||
if (state == NULL) return;
|
if (state == NULL) return;
|
||||||
@ -104,12 +109,15 @@ String XmdReplicantResolveName (ConstString rawName) {
|
|||||||
char ch = *list;
|
char ch = *list;
|
||||||
if (dirBuffer == NULL) dirBuffer = XmdBufferNew(char);
|
if (dirBuffer == NULL) dirBuffer = XmdBufferNew(char);
|
||||||
|
|
||||||
XmdBufferPush(dirBuffer, &ch);
|
|
||||||
if (ch == ':' || ch == 0) {
|
if (ch == ':' || ch == 0) {
|
||||||
|
char null = 0;
|
||||||
|
XmdBufferPush(dirBuffer, &null);
|
||||||
String dir = XmdBufferBreak(dirBuffer);
|
String dir = XmdBufferBreak(dirBuffer);
|
||||||
dirBuffer = NULL;
|
dirBuffer = NULL;
|
||||||
file = XmdReplicantScanDir(dir, name);
|
file = XmdReplicantScanDir(dir, name);
|
||||||
XtFree(dir);
|
XtFree(dir);
|
||||||
|
} else {
|
||||||
|
XmdBufferPush(dirBuffer, &ch);
|
||||||
}
|
}
|
||||||
list ++;
|
list ++;
|
||||||
}
|
}
|
||||||
@ -172,12 +180,13 @@ static Bool writeMapValue (
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XmdReplicantStateSave (XmdReplicantState *state) {
|
static XmdError XmdReplicantStateSave (XmdReplicantState *state) {
|
||||||
FILE *file = fopen(state->file, "w");
|
FILE *file = fopen(state->file, "w");
|
||||||
if (file == NULL) return;
|
if (file == NULL) return XmdErrorCantOpenFile;
|
||||||
fprintf(file, "[%s]\n", state->sourceName);
|
fprintf(file, "[%s]\n", state->sourceName);
|
||||||
XmdStringMapIterate(state->map, writeMapValue, file);
|
XmdStringMapIterate(state->map, writeMapValue, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
return XmdErrorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String readEscapedMapString (FILE *file, char delimiter) {
|
static String readEscapedMapString (FILE *file, char delimiter) {
|
||||||
@ -208,23 +217,42 @@ static String readEscapedMapString (FILE *file, char delimiter) {
|
|||||||
return XmdBufferBreak(string);
|
return XmdBufferBreak(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XmdReplicantStateLoad (XmdReplicantState *state) {
|
static XmdError XmdReplicantStateLoad (XmdReplicantState *state) {
|
||||||
FILE *file = fopen(state->file, "w");
|
if (state->sourceName != NULL) XtFree(state->sourceName);
|
||||||
if (file == NULL) return;
|
state->sourceName = NULL;
|
||||||
|
|
||||||
int ch = 0;
|
FILE *file = fopen(state->file, "r");
|
||||||
while (isspace((ch == fgetc(file))));
|
if (file == NULL) {
|
||||||
if (ch != '[') return;
|
return XmdErrorFileNotFound;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ch = ' ';
|
||||||
|
while (isspace(ch)) ch = fgetc(file);
|
||||||
|
if (ch != '[') {
|
||||||
|
fclose(file);
|
||||||
|
return XmdErrorBadSyntax;
|
||||||
|
}
|
||||||
state->sourceName = readEscapedMapString(file, ']');
|
state->sourceName = readEscapedMapString(file, ']');
|
||||||
ch = fgetc(file);
|
ch = fgetc(file);
|
||||||
if (ch != '\n') return;
|
if (ch != '\n') {
|
||||||
|
fclose(file);
|
||||||
|
return XmdErrorBadSyntax;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
String key = readEscapedMapString(file, '=');
|
String key = readEscapedMapString(file, '=');
|
||||||
String value = readEscapedMapString(file, '\n');
|
String value = readEscapedMapString(file, '\n');
|
||||||
XmdStringMapSet(state->map, key, value);
|
XmdStringMapSet(state->map, key, value);
|
||||||
XtFree(key);
|
XtFree(key);
|
||||||
if (value == NULL) break;
|
if (value == NULL) {
|
||||||
|
if (key == NULL) {
|
||||||
|
fclose(file);
|
||||||
|
return XmdErrorNone;
|
||||||
|
} else {
|
||||||
|
fclose(file);
|
||||||
|
return XmdErrorBadSyntax;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,18 +304,30 @@ static XmdReplicantSource *XmdReplicantSourceOpen (ConstString name) {
|
|||||||
XtFree(path);
|
XtFree(path);
|
||||||
if (source->handle == NULL) goto fail;
|
if (source->handle == NULL) goto fail;
|
||||||
|
|
||||||
/* find symbols */
|
/* find symbols */
|
||||||
String versionName = NULL;
|
String symbolName = NULL;
|
||||||
XtAsprintf(&versionName, "%s_XmdReplicantVersion", name);
|
XtAsprintf(&symbolName, "%s_XmdReplicantVersion", name);
|
||||||
source->symbols.version = (XmdReplicantVersion) (
|
source->symbols.version = (XmdReplicantFnVersion) (
|
||||||
dlsym(source->handle, versionName));
|
dlsym(source->handle, symbolName));
|
||||||
XtFree(versionName);
|
XtFree(symbolName);
|
||||||
if (source->symbols.version == NULL) goto fail;
|
if (source->symbols.version == NULL) goto fail;
|
||||||
String createName = NULL;
|
|
||||||
XtAsprintf(&createName, "%s_XmdReplicantCreate", name);
|
XtAsprintf(&symbolName, "%s_XmdReplicantConstruct", name);
|
||||||
source->symbols.create = (XmdReplicantCreate) (
|
source->symbols.construct = (XmdReplicantFnConstruct) (
|
||||||
dlsym(source->handle, createName));
|
dlsym(source->handle, symbolName));
|
||||||
XtFree(createName);
|
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) (
|
||||||
|
dlsym(source->handle, symbolName));
|
||||||
|
XtFree(symbolName);
|
||||||
if (source->symbols.create == NULL) goto fail;
|
if (source->symbols.create == NULL) goto fail;
|
||||||
|
|
||||||
/* check if the version matches */
|
/* check if the version matches */
|
||||||
@ -307,6 +347,8 @@ static void XmdReplicantSourceClose (XmdReplicantSource *source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) {
|
static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) {
|
||||||
|
XmdReplicantEnsure();
|
||||||
|
|
||||||
/* check to see if it has already been loaded */
|
/* check to see if it has already been loaded */
|
||||||
XmdReplicantSource *source = XmdStringMapGet(resident, name);
|
XmdReplicantSource *source = XmdStringMapGet(resident, name);
|
||||||
if (source != NULL) return source;
|
if (source != NULL) return source;
|
||||||
@ -316,7 +358,9 @@ static XmdReplicantSource *XmdReplicantSourceGet (ConstString name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String XmdReplicantScanDir (ConstString path, ConstString name) {
|
static String XmdReplicantScanDir (ConstString path, ConstString name) {
|
||||||
DIR *dir = opendir(path);
|
DIR *dir = opendir(path);
|
||||||
|
if (dir == NULL) return NULL;
|
||||||
|
|
||||||
String result = NULL;
|
String result = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
struct dirent *entry = readdir(dir);
|
struct dirent *entry = readdir(dir);
|
||||||
@ -330,3 +374,9 @@ static String XmdReplicantScanDir (ConstString path, ConstString name) {
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void XmdReplicantEnsure () {
|
||||||
|
if (resident == NULL) {
|
||||||
|
resident = XmdStringMapNew();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
replicants/Launcher/build.sh
Executable file
2
replicants/Launcher/build.sh
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
../../scripts/buildreplicant.sh Launcher "$@"
|
27
replicants/Launcher/src/icons/unknown.xbm
Normal file
27
replicants/Launcher/src/icons/unknown.xbm
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#define unknown_width 48
|
||||||
|
#define unknown_height 48
|
||||||
|
static unsigned char unknown_bits[] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x30, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x10, 0xe0, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
80
replicants/Launcher/src/main.c
Normal file
80
replicants/Launcher/src/main.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <Xm/PushB.h>
|
||||||
|
#include <Xmd/Icon.h>
|
||||||
|
#include <Xmd/Replicant.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "icons/appCalculator.xbm"
|
||||||
|
#include "icons/appEditor.xbm"
|
||||||
|
#include "icons/appFiles.xbm"
|
||||||
|
#include "icons/appMail.xbm"
|
||||||
|
#include "icons/appMusic.xbm"
|
||||||
|
#include "icons/appTerminal.xbm"
|
||||||
|
#include "icons/appWebBrowser.xbm"
|
||||||
|
#include "icons/unknown.xbm"
|
||||||
|
|
||||||
|
void activateLauncher (Widget button, XtPointer clientData, XtPointer callData) {
|
||||||
|
(void)(button);
|
||||||
|
(void)(callData);
|
||||||
|
XmdReplicantState *state = (XmdReplicantState *)(clientData);
|
||||||
|
|
||||||
|
String command = XmdReplicantStateQuery(state, "Exec");
|
||||||
|
String fullCommand = NULL;
|
||||||
|
XtAsprintf(&fullCommand, "%s &", command);
|
||||||
|
XtFree(command);
|
||||||
|
system(fullCommand);
|
||||||
|
XtFree(fullCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Launcher_XmdReplicantVersion () {
|
||||||
|
return XmdREPLICANT_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher_XmdReplicantConstruct () {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher_XmdReplicantDestruct () {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleDestroyFreePixmap (
|
||||||
|
Widget replicant,
|
||||||
|
XtPointer clientData,
|
||||||
|
XtPointer callData
|
||||||
|
) {
|
||||||
|
(void)(callData);
|
||||||
|
XFreePixmap(XtDisplay(replicant), (Pixmap)(clientData));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget Launcher_XmdReplicantCreate (Widget parent, XmdReplicantState *state) {
|
||||||
|
String iconName = XmdReplicantStateQuery(state, "Icon");
|
||||||
|
Pixmap icon;
|
||||||
|
#define iconCase(name) if (strcmp(#name, iconName) == 0) {\
|
||||||
|
icon = XmdLoadBitmapIcon(parent, app##name);\
|
||||||
|
} else
|
||||||
|
iconCase(Calculator)
|
||||||
|
iconCase(Editor)
|
||||||
|
iconCase(Files)
|
||||||
|
iconCase(Mail)
|
||||||
|
iconCase(Terminal)
|
||||||
|
iconCase(WebBrowser)
|
||||||
|
iconCase(Music)
|
||||||
|
icon = XmdLoadBitmapIcon(parent, unknown);
|
||||||
|
|
||||||
|
XtFree(iconName);
|
||||||
|
|
||||||
|
Widget button = XtVaCreateManagedWidget (
|
||||||
|
"launcher", xmPushButtonWidgetClass, parent,
|
||||||
|
XmNleftAttachment, XmATTACH_FORM,
|
||||||
|
XmNlabelType, XmPIXMAP,
|
||||||
|
XmNlabelPixmap, icon,
|
||||||
|
NULL);
|
||||||
|
XtAddCallback (
|
||||||
|
button, XmNactivateCallback,
|
||||||
|
activateLauncher, (XtPointer)(state));
|
||||||
|
XtAddCallback (
|
||||||
|
button, XmNdestroyCallback,
|
||||||
|
handleDestroyFreePixmap, (XtPointer)(icon));
|
||||||
|
return button;
|
||||||
|
}
|
34
scripts/buildreplicant.sh
Executable file
34
scripts/buildreplicant.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. `dirname $0`/flags.sh
|
||||||
|
|
||||||
|
function build() {
|
||||||
|
if
|
||||||
|
mkdir -p lib && \
|
||||||
|
cc src/*.c -o "lib/$1.so" -shared $CFLAGS
|
||||||
|
then
|
||||||
|
echo ".// ok"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "XXX FAIL!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean() {
|
||||||
|
rm -f bin/*
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
install)
|
||||||
|
clean; build "$1"
|
||||||
|
mkdir -p "$PREFIX/lib/Xmd/replicants"
|
||||||
|
cp "lib/$1.so" "$PREFIX/lib/Xmd/replicants"
|
||||||
|
clean
|
||||||
|
;;
|
||||||
|
clean)
|
||||||
|
clean
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
build "$1"
|
||||||
|
esac
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
CFLAGS="-std=c99 -Wall -Wextra -Werror -fPIC"
|
CFLAGS="-std=c99 -Wall -Wextra -Werror -fPIC"
|
||||||
PREFIX="/usr/local"
|
PREFIX="/usr/local"
|
||||||
APP_LIBS="-lXmd -lXm -lXt -lX11"
|
APP_LIBS="-lXmd -lXm -lXt -lX11 -ldl"
|
||||||
|
@ -2,32 +2,20 @@
|
|||||||
#include <Xm/Xm.h>
|
#include <Xm/Xm.h>
|
||||||
#include <Xm/RowColumn.h>
|
#include <Xm/RowColumn.h>
|
||||||
#include <Xm/PushB.h>
|
#include <Xm/PushB.h>
|
||||||
|
#include <Xmd/Dir.h>
|
||||||
#include <Xmd/Icon.h>
|
#include <Xmd/Icon.h>
|
||||||
|
#include <Xmd/Replicant.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include "icons/appCalculator.xbm"
|
|
||||||
#include "icons/appEditor.xbm"
|
|
||||||
#include "icons/appFiles.xbm"
|
|
||||||
#include "icons/appMail.xbm"
|
|
||||||
#include "icons/appTerminal.xbm"
|
|
||||||
#include "icons/appWebBrowser.xbm"
|
|
||||||
#include "icons/appMusic.xbm"
|
|
||||||
|
|
||||||
#include "icons/icon.xbm"
|
#include "icons/icon.xbm"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Pixmap icon;
|
|
||||||
const char * command;
|
|
||||||
} Launcher;
|
|
||||||
|
|
||||||
void createAllLaunchers (Widget);
|
|
||||||
Widget createLauncher (Widget, Launcher);
|
|
||||||
void activateLauncher (Widget, XtPointer, XtPointer);
|
|
||||||
|
|
||||||
XtAppContext application;
|
XtAppContext application;
|
||||||
|
|
||||||
|
static void loadReplicants (Widget parent);
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
Widget window = XtVaAppInitialize (
|
Widget window = XtVaAppInitialize (
|
||||||
&application, "Panel",
|
&application, "Panel",
|
||||||
@ -47,41 +35,42 @@ int main (int argc, char *argv[]) {
|
|||||||
"layout", xmRowColumnWidgetClass, window,
|
"layout", xmRowColumnWidgetClass, window,
|
||||||
XmNorientation, XmHORIZONTAL,
|
XmNorientation, XmHORIZONTAL,
|
||||||
NULL);
|
NULL);
|
||||||
createAllLaunchers(layout);
|
loadReplicants(layout);
|
||||||
|
|
||||||
XtManageChild(layout);
|
XtManageChild(layout);
|
||||||
XtRealizeWidget(window);
|
XtRealizeWidget(window);
|
||||||
XtAppMainLoop(application);
|
XtAppMainLoop(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createAllLaunchers (Widget parent) {
|
static void loadReplicants (Widget parent) {
|
||||||
#define add(name, cmd) createLauncher(parent, (Launcher){\
|
String userDir = XmdDirGetUser();
|
||||||
.icon = XmdLoadBitmapIcon(parent, app##name),\
|
String replicantsDir = NULL;
|
||||||
.command = cmd " &"\
|
XtAsprintf(&replicantsDir, "%s/panel", userDir);
|
||||||
} );
|
XtFree(userDir);
|
||||||
add(Calculator, "xcalc");
|
|
||||||
add(Editor, "nedit");
|
struct dirent **entries = NULL;
|
||||||
add(Files, "caja");
|
int entriesCount = scandir(replicantsDir, &entries, NULL, alphasort);
|
||||||
add(Mail, "nedit");
|
if (entriesCount < 0) {
|
||||||
add(Terminal, "uxterm");
|
XtFree(replicantsDir);
|
||||||
add(WebBrowser, "firefox");
|
/* TODO error message */
|
||||||
add(Music, "ymuse");
|
return;
|
||||||
#undef add
|
}
|
||||||
}
|
|
||||||
|
for (int index = 0; index < entriesCount; index ++) {
|
||||||
Widget createLauncher (Widget parent, Launcher launcher) {
|
struct dirent *entry = entries[index];
|
||||||
Widget button = XtVaCreateManagedWidget (
|
String point = NULL;
|
||||||
"launcher", xmPushButtonWidgetClass, parent,
|
if ((point = strrchr(entry->d_name,'.')) != NULL) {
|
||||||
XmNleftAttachment, XmATTACH_FORM,
|
if (strcmp(point, ".replicant") == 0) {
|
||||||
XmNlabelType, XmPIXMAP,
|
String fullName = NULL;
|
||||||
XmNlabelPixmap, launcher.icon,
|
XtAsprintf (
|
||||||
NULL);
|
&fullName, "%s/%s",
|
||||||
XtAddCallback(button, XmNactivateCallback, activateLauncher, (XtPointer)(launcher.command));
|
replicantsDir, entry->d_name);
|
||||||
return button;
|
XmdReplicantOpen(parent, fullName);
|
||||||
}
|
XtFree(fullName);
|
||||||
|
}
|
||||||
void activateLauncher (Widget button, XtPointer clientData, XtPointer callData) {
|
}
|
||||||
(void)(button);
|
XtFree((char *)(entry));
|
||||||
(void)(callData);
|
}
|
||||||
system((char *)(clientData));
|
XtFree((char *)(entries));
|
||||||
|
XtFree(replicantsDir);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user