Skip to content

Commit

Permalink
wm: add configure atom, event buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
ffwff committed Sep 6, 2019
1 parent 9497153 commit e6f2cb1
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 23 deletions.
37 changes: 33 additions & 4 deletions pkgs/wm/canvwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@ void canvas_ctx_draw_text(struct canvas_ctx *ctx, int xs, int ys, const char *s)
}
}

void window_redraw(struct canvas_ctx *ctx, int is_pressed) {
if(is_pressed) {
canvas_ctx_fill_rect(ctx, 0, 0, WIDTH, HEIGHT, canvas_color_rgb(0xff, 0xff, 0xff));
} else {
canvas_ctx_fill_rect(ctx, 0, 0, WIDTH, HEIGHT, canvas_color_rgb(0x32, 0x36, 0x39));
}
canvas_ctx_stroke_rect(ctx, 0, 0, WIDTH - 1, HEIGHT - 1, canvas_color_rgb(0x20, 0x21, 0x24));
}

int main(int argc, char **argv) {
struct canvas_ctx *ctx = canvas_ctx_create(WIDTH, HEIGHT, LIBCANVAS_FORMAT_RGB24);
canvas_ctx_fill_rect(ctx, 0, 0, WIDTH, HEIGHT, canvas_color_rgb(0x32, 0x36, 0x39));
canvas_ctx_stroke_rect(ctx, 0, 0, WIDTH - 1, HEIGHT - 1, canvas_color_rgb(0x20, 0x21, 0x24));
window_redraw(ctx, 0);

{
const char *title = "Hello World";
Expand Down Expand Up @@ -79,7 +87,14 @@ int main(int argc, char **argv) {
.type = GFX_BITBLIT_SURFACE
};

struct wm_atom configure_atom = {
.type = ATOM_CONFIGURE_MASK,
.configure.event_mask = 0,
};
write(sample_win_fd_s, (char *)&configure_atom, sizeof(configure_atom));

struct wm_atom atom;
int needs_redraw = 0;
int retval = 0;
while ((retval = read(sample_win_fd_m, (char *)&atom, sizeof(struct wm_atom))) >= 0) {
if(retval == 0)
Expand All @@ -90,14 +105,28 @@ int main(int argc, char **argv) {
};
switch (atom.type) {
case ATOM_REDRAW_TYPE: {
ioctl(fb_fd, GFX_BITBLIT, &sprite);
if (needs_redraw || atom.redraw.force_redraw) {
needs_redraw = 0;
ioctl(fb_fd, GFX_BITBLIT, &sprite);
respond_atom.respond.retval = 1;
}
write(sample_win_fd_s, (char *)&respond_atom, sizeof(respond_atom));
break;
}
case ATOM_MOVE_TYPE: {
sprite.x = atom.move.x;
sprite.y = atom.move.y;
respond_atom.respond.retval = 1;
needs_redraw = 1;
write(sample_win_fd_s, (char *)&respond_atom, sizeof(respond_atom));
break;
}
case ATOM_MOUSE_EVENT_TYPE: {
if(atom.mouse_event.type == WM_MOUSE_PRESS) {
window_redraw(ctx, 1);
} else {
window_redraw(ctx, 0);
}
needs_redraw = 1;
write(sample_win_fd_s, (char *)&respond_atom, sizeof(respond_atom));
break;
}
Expand Down
File renamed without changes.
File renamed without changes.
106 changes: 92 additions & 14 deletions pkgs/wm/wm.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ static void panic(const char *s) {

#define min(x, y) ((x)<(y)?(x):(y))

#define PACKET_TIMEOUT 1000000
#define FRAME_TICK 1000000/60
#define PACKET_TIMEOUT 100000
#define FRAME_WAIT 10000

/* WM State */

Expand All @@ -60,19 +60,25 @@ struct wm_window;
struct wm_window_prog;
struct wm_window_sprite;

#define WM_EVENT_QUEUE_LEN 128

struct wm_state {
int needs_redraw;
int mouse_fd;
struct wm_window *mouse_win; // weakref
struct wm_atom last_mouse_atom;
struct wm_window *windows;
int nwindows;
struct wm_atom queue[WM_EVENT_QUEUE_LEN];
int queue_len;
};

#define WM_WINDOW_PROG 0
#define WM_WINDOW_SPRITE 1

struct wm_window_prog {
int mfd, sfd;
unsigned long event_mask;
};

struct wm_window_sprite {
Expand All @@ -81,6 +87,7 @@ struct wm_window_sprite {

struct wm_window {
int type;
int wid;
union {
struct wm_window_prog prog;
struct wm_window_sprite sprite;
Expand All @@ -93,21 +100,24 @@ struct wm_window {
int win_write_and_wait(struct wm_window_prog *prog,
struct wm_atom *write_atom,
struct wm_atom *respond_atom) {
ftruncate(prog->mfd, 0);
write(prog->mfd, (char *)write_atom, sizeof(struct wm_atom));
if (waitfd(prog->sfd, PACKET_TIMEOUT) < 0) {
ftruncate(prog->mfd, 0);
ftruncate(prog->sfd, 0);
return 0;
}
// respond received
return read(prog->sfd, (char *)respond_atom, sizeof(struct wm_atom));
}

/* IMPL */
/* WINDOW */

struct wm_window *wm_add_window(struct wm_state *state) {
state->windows = realloc(state->windows, state->nwindows + 1);
return &state->windows[state->nwindows++];
struct wm_window *win = &state->windows[state->nwindows++];
memset(win, 0, sizeof(struct wm_window));
win->wid = state->nwindows;
return win;
}

struct wm_window *wm_add_win_prog(struct wm_state *state) {
Expand Down Expand Up @@ -135,6 +145,16 @@ struct wm_window *wm_add_sprite(struct wm_state *state, struct wm_window_sprite
return win;
}

void wm_handle_request_atom(struct wm_state *state, struct wm_window *win, struct wm_atom *atom) {
switch (atom->type) {
case ATOM_CONFIGURE_TYPE: {
win->as.prog.event_mask = atom->configure.event_mask;
}
}
}

/* IMPL */

int wm_sort_windows_by_z_compar(const void *av, const void *bv) {
const struct wm_window *a = av, *b = bv;
if (a->z_index < b->z_index) return -1;
Expand All @@ -143,7 +163,26 @@ int wm_sort_windows_by_z_compar(const void *av, const void *bv) {
}

void wm_sort_windows_by_z(struct wm_state *state) {
int mouse_wid = state->mouse_win->wid;

qsort(state->windows, state->nwindows, sizeof(struct wm_window), wm_sort_windows_by_z_compar);

for (int i = 0; i < state->nwindows; i++) {
struct wm_window *win = &state->windows[i];
if (win->wid == mouse_wid) {
state->mouse_win = win;
break;
}
}
}

/* QUEUE */

void wm_add_queue(struct wm_state *state, struct wm_atom *atom) {
if(state->queue_len == WM_EVENT_QUEUE_LEN) {
return;
}
state->queue[state->queue_len++] = *atom;
}

int main(int argc, char **argv) {
Expand Down Expand Up @@ -222,28 +261,67 @@ int main(int argc, char **argv) {

unsigned int speed = __builtin_ffs(mouse_packet.x + mouse_packet.y);
struct fbdev_bitblit *sprite = &wm.mouse_win->as.sprite.sprite;

struct wm_atom mouse_atom = { 0 };
mouse_atom.type = ATOM_MOUSE_EVENT_TYPE;

if (mouse_packet.x != 0) {
// left = negative
sprite->x += mouse_packet.x * speed;
sprite->x = min(sprite->x, ws.ws_col);
wm.needs_redraw = 1;
}
mouse_atom.mouse_event.x = sprite->x;

if (mouse_packet.y != 0) {
// bottom = negative
sprite->y -= mouse_packet.y * speed;
sprite->y = min(sprite->y, ws.ws_col);
wm.needs_redraw = 1;
}
mouse_atom.mouse_event.y = sprite->y;

if ((mouse_packet.attr_byte & MOUSE_ATTR_LEFT_BTN) != 0) {
mouse_atom.mouse_event.type = WM_MOUSE_PRESS;
} else {
mouse_atom.mouse_event.type = WM_MOUSE_RELEASE;
}

if(!wm_atom_eq(&mouse_atom, &wm.last_mouse_atom)) {
wm_add_queue(&wm, &mouse_atom);
}

wm.last_mouse_atom = mouse_atom;
}
for (int i = 0; i < wm.nwindows; i++) {
struct wm_window *win = &wm.windows[i];
switch (win->type) {
case WM_WINDOW_PROG: {
int retval;
struct wm_atom respond_atom;

// read from queue
struct wm_atom req_atom;
while(
read(win->as.prog.sfd, (char *)&req_atom, sizeof(struct wm_atom))
== sizeof(struct wm_atom)
) {
wm_handle_request_atom(&wm, win, &req_atom);
}

// transmit events in queue
for(int i = 0; i < wm.queue_len; i++) {
if((win->as.prog.event_mask & (1 << wm.queue[i].type)) != 0) {
win_write_and_wait(&win->as.prog, &wm.queue[i], &respond_atom);
}
}

// request a redraw
struct wm_atom redraw_atom = {
.type = ATOM_REDRAW_TYPE
.type = ATOM_REDRAW_TYPE,
.redraw.force_redraw = wm.needs_redraw,
};
struct wm_atom respond_atom;
int retval = win_write_and_wait(&win->as.prog, &redraw_atom, &respond_atom);
retval = win_write_and_wait(&win->as.prog, &redraw_atom, &respond_atom);

if (retval > 0) {
if (respond_atom.respond.retval)
Expand All @@ -257,12 +335,12 @@ int main(int argc, char **argv) {
}
}
}
ioctl(fb_fd, GFX_SWAPBUF, 0);
//if (wm.needs_redraw || 1) {
// wm.needs_redraw = 0;
//}
// TODO: consistent frame rate
usleep(FRAME_TICK);
if (wm.needs_redraw) {
ioctl(fb_fd, GFX_SWAPBUF, 0);
wm.needs_redraw = 0;
}
wm.queue_len = 0;
usleep(FRAME_WAIT);
}

return 0;
Expand Down
64 changes: 60 additions & 4 deletions pkgs/wm/wm.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,83 @@
#pragma once

// Configure

struct wm_atom_configure {
unsigned long event_mask;
};

// Move

struct wm_atom_move {
unsigned long x;
unsigned long y;
};

// Redraw

struct wm_atom_redraw {
int needs_redraw;
int force_redraw;
};

// Response

struct wm_atom_respond {
int retval;
};

// Mouse event
enum wm_atom_mouse_event_type {
WM_MOUSE_RELEASE = 0,
WM_MOUSE_PRESS = 1,
};

struct wm_atom_mouse_event {
enum wm_atom_mouse_event_type type;
unsigned long x, y;
};

struct wm_atom {
int type;
union {
struct wm_atom_redraw redraw;
struct wm_atom_move move;
struct wm_atom_respond respond;
struct wm_atom_mouse_event mouse_event;
struct wm_atom_configure configure;
};
};

#define ATOM_REDRAW_TYPE 0
#define ATOM_RESPOND_TYPE 1
#define ATOM_MOVE_TYPE 2
#define ATOM_REDRAW_TYPE 0
#define ATOM_RESPOND_TYPE 1
#define ATOM_MOVE_TYPE 2
#define ATOM_MOUSE_EVENT_TYPE 3
#define ATOM_CONFIGURE_TYPE 4

#define ATOM_REDRAW_MASK (1 << ATOM_REDRAW_TYPE)
#define ATOM_RESPOND_MASK (1 << ATOM_RESPOND_TYPE)
#define ATOM_MOVE_MASK (1 << ATOM_MOVE_TYPE)
#define ATOM_MOUSE_EVENT_MASK (1 << ATOM_MOUSE_EVENT_TYPE)
#define ATOM_CONFIGURE_MASK (1 << ATOM_CONFIGURE_TYPE)

static inline int wm_atom_eq(struct wm_atom *a, struct wm_atom *b) {
if(a->type != b->type)
return 0;
switch(a->type) {
case ATOM_REDRAW_TYPE: {
return 1;
}
case ATOM_RESPOND_TYPE: {
return a->respond.retval == b->respond.retval;
}
case ATOM_MOVE_TYPE: {
return a->move.x == b->move.x &&
a->move.y == b->move.y;
}
case ATOM_MOUSE_EVENT_TYPE: {
return a->mouse_event.type == b->mouse_event.type &&
a->mouse_event.x == b->mouse_event.x &&
a->mouse_event.y == b->mouse_event.y;
}
}
return 0;
}
2 changes: 1 addition & 1 deletion src/fs/impl/consolefs.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private class ConsoleFSNode < VFSNode
-1
end
when SC_IOCTL_TIOCGSTATE
Console.enabled = data == 0
Console.enabled = data == 1
Console.enabled ? 1 : 0
else
-1
Expand Down

0 comments on commit e6f2cb1

Please sign in to comment.