aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--backend/CMakeLists.txt15
-rw-r--r--backend/wayland/CMakeLists.txt13
-rw-r--r--backend/wayland/backend.c46
-rw-r--r--backend/wayland/registry.c29
-rw-r--r--common/CMakeLists.txt6
-rw-r--r--common/list.c91
-rw-r--r--common/log.c100
-rw-r--r--example/CMakeLists.txt7
-rw-r--r--example/main.c19
-rw-r--r--include/backend/wayland.h21
-rw-r--r--include/common/log.h18
-rw-r--r--include/wlr/backend.h7
-rw-r--r--include/wlr/backend/wayland.h14
-rw-r--r--include/wlr/common/list.h31
-rw-r--r--include/wlr/common/log.h16
-rw-r--r--include/wlr/wayland.h32
17 files changed, 445 insertions, 22 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 19546711..939def0c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,3 +58,5 @@ include(Manpage)
include_directories(include)
add_subdirectory(backend)
+add_subdirectory(common)
+add_subdirectory(example)
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index d69efdd5..01ac5e4e 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -1 +1,14 @@
-add_subdirectory(wayland)
+include_directories(
+ ${PROTOCOLS_INCLUDE_DIRS}
+ ${WAYLAND_INCLUDE_DIR}
+)
+
+add_library(wlr-backend
+ wayland/backend.c
+ wayland/registry.c
+)
+
+target_link_libraries(wlr-backend
+ wlr-common
+ ${WAYLAND_LIBRARIES}
+)
diff --git a/backend/wayland/CMakeLists.txt b/backend/wayland/CMakeLists.txt
deleted file mode 100644
index f185245c..00000000
--- a/backend/wayland/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-include_directories(
- ${PROTOCOLS_INCLUDE_DIRS}
- ${WAYLAND_INCLUDE_DIR}
- .
-)
-
-add_library(wlr-backend-wayland
- backend.c
-)
-
-target_link_libraries(wlr-backend-wayland
- ${WAYLAND_LIBRARIES}
-)
diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c
index 3564fc12..8ea54058 100644
--- a/backend/wayland/backend.c
+++ b/backend/wayland/backend.c
@@ -1,13 +1,49 @@
#include <stdlib.h>
#include <stdint.h>
#include <wayland-server.h>
+#include <assert.h>
#include "backend/wayland.h"
+#include "common/log.h"
-struct wlr_wayland_backend *wayland_backend_init(struct wl_display *display,
- size_t outputs) {
- struct wlr_wayland_backend *backend = calloc(
- sizeof(struct wlr_wayland_backend), 1);
+void wlr_wl_backend_free(struct wlr_wl_backend *backend) {
+ if (!backend) {
+ return;
+ }
+ // TODO: free more shit
+ free(backend);
+}
+
+/*
+ * Initializes the wayland backend. Opens a connection to a remote wayland
+ * compositor and creates surfaces for each output, then registers globals on
+ * the specified display.
+ */
+struct wlr_wl_backend *wlr_wl_backend_init(
+ struct wl_display *display, size_t outputs) {
+ assert(display);
+ struct wlr_wl_backend *backend;
+ if (!(backend = calloc(sizeof(struct wlr_wl_backend), 1))) {
+ wlr_log(L_ERROR, "Could not allocate backend");
+ goto error;
+ }
+ if (!(backend->outputs = list_create())) {
+ wlr_log(L_ERROR, "Could not allocate output list");
+ goto error;
+ }
backend->local_display = display;
- // TODO: obtain reference to remote display
+ backend->remote_display = wl_display_connect(getenv("_WAYLAND_DISPLAY"));
+ if (!backend->remote_display) {
+ wlr_log(L_ERROR, "Could not connect to remote display");
+ goto error;
+ }
+ if (!(backend->remote_registry = wl_display_get_registry(
+ backend->remote_display))) {
+ wlr_log(L_ERROR, "Could not obtain reference to remote registry");
+ goto error;
+ }
+ wlr_wlb_registry_poll(backend);
return backend;
+error:
+ wlr_wl_backend_free(backend);
+ return NULL;
}
diff --git a/backend/wayland/registry.c b/backend/wayland/registry.c
new file mode 100644
index 00000000..35d386d3
--- /dev/null
+++ b/backend/wayland/registry.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <wayland-client.h>
+#include "backend/wayland.h"
+#include "common/log.h"
+
+static void registry_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version) {
+ //struct wlr_wl_backend *backend = data;
+ wlr_log(L_DEBUG, "Remote wayland global: %s v%d", interface, version);
+ // TODO
+}
+
+static void registry_global_remove(void *data,
+ struct wl_registry *registry, uint32_t name) {
+ // TODO
+}
+
+static const struct wl_registry_listener registry_listener = {
+ .global = registry_global,
+ .global_remove = registry_global_remove
+};
+
+void wlr_wlb_registry_poll(struct wlr_wl_backend *backend) {
+ wl_registry_add_listener(backend->remote_registry,
+ &registry_listener, backend->remote_registry);
+ wl_display_dispatch(backend->remote_display);
+ wl_display_roundtrip(backend->remote_display);
+}
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100644
index 00000000..d8d52681
--- /dev/null
+++ b/common/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(wlr-common STATIC
+ list.c
+ log.c
+)
+
+target_link_libraries(wlr-common m)
diff --git a/common/list.c b/common/list.c
new file mode 100644
index 00000000..095fbced
--- /dev/null
+++ b/common/list.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <wlr/common/list.h>
+
+list_t *list_create(void) {
+ list_t *list = malloc(sizeof(list_t));
+ list->capacity = 10;
+ list->length = 0;
+ list->items = malloc(sizeof(void*) * list->capacity);
+ return list;
+}
+
+static void list_resize(list_t *list) {
+ if (list->length == list->capacity) {
+ list->capacity += 10;
+ list->items = realloc(list->items, sizeof(void*) * list->capacity);
+ }
+}
+
+void list_free(list_t *list) {
+ if (list == NULL) {
+ return;
+ }
+ free(list->items);
+ free(list);
+}
+
+void list_foreach(list_t *list, void (*callback)(void *item)) {
+ if (list == NULL || callback == NULL) {
+ return;
+ }
+ for (size_t i = 0; i < list->length; i++) {
+ callback(list->items[i]);
+ }
+}
+
+void list_add(list_t *list, void *item) {
+ list_resize(list);
+ list->items[list->length++] = item;
+}
+
+void list_push(list_t *list, void *item) {
+ list_add(list, item);
+}
+
+void list_insert(list_t *list, size_t index, void *item) {
+ list_resize(list);
+ memmove(&list->items[index + 1], &list->items[index], sizeof(void*) * (list->length - index));
+ list->length++;
+ list->items[index] = item;
+}
+
+void list_del(list_t *list, size_t index) {
+ list->length--;
+ memmove(&list->items[index], &list->items[index + 1], sizeof(void*) * (list->length - index));
+}
+
+void *list_pop(list_t *list) {
+ void *_ = list->items[list->length - 1];
+ list_del(list, list->length - 1);
+ return _;
+}
+
+void *list_peek(list_t *list) {
+ return list->items[list->length - 1];
+}
+
+void list_cat(list_t *list, list_t *source) {
+ size_t i;
+ for (i = 0; i < source->length; ++i) {
+ list_add(list, source->items[i]);
+ }
+}
+
+void list_qsort(list_t* list, int compare(const void *left, const void *right)) {
+ qsort(list->items, list->length, sizeof(void *), compare);
+}
+
+int list_seq_find(list_t *list,
+ int compare(const void *item, const void *data),
+ const void *data) {
+ for (size_t i = 0; i < list->length; i++) {
+ void *item = list->items[i];
+ if (compare(item, data) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
diff --git a/common/log.c b/common/log.c
new file mode 100644
index 00000000..7e59fcca
--- /dev/null
+++ b/common/log.c
@@ -0,0 +1,100 @@
+#define _POSIX_C_SOURCE 1
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include "wlr/common/log.h"
+#include "common/log.h"
+
+static bool colored = true;
+static log_callback_t log_callback;
+
+static const char *verbosity_colors[] = {
+ [L_SILENT] = "",
+ [L_ERROR ] = "\x1B[1;31m",
+ [L_INFO ] = "\x1B[1;34m",
+ [L_DEBUG ] = "\x1B[1;30m",
+};
+
+void wlr_log_init(log_callback_t callback) {
+ log_callback = callback;
+ // TODO: Use log callback
+}
+
+void _wlr_vlog(const char *filename, int line, log_importance_t verbosity,
+ const char *format, va_list args) {
+ // prefix the time to the log message
+ static struct tm result;
+ static time_t t;
+ static struct tm *tm_info;
+ char buffer[26];
+
+ // get current time
+ t = time(NULL);
+ // convert time to local time (determined by the locale)
+ tm_info = localtime_r(&t, &result);
+ // generate time prefix
+ strftime(buffer, sizeof(buffer), "%x %X - ", tm_info);
+ fprintf(stderr, "%s", buffer);
+
+ unsigned int c = verbosity;
+ if (c > sizeof(verbosity_colors) / sizeof(char *) - 1) {
+ c = sizeof(verbosity_colors) / sizeof(char *) - 1;
+ }
+
+ if (colored && isatty(STDERR_FILENO)) {
+ fprintf(stderr, "%s", verbosity_colors[c]);
+ }
+
+ if (filename && line) {
+ const char *file = filename + strlen(filename);
+ while (file != filename && *file != '/') {
+ --file;
+ }
+ if (*file == '/') {
+ ++file;
+ }
+ fprintf(stderr, "[%s:%d] ", file, line);
+ }
+
+ vfprintf(stderr, format, args);
+
+ if (colored && isatty(STDERR_FILENO)) {
+ fprintf(stderr, "\x1B[0m");
+ }
+ fprintf(stderr, "\n");
+}
+
+void _wlr_log(const char *filename, int line, log_importance_t verbosity, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ _wlr_vlog(filename, line, verbosity, format, args);
+ va_end(args);
+}
+
+void wlr_log_errno(log_importance_t verbosity, char* format, ...) {
+ unsigned int c = verbosity;
+ if (c > sizeof(verbosity_colors) / sizeof(char *) - 1) {
+ c = sizeof(verbosity_colors) / sizeof(char *) - 1;
+ }
+
+ if (isatty(STDERR_FILENO)) {
+ fprintf(stderr, "%s", verbosity_colors[c]);
+ }
+
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+
+ fprintf(stderr, ": ");
+ fprintf(stderr, "%s", strerror(errno));
+
+ if (isatty(STDERR_FILENO)) {
+ fprintf(stderr, "\x1B[0m");
+ }
+ fprintf(stderr, "\n");
+}
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
new file mode 100644
index 00000000..73768393
--- /dev/null
+++ b/example/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_executable(example
+ main.c
+)
+
+target_link_libraries(example
+ wlr-backend
+)
diff --git a/example/main.c b/example/main.c
new file mode 100644
index 00000000..4240b9e3
--- /dev/null
+++ b/example/main.c
@@ -0,0 +1,19 @@
+#define _POSIX_C_SOURCE 200112L
+#include <stdlib.h>
+#include <wlr/backend.h>
+#include <wlr/backend/wayland.h>
+#include <wayland-server.h>
+
+int main(int argc, char **argv) {
+ // TODO: Move this stuff to a wlr backend selector function
+ char *_wl_display = getenv("WAYLAND_DISPLAY");
+ if (_wl_display) {
+ unsetenv("WAYLAND_DISPLAY");
+ setenv("_WAYLAND_DISPLAY", _wl_display, 1);
+ }
+ struct wl_display *wl_display = wl_display_create();
+ struct wlr_wl_backend *backend = wlr_wl_backend_init(wl_display, 1);
+ wlr_wl_backend_free(backend);
+ wl_display_destroy(wl_display);
+ return 0;
+}
diff --git a/include/backend/wayland.h b/include/backend/wayland.h
index 9a445af9..368b0724 100644
--- a/include/backend/wayland.h
+++ b/include/backend/wayland.h
@@ -1,9 +1,24 @@
-#ifndef _WLR_BACKEND_WAYLAND_INTERNAL_H
-#define _WLR_BACKEND_WAYLAND_INTERNAL_H
+#ifndef _WLR_INTERNAL_BACKEND_WAYLAND_H
+#define _WLR_INTERNAL_BACKEND_WAYLAND_H
-struct wlr_wayland_backend {
+#include <wayland-client.h>
+#include <wayland-server.h>
+#include <wlr/common/list.h>
+#include <wlr/wayland.h>
+
+struct wlr_wl_backend {
+ /* local state */
struct wl_display *local_display;
+ /* remote state */
struct wl_display *remote_display;
+ struct wl_registry *remote_registry;
+ struct wl_compositor *remote_compositor;
+ struct wl_shell *shell;
+ struct wl_shm *shm;
+ struct wlr_wl_seat *seat;
+ list_t *outputs;
};
+void wlr_wlb_registry_poll(struct wlr_wl_backend *backend);
+
#endif
diff --git a/include/common/log.h b/include/common/log.h
new file mode 100644
index 00000000..849f8ef0
--- /dev/null
+++ b/include/common/log.h
@@ -0,0 +1,18 @@
+#ifndef _WLR_INTERNAL_COMMON_LOG_H
+#define _WLR_INTERNAL_COMMON_LOG_H
+#include <stdbool.h>
+#include <wlr/common/log.h>
+
+void wlr_log_errno(log_importance_t verbosity, char* format, ...) __attribute__((format(printf,2,3)));
+
+void wlr_log_errno(log_importance_t verbosity, char* format, ...) __attribute__((format(printf,2,3)));
+
+void _wlr_log(const char *filename, int line, log_importance_t verbosity, const char* format, ...) __attribute__((format(printf,4,5)));
+
+#define wlr_log(VERBOSITY, FMT, ...) \
+ _wlr_log(__FILE__, __LINE__, VERBOSITY, FMT, ##__VA_ARGS__)
+
+#define wlr_vlog(VERBOSITY, FMT, VA_ARGS) \
+ _wlr_vlog(__FILE__, __LINE__, VERBOSITY, FMT, VA_ARGS)
+
+#endif
diff --git a/include/wlr/backend.h b/include/wlr/backend.h
new file mode 100644
index 00000000..527efa05
--- /dev/null
+++ b/include/wlr/backend.h
@@ -0,0 +1,7 @@
+#ifndef _WLR_BACKEND_H
+#define _WLR_BACKEND_H
+
+struct wlr_backend *wlr_backend_init();
+void wlr_backend_free(struct wlr_backend *backend);
+
+#endif
diff --git a/include/wlr/backend/wayland.h b/include/wlr/backend/wayland.h
new file mode 100644
index 00000000..4318cc26
--- /dev/null
+++ b/include/wlr/backend/wayland.h
@@ -0,0 +1,14 @@
+#ifndef _WLR_BACKEND_WAYLAND_INTERNAL_H
+#define _WLR_BACKEND_WAYLAND_INTERNAL_H
+
+#include <wayland-client.h>
+#include <wayland-server.h>
+#include <wlr/wayland.h>
+
+struct wlr_wl_backend;
+
+void wlr_wl_backend_free(struct wlr_wl_backend *backend);
+struct wlr_wl_backend *wlr_wl_backend_init(struct wl_display *display,
+ size_t outputs);
+
+#endif
diff --git a/include/wlr/common/list.h b/include/wlr/common/list.h
new file mode 100644
index 00000000..2bc82570
--- /dev/null
+++ b/include/wlr/common/list.h
@@ -0,0 +1,31 @@
+#ifndef _WLR_LIST_H
+#define _WLR_LIST_H
+
+#include <stddef.h>
+
+typedef struct {
+ size_t capacity;
+ size_t length;
+ void **items;
+} list_t;
+
+list_t *list_create(void);
+void list_free(list_t *list);
+void list_foreach(list_t *list, void (*callback)(void* item));
+void list_add(list_t *list, void *item);
+void list_push(list_t *list, void *item);
+void list_insert(list_t *list, size_t index, void *item);
+void list_del(list_t *list, size_t index);
+void *list_pop(list_t *list);
+void *list_peek(list_t *list);
+void list_cat(list_t *list, list_t *source);
+// See qsort. Remember to use *_qsort functions as compare functions,
+// because they dereference the left and right arguments first!
+void list_qsort(list_t *list, int compare(const void *left, const void *right));
+// Return index for first item in list that returns 0 for given compare
+// function or -1 if none matches.
+int list_seq_find(list_t *list,
+ int compare(const void *item, const void *cmp_to),
+ const void *cmp_to);
+
+#endif
diff --git a/include/wlr/common/log.h b/include/wlr/common/log.h
new file mode 100644
index 00000000..5b4d5a53
--- /dev/null
+++ b/include/wlr/common/log.h
@@ -0,0 +1,16 @@
+#ifndef _WLR_COMMON_LOG_H
+#define _WLR_COMMON_LOG_H
+#include <stdbool.h>
+
+typedef enum {
+ L_SILENT = 0,
+ L_ERROR = 1,
+ L_INFO = 2,
+ L_DEBUG = 3,
+} log_importance_t;
+
+typedef void (*log_callback_t)(log_importance_t importance, const char *fmt, va_list args);
+
+void init_log(log_callback_t callback);
+
+#endif
diff --git a/include/wlr/wayland.h b/include/wlr/wayland.h
new file mode 100644
index 00000000..1c0b30ae
--- /dev/null
+++ b/include/wlr/wayland.h
@@ -0,0 +1,32 @@
+#ifndef _WLR_WAYLAND_H
+#define _WLR_WAYLAND_H
+
+#include <wayland-server.h>
+#include <wlr/common/list.h>
+
+struct wlr_wl_seat {
+ struct wl_seat *wl_seat;
+ uint32_t capabilities;
+ const char *name;
+ list_t *outputs;
+ list_t *pointers;
+};
+
+struct wlr_wl_output {
+ struct wl_output *wl_output;
+ uint32_t flags;
+ uint32_t width, height;
+ uint32_t scale;
+};
+
+struct wlr_wl_keyboard {
+ struct wl_keyboard *wl_keyboard;
+};
+
+struct wlr_wl_pointer {
+ struct wl_pointer *wl_pointer;
+ struct wl_surface *current_surface;
+ wl_fixed_t x, y;
+};
+
+#endif