diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | backend/CMakeLists.txt | 15 | ||||
| -rw-r--r-- | backend/wayland/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | backend/wayland/backend.c | 46 | ||||
| -rw-r--r-- | backend/wayland/registry.c | 29 | ||||
| -rw-r--r-- | common/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | common/list.c | 91 | ||||
| -rw-r--r-- | common/log.c | 100 | ||||
| -rw-r--r-- | example/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | example/main.c | 19 | ||||
| -rw-r--r-- | include/backend/wayland.h | 21 | ||||
| -rw-r--r-- | include/common/log.h | 18 | ||||
| -rw-r--r-- | include/wlr/backend.h | 7 | ||||
| -rw-r--r-- | include/wlr/backend/wayland.h | 14 | ||||
| -rw-r--r-- | include/wlr/common/list.h | 31 | ||||
| -rw-r--r-- | include/wlr/common/log.h | 16 | ||||
| -rw-r--r-- | include/wlr/wayland.h | 32 | 
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, +			®istry_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 | 
