aboutsummaryrefslogtreecommitdiff
path: root/main.c
blob: acc328de7fbe81a45b4685917c35cc65607852dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>
#include <poll.h>
#include <unistd.h>

#include "array.h"
#include "state.h"
#include "wayland.h"
#include "graphics.h"
#include "input_field.h"
#include "font.h"
#include "array.h"

void poll_events(client_state* state);

void read_stdin(client_state* state) {
	ssize_t len = 0;
	size_t a;
	char* line = NULL;
	while((len = getline(&line, &a, stdin)) != -1) {
		if (line[len - 1] == '\n') {
			line[len - 1] = '\0';
			len -= 1;
		}
		if (len != 0) {
			array_add(state->items, (item_t){0});
			array_last(state->items).text = line;
		}
		line = NULL;
	}
	free(line);
}

int main() {
	client_state state = {0};
	state.running = true;
	state.input_buffer = array_new(char, 0);

	read_stdin(&state);

	// find font
	char* font = get_font("Monospace");
	if (!freetype_init(&state, font)) {
		fprintf(stderr, "Failed to Initalize FreeType\n");
	}
	free(font);

	// create font atlas
	atlas_init(&state);

	atlas_calc_item_widths(&state);

	// start wayland
	state.display = wl_display_connect(NULL);
	if (!state.display) {
		fprintf(stderr, "Failed to Connect to wayland display\n");
		return 0;
	}

	// bind globals and roundtrip
	setup_registry_and_globals(&state);
	wl_display_roundtrip(state.display);

	// set up other objects and roundtrip
	setup_seat(&state);
	create_surface(&state);
	wl_display_roundtrip(state.display);

	// set up graphics
	if (!init_gl(&state)) {
		fprintf(stderr, "Failed to Initalize EGL/OpenGL\n");
		return 1;
	}

	// create font altas textures
	atlas_create_texture(&state);

	initTextBuffer(&state, &state.input_buffer_text, "this is a test", strlen("this is a test"));

	// event loop
	while (state.running) {
		poll_events(&state);
		render_frame(&state);
	}

	array_free(state.items);
}

void poll_events(client_state* state) {
    enum { DISPLAY_FD, KEYREPEAT_FD };
    struct pollfd fds[] = {
        [DISPLAY_FD] = { wl_display_get_fd(state->display), POLLIN },
        [KEYREPEAT_FD] = { state->key_repeat_timer_fd, POLLIN },
    };

    bool event = false;
    while (!event) {
        while (wl_display_prepare_read(state->display) != 0) {
            if (wl_display_dispatch_pending(state->display) > 0) {
                return;
            }
        }
        if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) {
            wl_display_cancel_read(state->display);
            return;
        }
        if (fds[DISPLAY_FD].revents & POLLIN) {
            wl_display_read_events(state->display);
            if (wl_display_dispatch_pending(state->display) > 0)
                event = true;
        }
        else {
            wl_display_cancel_read(state->display);
        }
        if (fds[KEYREPEAT_FD].revents & POLLIN) {
            uint64_t repeats;
            if (read(state->key_repeat_timer_fd, &repeats, sizeof(repeats)) == 8) {
                for (uint64_t i = 0; i < repeats; i++) {
					type_key(state, state->repeat_key);
                }
                event = true;
            }
        }
    }
}