# Now build all of the binaries
parallel --halt now,fail=1 'Binary build/bin/{/.} {}' ::: src/*.c
+
+Binary "src/shell/"
+
+## Build all of the multi-file binaries last
+#for lib in src/*/; do
+# Binary "$lib"
+#done
--- /dev/null
+typedef struct UIWin UIWin;
+
+UIWin* WindowCreate(char* title);
+void WindowDelete(UIWin* win);
+void WindowShow(UIWin* win);
+void WindowHide(UIWin* win);
--- /dev/null
+#define _XOPEN_SOURCE 700
+#include <stdc.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static sigset_t set;
+static char* const rcinitcmd[] = { "/etc/rc.init", 0 };
+static char* const rcrebootcmd[] = { "/etc/rc.shutdown", "reboot", 0 };
+static char* const rcpoweroffcmd[] = { "/etc/rc.shutdown", "poweroff", 0 };
+
+static void spawn(char* const argv[])
+{
+ if (0 == fork())
+ {
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ setsid();
+ execvp(argv[0], argv);
+ _exit(1);
+ }
+}
+
+int main(void)
+{
+ if (getpid() != 1) return 1;
+ if (chdir("/") < 0) return 1;
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ spawn(rcinitcmd);
+ while (1)
+ {
+ int sig;
+ sigwait(&set, &sig);
+ switch (sig)
+ {
+ case SIGUSR1: spawn(rcpoweroffcmd); break;
+ case SIGINT: spawn(rcrebootcmd); break;
+ case SIGCHLD:
+ while (waitpid(-1, NULL, WNOHANG) > 0);
+ break;
+ }
+ }
+ return 0;
+}
--- /dev/null
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xft/Xft.h>
+
+struct UIWin
+{
+ struct UIWin* next;
+ Display* display;
+ Window root;
+ Screen* screen;
+ int screen_num;
+ int depth;
+ Visual* visual;
+ Colormap colormap;
+ int width;
+ int height;
+ Window self;
+ Pixmap pixmap;
+ GC gc;
+ XftDraw* xft;
+ XftFont* font;
+};
+
+extern struct UIWin* Managed_Windows;
+
+enum {
+ WIN_BACKGROUND = 0xEAEAEA
+};
--- /dev/null
+#include <stdc.h>
+#include <liba.h>
+#include <libui.h>
+#include "libui_impl.h"
+
+static Display* XDisplay = NULL;
+struct UIWin* Managed_Windows = NULL;
+
+UIWin* WindowCreate(char* title)
+{
+ assert(title);
+
+ /* initialize xlib if it isn't already */
+ if (!XDisplay)
+ {
+ XDisplay = XOpenDisplay(NULL);
+ if (!XDisplay)
+ {
+ exit(1);
+ }
+ }
+
+ /* allocate a window struct and start populating it */
+ UIWin* win = ecalloc(1, sizeof(UIWin));
+ win->display = XDisplay;
+ win->root = DefaultRootWindow(win->display);
+ win->screen = DefaultScreenOfDisplay(win->display);
+ win->screen_num = DefaultScreen(win->display);
+ win->depth = DefaultDepth(win->display, win->screen_num);
+ XWindowAttributes wa;
+ XGetWindowAttributes(win->display, win->root, &wa);
+ win->visual = wa.visual;
+ win->colormap = wa.colormap;
+ win->width = 640;
+ win->height = 480;
+ win->self = XCreateSimpleWindow(win->display, win->root, 0, 0, win->width, win->height, 0, 0, 0xEAEAEA);
+ XStoreName(win->display, win->self, title);
+
+ /* initialize the graphics */
+ win->pixmap = XCreatePixmap(win->display, win->self, win->width, win->height, win->depth);
+ win->xft = XftDrawCreate(win->display, win->pixmap, win->visual, win->colormap);
+// win->font = FontLoad("Verdana:size=12");
+ XGCValues gcv;
+ gcv.foreground = 0xEAEAEA;
+ gcv.graphics_exposures = False;
+ win->gc = XCreateGC(win->display, win->self, GCGraphicsExposures, &gcv);
+
+ /* initialize event handling */
+ XSelectInput(win->display, win->self, 0
+ | ButtonPressMask
+ | ButtonReleaseMask
+ | ButtonMotionMask
+ | PropertyChangeMask
+ | KeyPressMask
+ | EnterWindowMask
+ | ExposureMask
+ | VisibilityChangeMask
+ | StructureNotifyMask
+ );
+
+ /* register it so the even loop will manage it*/
+ win->next = Managed_Windows;
+ Managed_Windows = win;
+
+ return win;
+}
--- /dev/null
+#include <stdc.h>
+#include <liba.h>
+#include <libui.h>
+#include "libui_impl.h"
+
+void WindowDelete(UIWin* win)
+{
+ assert(win);
+ WindowHide(win);
+ /* TODO: remove window from managed list */
+ /* TODO: delete/close the X window and free resources */
+}
--- /dev/null
+#include <stdc.h>
+#include <liba.h>
+#include <libui.h>
+#include "libui_impl.h"
+
+void WindowShow(UIWin* win)
+{
+ XUnmapWindow(win->display, win->self);
+ XSync(win->display, False);
+}
--- /dev/null
+#include <stdc.h>
+#include <liba.h>
+#include <libui.h>
+#include "libui_impl.h"
+
+void WindowShow(UIWin* win)
+{
+ XMapWindow(win->display, win->self);
+ XSync(win->display, False);
+}
--- /dev/null
+#define _XOPEN_SOURCE 700
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LSH_TOK_BUFSIZE 64
+#define LSH_TOK_DELIM " \t\r\n\a"
+
+#define nelem(ary) \
+ (sizeof(ary) / sizeof(ary[0]))
+
+int cd(char **args)
+{
+ if (args[1] == NULL)
+ {
+ fprintf(stderr, "lsh: expected argument to \"cd\"\n");
+ }
+ else
+ {
+ if (chdir(args[1]) != 0)
+ {
+ perror("lsh");
+ }
+ }
+ return 1;
+}
+
+struct {
+ char* name;
+ int (*func)(char**);
+} Builtins[] = {
+ { .name = "cd", .func = cd }
+};
+
+int launch(char **args)
+{
+ pid_t pid = fork();
+ if (pid == 0)
+ {
+ // Child process
+ if (execvp(args[0], args) == -1)
+ {
+ perror("lsh");
+ }
+ exit(EXIT_FAILURE);
+ }
+ else if (pid < 0)
+ {
+ // Error forking
+ perror("lsh");
+ }
+ else
+ {
+ int status;
+ do
+ {
+ waitpid(pid, &status, WUNTRACED);
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ }
+
+ return 1;
+}
+
+int execute(char **args)
+{
+ if (args[0] == NULL)
+ {
+ // An empty command was entered.
+ return 1;
+ }
+
+ for (size_t i = 0; i < nelem(Builtins); i++)
+ {
+ if (!strcmp(args[0], Builtins[i].name))
+ {
+ return Builtins[i].func(args);
+ }
+ }
+
+ return launch(args);
+}
+
+/**
+ @brief Read a line of input from stdin.
+ @return The line from stdin.
+ */
+char *read_line(void)
+{
+ char *line = NULL;
+ size_t bufsize = 0; // have getline allocate a buffer for us
+ if (getline(&line, &bufsize, stdin) == -1)
+ {
+ if (feof(stdin))
+ {
+ exit(EXIT_SUCCESS); // We recieved an EOF
+ }
+ else
+ {
+ perror("lsh: getline\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ return line;
+}
+
+
+char** split_line(char *line)
+{
+ int bufsize = LSH_TOK_BUFSIZE, position = 0;
+ char **tokens = malloc(bufsize * sizeof(char*));
+ char *token, **tokens_backup;
+
+ if (!tokens)
+ {
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ token = strtok(line, LSH_TOK_DELIM);
+ while (token != NULL)
+ {
+ tokens[position] = token;
+ position++;
+
+ if (position >= bufsize)
+ {
+ bufsize += LSH_TOK_BUFSIZE;
+ tokens_backup = tokens;
+ tokens = realloc(tokens, bufsize * sizeof(char*));
+ if (!tokens)
+ {
+ free(tokens_backup);
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ token = strtok(NULL, LSH_TOK_DELIM);
+ }
+ tokens[position] = NULL;
+ return tokens;
+}
+
+int main(int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ // Load config files, if any.
+
+ int status = 0;
+ do
+ {
+ printf("> ");
+ char* line = read_line();
+ char** args = split_line(line);
+ int status = execute(args);
+ (void)status;
+ free(line);
+ free(args);
+ }
+ while (status);
+
+ // Perform any shutdown/cleanup.
+
+ return EXIT_SUCCESS;
+}
+
#!/bin/sh
-echo "Binary $1"
-mkdir -p build/bin
-cc -Iinc/ --std=c99 -Wall -Wextra -Werror -o "$@"
\ No newline at end of file
+if [ -d "$2" ]; then
+ echo "Binary $1"
+else
+ if [ "$2" -nt "$1" ]; then
+ echo "Binary $1"
+ mkdir -p build/bin
+ cc -Iinc/ --std=c99 -Wall -Wextra -Werror -I/usr/include/freetype2 -o "$@"
+ fi
+fi
+
#!/bin/sh
-echo "Object $1"
-cc -Iinc/ --std=c99 -Wall -Wextra -Werror -c -o "$@"
\ No newline at end of file
+if [ "$2" -nt "$1" ]; then
+ echo "Object $1"
+ cc -Iinc/ --std=c99 -Wall -Wextra -Werror -I/usr/include/freetype2 -c -o "$@"
+fi
\ No newline at end of file