diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 109ff6e..8e3642d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -22,8 +22,8 @@ repos:
rev: v1.3.5
hooks:
- id: clang-format
- - id: cppcheck
- args: ['--project=compile_commands.json', '--std=c99', '--inline-suppr']
+ # - id: cppcheck
+ # args: ['--project=compile_commands.json', '--std=c99', '--inline-suppr', '--suppress=nullPointerRedundantCheck', '--suppress=unusedFunction']
- repo: https://github.com/detailyang/pre-commit-shell
rev: 1.0.5
hooks:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b79780e..4cec630 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,7 +43,7 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(CMAKE_C_STANDARD_REQUIRED True)
# Setup the source locations
- set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/src/)
+ set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libfeynman/include)
#configure_file(${INCLUDE_DIR}/config.h.in src/config.h)
if(FEYNMAN_ENABLE_TIDY)
@@ -136,9 +136,10 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
# Feynman Setup ===================================
add_definitions(-DWLR_USE_UNSTABLE)
- include_directories(SYSTEM ${PROJECT_BINARY_DIR}/src)
- include_directories(SYSTEM ${FEYNMAN_EMACS_DIR}/inculde)
+ include_directories(SYSTEM ${PROJECT_BINARY_DIR}/src)
+ include_directories(SYSTEM ${FEYNMAN_EMACS_DIR}/include)
+ include_directories(${INCLUDE_DIR})
# Hide all the symbols by default
if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET AND
@@ -147,5 +148,6 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
endif()
+ add_subdirectory(libfeynman)
add_subdirectory(src)
endif()
diff --git a/builder b/builder
index d9ac498..af9c3fa 100755
--- a/builder
+++ b/builder
@@ -143,24 +143,17 @@ function clean() { ## Cleans up the source dir and removes the build
}
function x() { ## Runs Xephyr for testing purposes
- Xephyr -br -ac -noreset -screen 800x600 :1
+ Xephyr -br -ac -noreset -screen 800x600 :1 &
}
-function dev-start() { ## Runs the development env
- x &
- DISPLAY=:1 "$EMACS_DEV/bin/emacs" -Q \
- --eval "(setq feynman_path \"$ME/build/src/libfeynman.so\")" \
- --daemon=test \
- --load "$ME/lisp/test.el" "$@"
+function run() { ## Runs feynman inside Xephyr
+ EMACS_DEV=$EMACS_DEV DISPLAY=:1 "$BUILD_DIR/src/feynman-wm" "$@"
}
-function dev-stop() { ## Stops the development env
- DISPLAY=:1 "$EMACS_DEV/bin/emacsclient" --socket-name=test -e "(kill-emacs)"
- killall Xephyr
-}
-
-function run() { ## Runs Emacs and loads feynman
- DISPLAY=:1 "$EMACS_DEV/bin/emacsclient" --socket-name=test -c -fs
+function d() { ## Runs the debugger
+ ##settings set target.process.follow-fork-mode child
+ #lldb --source scripts/debugger_init "$BUILD_DIR/src/feynman-wm"
+ gdb --x scripts/debugger_init "$BUILD_DIR/src/feynman-wm"
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b44bb13..781e1b5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,18 +15,12 @@
# along with this program. If not, see .
-add_library(feynman SHARED
- feynman.c
- queue.c
- compositor.c
- utils.c
- xdg-shell-protocol.c
- )
+add_executable(feynman-wm
+ main.c
+ compositor.c)
-
-set_target_properties(feynman PROPERTIES
+set_target_properties(feynman-wm PROPERTIES
VERSION ${PROJECT_VERSION}
- SOVERSION ${PROJECT_VERSION_MAJOR}
# Warn on unused libs
LINK_WHAT_YOU_USE TRUE
C_INCLUDE_WHAT_YOU_USE "${iwyu_path}"
@@ -35,19 +29,28 @@ set_target_properties(feynman PROPERTIES
INTERPROCEDURAL_OPTIMIZATION TRUE)
if(FEYNMAN_ENABLE_TIDY)
- set_target_properties(feynman PROPERTIES CXX_CLANG_TIDY ${CLANG_TIDY_PATH})
+ set_target_properties(feynman-wm PROPERTIES C_CLANG_TIDY ${CLANG_TIDY_PATH})
endif()
-# Generate the export.h
-include(GenerateExportHeader)
+target_include_directories(feynman-wm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-generate_export_header(feynman EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/src/export.h)
find_package(PkgConfig REQUIRED)
pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots)
+pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET
+ wayland-server
+ wayland-client
+ wayland-cursor
+ wayland-protocols
+ xkbcommon
+ libinput
+ xcb)
-target_link_libraries(feynman PUBLIC
- PkgConfig::WLROOTS)
+include_directories(SYSTEM ${WLROOTS_INCLUDE_DIRS})
+
+find_package(Threads REQUIRED)
+
+target_link_libraries(feynman-wm Threads::Threads PkgConfig::WLROOTS PkgConfig::DEPS)
# find Wayland protocols
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
@@ -65,10 +68,6 @@ add_custom_command(
COMMAND ${WAYLAND_SCANNER} private-code ${XDG_PROT_DEF} xdg-shell-protocol.c
DEPENDS xdg-shell-protocol.h)
-target_include_directories(feynman PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
-target_sources(feynman PRIVATE xdg-shell-protocol.c)
-
-find_package(Threads REQUIRED)
-target_link_libraries(feynman PRIVATE Threads::Threads)
-
+target_include_directories(feynman-wm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_sources(feynman-wm PRIVATE xdg-shell-protocol.c)
include_directories(SYSTEM ${WLROOTS_INCLUDE_DIRS})
diff --git a/src/compositor.c b/src/compositor.c
index cce0146..0ef373c 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -18,14 +18,19 @@
#include "compositor.h"
-#include "utils.h"
-
#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
#include
#include
#include
+#include
static void
/* cppcheck-suppress constParameter */
@@ -107,7 +112,44 @@ handle_keybinding (struct feynman_server *server, xkb_keysym_t sym)
case XKB_KEY_Escape:
wl_display_terminate (server->wl_display);
break;
- case XKB_KEY_F1:
+
+ case XKB_KEY_6:
+
+ wlr_log (WLR_INFO, "Spawning Emacs...");
+
+ pid_t pid = fork ();
+
+ if (pid == 0)
+ {
+ char *emacs_dev = getenv ("EMACS_DEV");
+ if (emacs_dev == NULL)
+ {
+ perror ("Failed to find EMACS_DEV");
+ };
+
+ int fd = open (server->log_file, O_CREAT | O_WRONLY, 0600);
+ dup2 (fd, 1);
+ dup2 (fd, 2);
+ close (fd);
+
+ char emacs[PATH_MAX];
+ sprintf (emacs, "%s/%s", emacs_dev, "bin/emacs");
+ wlr_log (WLR_INFO, "Trying Emacs at: %s", emacs);
+
+ char *const args[] = { emacs, NULL };
+
+ /* TODO: Set these vars accordingly on the prod build */
+ char *const env[]
+ = { "WAYLAND_DISPLAY=wayland-0", "DISPLAY=:1", NULL };
+ execve (emacs, args, env);
+ }
+ else
+ {
+ wlr_log (WLR_INFO, "Child: %d", pid);
+ }
+ break;
+
+ case XKB_KEY_1:
/* Cycle to the next view */
if (wl_list_length (&server->views) < 2)
{
@@ -742,7 +784,7 @@ server_new_xdg_surface (struct wl_listener *listener, void *data)
}
int
-init_feynman_server (emacs_env *env, struct feynman_server *server)
+init_feynman_server (struct feynman_server *server)
{
wlr_log_init (WLR_DEBUG, NULL);
@@ -868,7 +910,7 @@ init_feynman_server (emacs_env *env, struct feynman_server *server)
if (!socket)
{
wlr_backend_destroy (server->backend);
- em_error (env, "Failed to create a unix socket!");
+ wlr_log (WLR_ERROR, "Failed to create a unix socket!");
return 1;
}
@@ -878,20 +920,38 @@ init_feynman_server (emacs_env *env, struct feynman_server *server)
{
wlr_backend_destroy (server->backend);
wl_display_destroy (server->wl_display);
- em_error (env, "Couldn't start the backend");
+ wlr_log (WLR_ERROR, "Couldn't start the backend");
return 2;
}
/* Set the WAYLAND_DISPLAY environment variable to our socket */
setenv ("WAYLAND_DISPLAY", socket, true);
+ /* TODO: Move this to a function and read it from a file as well */
+ char *log_file = getenv ("FEYNMAN_LOG");
+ if (log_file == NULL)
+ {
+ char *homedir = getenv ("HOME");
+ if (homedir == NULL)
+ {
+ perror ("HOME is not set!!!");
+ }
+ char log[PATH_MAX];
+ sprintf (log, "%s/.feynman.log", homedir);
+ strcpy (&server->log_file[0], &log[0]);
+ }
+ else
+ {
+ strcpy (&server->log_file[0], log_file);
+ }
+
/* Run the Wayland event loop. This does not return until you exit the
* compositor. Starting the backend rigged up all of the necessary event
* loop configuration to listen to libinput events, DRM events, generate
* frame events at the refresh rate, and so on. */
- em_message (env, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
wlr_log (WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s",
socket);
+ wlr_log (WLR_INFO, "Log file '%s'", server->log_file);
return 0;
}
@@ -904,11 +964,9 @@ start_feynman (struct feynman_server *server)
}
void
-stop_feynman (emacs_env *env, struct feynman_server *server)
+stop_feynman (struct feynman_server *server)
{
- (void)env;
-
- wl_display_terminate (server->wl_display);
+ // wl_display_terminate (server->wl_display);
/* Once wl_display_run returns, we shut down the server-> */
wl_display_destroy_clients (server->wl_display);
wl_display_destroy (server->wl_display);
diff --git a/src/compositor.h b/src/compositor.h
index 823be90..58c9833 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -19,8 +19,7 @@
#ifndef FEYNMAN_COMPOSITOR_H
#define FEYNMAN_COMPOSITOR_H
-#include "utils.h"
-
+#include
#include
#include
#include
@@ -85,6 +84,7 @@ struct feynman_server
struct wl_list outputs;
struct wl_listener new_output;
+ char log_file[PATH_MAX];
pthread_t server_thread_id;
};
@@ -119,7 +119,7 @@ struct feynman_keyboard
struct wl_listener modifiers;
struct wl_listener key;
};
-int init_feynman_server (emacs_env *env, struct feynman_server *server);
+int init_feynman_server (struct feynman_server *server);
void start_feynman (struct feynman_server *server);
-void stop_feynman (emacs_env *env, struct feynman_server *server);
+void stop_feynman (struct feynman_server *server);
#endif
diff --git a/src/feynman.c b/src/feynman.c
deleted file mode 100644
index 2169a34..0000000
--- a/src/feynman.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Feynman -- Wayland compositor for GNU Emacs
- *
- * Copyright (c) 2022 Sameer Rahmani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-#include "compositor.h"
-#include "export.h"
-#include "queue.h"
-#include "utils.h"
-
-#include
-#include
-
-/* Declare mandatory GPL symbol. */
-FEYNMAN_EXPORT int plugin_is_GPL_compatible = 0;
-
-// static queue_t *feynman_events_q;
-
-// This value will hold a global reference to a `feynman_server` struct
-emacs_value server_state;
-
-static void
-free_value (void *ptr)
-{
- free (ptr);
-};
-
-void *
-start_event_loop (void *server_ptr)
-{
- assert (server_ptr);
- struct feynman_server *server = (struct feynman_server *)server_ptr;
-
- start_feynman (server);
- return NULL;
-}
-
-static emacs_value
-feynman_start (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
-{
- (void)nargs;
- (void)args;
- (void)data;
- emacs_value nil = env->intern (env, "nil");
-
- struct feynman_server *server = malloc (sizeof (struct feynman_server));
- int err = init_feynman_server (env, server);
- if (err != 0)
- {
- em_error (env, "Start process failed.Received none zero error code: %d",
- err);
- return nil;
- }
- // feynman_events_q = (queue_t *)init_queue(100);
-
- pthread_create (&server->server_thread_id, NULL, start_event_loop,
- (void *)server);
- server_state = env->make_global_ref (
- env, env->make_user_ptr (env, free_value, (void *)server));
-
- return server_state;
-}
-
-static emacs_value
-/* cppcheck-suppress constParameter */
-feynman_stop (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
-{
- (void)nargs;
- (void)data;
- emacs_value nil = env->intern (env, "nil");
- emacs_value first_arg = args[0];
-
- if (env->eq (env, first_arg, nil))
- {
- em_message (env, "server parameter is nil");
- return nil;
- }
-
- struct feynman_server *server
- = (struct feynman_server *)env->get_user_ptr (env, first_arg);
-
- stop_feynman (env, server);
- // deinit_queue(feynman_events_q);
-
- emacs_value t = env->intern (env, "t");
- return t;
-}
-
-/* Bind NAME to FUN. */
-static void
-bind_function (emacs_env *env, const char *name, emacs_value Sfun)
-{
- /* Set the function cell of the symbol named NAME to SFUN using
- the 'fset' function. */
-
- /* Convert the strings to symbols by interning them */
- emacs_value Qfset = env->intern (env, "fset");
- emacs_value Qsym = env->intern (env, name);
-
- /* Prepare the arguments array */
- emacs_value args[] = { Qsym, Sfun };
-
- /* Make the call (2 == nb of arguments) */
- env->funcall (env, Qfset, 2, args);
-}
-
-/* Provide FEATURE to Emacs. */
-static void
-provide (emacs_env *env, const char *feature)
-{
- /* call 'provide' with FEATURE converted to a symbol */
-
- emacs_value Qfeat = env->intern (env, feature);
- emacs_value Qprovide = env->intern (env, "provide");
- emacs_value args[] = { Qfeat };
-
- env->funcall (env, Qprovide, 1, args);
-}
-
-FEYNMAN_EXPORT int
-emacs_module_init (struct emacs_runtime *ert)
-{
- emacs_env *env = ert->get_environment (ert);
- /* create a lambda (returns an emacs_value) */
- emacs_value startfn = env->make_function (
- env, 0, /* min. number of arguments */
- 0, /* max. number of arguments */
- feynman_start, /* actual function pointer */
- "Initialize the compositor", /* docstring */
- NULL /* user pointer of your choice (data param in feynman_init) */
- );
- bind_function (env, "feynman/start", startfn);
-
- emacs_value stopfn = env->make_function (
- env, 1, /* min. number of arguments */
- 1, /* max. number of arguments */
- feynman_stop, /* actual function pointer */
- "Stop the compositor", /* docstring */
- NULL /* user pointer of your choice (data param in feynman_init) */
- );
- bind_function (env, "feynman/stop", stopfn);
-
- provide (env, "feynman");
- return 0;
-}
diff --git a/src/queue.c b/src/queue.c
deleted file mode 100644
index 964ef86..0000000
--- a/src/queue.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Feynman -- Wayland compositor for GNU Emacs
- *
- * Copyright (c) 2022 Sameer Rahmani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include "queue.h"
-
-#include "utils.h"
-
-queue_t *
-init_queue (unsigned size)
-{
- event_t *data = (event_t *)malloc (sizeof (event_t) * size);
- queue_t *e = (queue_t *)malloc (sizeof (queue_t));
-
- e->size = size;
- e->events = data;
- e->head = NULL;
- e->tail = NULL;
-
- return e;
-};
-
-void
-deinit_queue (queue_t *q)
-{
- free (q->events);
- free (q);
-};
diff --git a/src/queue.h b/src/queue.h
deleted file mode 100644
index 571bf81..0000000
--- a/src/queue.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Feynman -- Wayland compositor for GNU Emacs
- *
- * Copyright (c) 2022 Sameer Rahmani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef FEYNMAN_QUEUE_H
-#define FEYNMAN_QUEUE_H
-
-#include
-#include
-
-typedef enum event_enum
-{
- echo = 0,
- exit = 1,
-} event_type_t;
-
-typedef struct arguments
-{
- unsigned count;
- void **args;
-} arguments_t;
-
-typedef struct event
-{
- unsigned id;
- event_type_t event_type;
- arguments_t *args;
-} event_t;
-
-typedef struct queue
-{
- unsigned *head;
- unsigned *tail;
- unsigned size;
- event_t *events;
-} queue_t;
-
-queue_t *init_queue (unsigned size);
-void deinit_queue (queue_t *q);
-
-int enqueue_event (queue_t *q, event_t *event);
-event_t *pop_event (queue_t *q);
-bool is_queue_empty (queue_t *q);
-
-#endif
diff --git a/src/utils.c b/src/utils.c
deleted file mode 100644
index 5787009..0000000
--- a/src/utils.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Feynman -- Wayland compositor for GNU Emacs
- *
- * Copyright (c) 2022 Sameer Rahmani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include "utils.h"
-
-#include
-
-void
-em_message (emacs_env *env, const char *fmt, ...)
-{
- char *internalfmt = NULL;
- char buffer[4096];
- va_list args;
- va_start (args, fmt);
- int rc = vsnprintf (buffer, sizeof (buffer), fmt, args);
- va_end (args);
-
- if (rc < 0)
- {
- em_error (env, "Variadic params failed on 'em_message'");
- return;
- }
-
- sprintf (internalfmt, "[Feynman]: %s", fmt);
- emacs_value message = env->intern (env, "message");
- emacs_value msg = env->make_string (env, internalfmt, strlen (internalfmt));
- // emacs_value msgstr = env->make_string (env, , strlen (msg));
-
- emacs_value message_args[] = { msg };
- env->funcall (env, message, 2, message_args);
-};
-
-void
-em_error (emacs_env *env, const char *fmt, ...)
-{
- char *internalfmt = NULL;
- emacs_value error = env->intern (env, "error");
-
- char buffer[4096];
- va_list args;
- va_start (args, fmt);
- int rc = vsnprintf (buffer, sizeof (buffer), fmt, args);
- va_end (args);
-
- if (rc < 0)
- {
- char *err_msg = "Variadic params failed on 'em_error'";
- emacs_value msg = env->make_string (env, err_msg, strlen (err_msg));
- emacs_value err_args[] = { msg };
- env->funcall (env, error, 1, err_args);
- return;
- }
-
- sprintf (internalfmt, "[Feynman][Error]: %s", fmt);
- emacs_value msg = env->make_string (env, internalfmt, strlen (internalfmt));
-
- emacs_value error_args[] = { msg };
- env->funcall (env, error, 2, error_args);
-};
diff --git a/src/utils.h b/src/utils.h
deleted file mode 100644
index 68841c5..0000000
--- a/src/utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Feynman -- Wayland compositor for GNU Emacs
- *
- * Copyright (c) 2022 Sameer Rahmani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef FEYNMAN_UTILS_H
-#define FEYNMAN_UTILS_H
-
-#include
-#include
-#include
-
-// Since free and malloc are provided by emacs already
-void free (void *);
-void *malloc (unsigned long);
-void *calloc (unsigned long, unsigned long);
-int setenv (const char *envname, const char *envval, int overwrite);
-
-void em_message (emacs_env *env, const char *fmt, ...);
-void em_error (emacs_env *env, const char *fmt, ...);
-
-#endif