From: Michael D. Lowis Date: Wed, 30 Sep 2020 16:55:57 +0000 (-0400) Subject: added window creation functions X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=b1a0cffd75ab94f7e34566158e8fb4a45435ce28;p=proto%2Faos.git added window creation functions --- diff --git a/build.sh b/build.sh index cc7a1aa..18f8aa5 100755 --- a/build.sh +++ b/build.sh @@ -9,3 +9,10 @@ done # 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 diff --git a/inc/libui.h b/inc/libui.h new file mode 100644 index 0000000..b074aaf --- /dev/null +++ b/inc/libui.h @@ -0,0 +1,6 @@ +typedef struct UIWin UIWin; + +UIWin* WindowCreate(char* title); +void WindowDelete(UIWin* win); +void WindowShow(UIWin* win); +void WindowHide(UIWin* win); diff --git a/src/init.c b/src/init.c new file mode 100644 index 0000000..40011ce --- /dev/null +++ b/src/init.c @@ -0,0 +1,43 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include + +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; +} diff --git a/src/libui/libui_impl.h b/src/libui/libui_impl.h new file mode 100644 index 0000000..31ba9b9 --- /dev/null +++ b/src/libui/libui_impl.h @@ -0,0 +1,28 @@ +#include +#include +#include + +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 +}; diff --git a/src/libui/window_create.c b/src/libui/window_create.c new file mode 100644 index 0000000..8b82ffe --- /dev/null +++ b/src/libui/window_create.c @@ -0,0 +1,66 @@ +#include +#include +#include +#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; +} diff --git a/src/libui/window_delete.c b/src/libui/window_delete.c new file mode 100644 index 0000000..7f2db56 --- /dev/null +++ b/src/libui/window_delete.c @@ -0,0 +1,12 @@ +#include +#include +#include +#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 */ +} diff --git a/src/libui/window_hide.c b/src/libui/window_hide.c new file mode 100644 index 0000000..78ca6e8 --- /dev/null +++ b/src/libui/window_hide.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "libui_impl.h" + +void WindowShow(UIWin* win) +{ + XUnmapWindow(win->display, win->self); + XSync(win->display, False); +} diff --git a/src/libui/window_show.c b/src/libui/window_show.c new file mode 100644 index 0000000..6cc8d59 --- /dev/null +++ b/src/libui/window_show.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include "libui_impl.h" + +void WindowShow(UIWin* win) +{ + XMapWindow(win->display, win->self); + XSync(win->display, False); +} diff --git a/src/shell.c b/src/shell.c new file mode 100644 index 0000000..6784262 --- /dev/null +++ b/src/shell.c @@ -0,0 +1,171 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/tools/Binary b/tools/Binary index 74863a3..d070e58 100755 --- a/tools/Binary +++ b/tools/Binary @@ -1,5 +1,12 @@ #!/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 + diff --git a/tools/Object b/tools/Object index 95c0580..893d961 100755 --- a/tools/Object +++ b/tools/Object @@ -1,4 +1,6 @@ #!/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