|
|
|
@ -129,11 +129,17 @@ struct wlsc_compositor { |
|
|
|
|
|
|
|
|
|
uint32_t meta_state; |
|
|
|
|
struct wl_list animate_list; |
|
|
|
|
struct wlsc_surface *primary; |
|
|
|
|
|
|
|
|
|
struct wlsc_session *primary; |
|
|
|
|
struct wl_list session_list; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define META_DOWN 256 |
|
|
|
|
|
|
|
|
|
struct wlsc_vector { |
|
|
|
|
GLdouble x, y, z; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct wlsc_animate { |
|
|
|
|
struct wl_list link; |
|
|
|
|
void (*animate)(struct wlsc_animate *animate,
|
|
|
|
@ -141,8 +147,13 @@ struct wlsc_animate { |
|
|
|
|
uint32_t frame, uint32_t msecs); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct wlsc_vector { |
|
|
|
|
GLdouble x, y, z; |
|
|
|
|
struct wlsc_session { |
|
|
|
|
struct wlsc_surface *surface; |
|
|
|
|
struct wlsc_vector target, current, previous; |
|
|
|
|
GLdouble target_angle, current_angle, previous_angle; |
|
|
|
|
struct wlsc_animate animate; |
|
|
|
|
struct wl_list link; |
|
|
|
|
struct wlsc_listener listener; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct wlsc_surface { |
|
|
|
@ -156,9 +167,8 @@ struct wlsc_surface { |
|
|
|
|
struct wl_list link; |
|
|
|
|
struct wlsc_matrix matrix; |
|
|
|
|
|
|
|
|
|
struct wlsc_vector target, current, previous; |
|
|
|
|
GLdouble target_angle, current_angle, previous_angle; |
|
|
|
|
struct wlsc_animate animate; |
|
|
|
|
/* FIXME: This should be it's own object at some point. */ |
|
|
|
|
struct wlsc_session session; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static const char *option_background = "background.jpg"; |
|
|
|
@ -317,21 +327,6 @@ wlsc_matrix_rotate(struct wlsc_matrix *matrix, |
|
|
|
|
wlsc_matrix_multiply(matrix, &rotate); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_surface_update_matrix(struct wlsc_surface *es) |
|
|
|
|
{ |
|
|
|
|
GLdouble tx, ty; |
|
|
|
|
|
|
|
|
|
tx = es->map.x + es->map.width / 2; |
|
|
|
|
ty = es->map.y + es->map.height / 2; |
|
|
|
|
|
|
|
|
|
wlsc_matrix_init(&es->matrix); |
|
|
|
|
wlsc_matrix_translate(&es->matrix, -tx, -ty, 0); |
|
|
|
|
wlsc_matrix_rotate(&es->matrix, es->current_angle, 0, 1, 0); |
|
|
|
|
wlsc_matrix_translate(&es->matrix, tx + es->current.x, |
|
|
|
|
ty + es->current.y, es->current.z); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_surface_init(struct wlsc_surface *surface, |
|
|
|
|
struct wlsc_compositor *compositor, struct wl_visual *visual, |
|
|
|
@ -345,17 +340,7 @@ wlsc_surface_init(struct wlsc_surface *surface, |
|
|
|
|
surface->map.height = height; |
|
|
|
|
surface->surface = EGL_NO_SURFACE; |
|
|
|
|
surface->visual = visual; |
|
|
|
|
surface->current.x = 0; |
|
|
|
|
surface->current.y = 0; |
|
|
|
|
surface->current.z = 0; |
|
|
|
|
surface->current_angle = 0; |
|
|
|
|
surface->target.x = 0; |
|
|
|
|
surface->target.y = 0; |
|
|
|
|
surface->target.z = 0; |
|
|
|
|
surface->target_angle = 0; |
|
|
|
|
surface->previous_angle = 0; |
|
|
|
|
|
|
|
|
|
wlsc_surface_update_matrix(surface); |
|
|
|
|
wlsc_matrix_init(&surface->matrix); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct wlsc_surface * |
|
|
|
@ -391,17 +376,17 @@ static void |
|
|
|
|
wlsc_surface_destroy(struct wlsc_surface *surface, |
|
|
|
|
struct wlsc_compositor *compositor) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_listener *l; |
|
|
|
|
struct wlsc_listener *l, *next; |
|
|
|
|
|
|
|
|
|
l = container_of(compositor->surface_destroy_listener_list.next, |
|
|
|
|
struct wlsc_listener, link); |
|
|
|
|
while (&l->link != &compositor->surface_destroy_listener_list) { |
|
|
|
|
next = container_of(l->link.next, struct wlsc_listener, link); |
|
|
|
|
l->func(l, surface); |
|
|
|
|
l = container_of(l->link.next, struct wlsc_listener, link); |
|
|
|
|
l = next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_remove(&surface->link); |
|
|
|
|
wl_list_remove(&surface->animate.link); |
|
|
|
|
|
|
|
|
|
glDeleteTextures(1, &surface->texture); |
|
|
|
|
if (surface->surface != EGL_NO_SURFACE) |
|
|
|
@ -555,6 +540,24 @@ wlsc_surface_draw(struct wlsc_surface *es) |
|
|
|
|
glPopMatrix(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_surface_raise(struct wlsc_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *compositor = surface->compositor; |
|
|
|
|
|
|
|
|
|
wl_list_remove(&surface->link); |
|
|
|
|
wl_list_insert(compositor->surface_list.prev, &surface->link); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_surface_lower(struct wlsc_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *compositor = surface->compositor; |
|
|
|
|
|
|
|
|
|
wl_list_remove(&surface->link); |
|
|
|
|
wl_list_insert(&compositor->surface_list, &surface->link); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_vector_add(struct wlsc_vector *v1, struct wlsc_vector *v2) |
|
|
|
|
{ |
|
|
|
@ -599,7 +602,7 @@ repaint_output(struct wlsc_output *output) |
|
|
|
|
output->height / s, -output->height / s, 1, 2 * s); |
|
|
|
|
glMatrixMode(GL_MODELVIEW); |
|
|
|
|
glLoadIdentity(); |
|
|
|
|
glClearColor(0, 0, 0.2, 1); |
|
|
|
|
glClearColor(0, 0, 0, 1); |
|
|
|
|
|
|
|
|
|
glTranslatef(-output->width / 2, -output->height / 2, -s / 2); |
|
|
|
|
|
|
|
|
@ -671,14 +674,14 @@ repaint(void *data) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
schedule_repaint(struct wlsc_compositor *ec) |
|
|
|
|
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor) |
|
|
|
|
{ |
|
|
|
|
struct wl_event_loop *loop; |
|
|
|
|
|
|
|
|
|
ec->repaint_needed = 1; |
|
|
|
|
if (!ec->repaint_on_timeout) { |
|
|
|
|
loop = wl_display_get_event_loop(ec->wl_display); |
|
|
|
|
wl_event_loop_add_idle(loop, repaint, ec); |
|
|
|
|
compositor->repaint_needed = 1; |
|
|
|
|
if (!compositor->repaint_on_timeout) { |
|
|
|
|
loop = wl_display_get_event_loop(compositor->wl_display); |
|
|
|
|
wl_event_loop_add_idle(loop, repaint, compositor); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -691,7 +694,7 @@ surface_destroy(struct wl_client *client, |
|
|
|
|
|
|
|
|
|
wlsc_surface_destroy(es, ec); |
|
|
|
|
|
|
|
|
|
schedule_repaint(ec); |
|
|
|
|
wlsc_compositor_schedule_repaint(ec); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -727,6 +730,9 @@ surface_attach(struct wl_client *client, |
|
|
|
|
eglBindTexImage(ec->display, es->surface, GL_TEXTURE_2D); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_session_update_matrix(struct wlsc_session *session); |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
surface_map(struct wl_client *client, |
|
|
|
|
struct wl_surface *surface, |
|
|
|
@ -738,7 +744,8 @@ surface_map(struct wl_client *client, |
|
|
|
|
es->map.y = y; |
|
|
|
|
es->map.width = width; |
|
|
|
|
es->map.height = height; |
|
|
|
|
wlsc_surface_update_matrix(es); |
|
|
|
|
|
|
|
|
|
wlsc_session_update_matrix(&es->session); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -782,71 +789,210 @@ const static struct wl_surface_interface surface_interface = { |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
animate_surface(struct wlsc_animate *animate,
|
|
|
|
|
wlsc_session_update_matrix(struct wlsc_session *session) |
|
|
|
|
{ |
|
|
|
|
GLdouble tx, ty; |
|
|
|
|
struct wlsc_surface *s = session->surface; |
|
|
|
|
|
|
|
|
|
tx = s->map.x + s->map.width / 2; |
|
|
|
|
ty = s->map.y + s->map.height / 2; |
|
|
|
|
|
|
|
|
|
wlsc_matrix_init(&s->matrix); |
|
|
|
|
wlsc_matrix_translate(&s->matrix, -tx, -ty, 0); |
|
|
|
|
wlsc_matrix_rotate(&s->matrix, session->current_angle, 0, 1, 0); |
|
|
|
|
wlsc_matrix_translate(&s->matrix, tx + session->current.x, |
|
|
|
|
ty + session->current.y, session->current.z); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wl_session_animate(struct wlsc_animate *animate,
|
|
|
|
|
struct wlsc_compositor *compositor, |
|
|
|
|
uint32_t frame, uint32_t msecs) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_session *session; |
|
|
|
|
struct wlsc_surface *s; |
|
|
|
|
double angle_force, angle; |
|
|
|
|
struct wlsc_vector force, tmp; |
|
|
|
|
double step = 0.3; |
|
|
|
|
double friction = 1; |
|
|
|
|
double step = 0.2; |
|
|
|
|
double friction = 1.5; |
|
|
|
|
double spring = 0.2; |
|
|
|
|
|
|
|
|
|
s = container_of(animate, struct wlsc_surface, animate); |
|
|
|
|
session = container_of(animate, struct wlsc_session, animate); |
|
|
|
|
s = session->surface; |
|
|
|
|
|
|
|
|
|
angle = s->current_angle; |
|
|
|
|
angle_force = (s->target_angle - angle) * spring + |
|
|
|
|
(s->previous_angle - angle) * friction; |
|
|
|
|
angle = session->current_angle; |
|
|
|
|
angle_force = (session->target_angle - angle) * spring + |
|
|
|
|
(session->previous_angle - angle) * friction; |
|
|
|
|
|
|
|
|
|
s->current_angle = angle + (angle - s->previous_angle) + angle_force * step; |
|
|
|
|
s->previous_angle = angle; |
|
|
|
|
session->current_angle = |
|
|
|
|
angle + (angle - session->previous_angle) + angle_force * step; |
|
|
|
|
session->previous_angle = angle; |
|
|
|
|
|
|
|
|
|
force = s->target; |
|
|
|
|
wlsc_vector_subtract(&force, &s->current); |
|
|
|
|
force = session->target; |
|
|
|
|
wlsc_vector_subtract(&force, &session->current); |
|
|
|
|
wlsc_vector_scalar(&force, spring); |
|
|
|
|
tmp = s->previous; |
|
|
|
|
wlsc_vector_subtract(&tmp, &s->current); |
|
|
|
|
tmp = session->previous; |
|
|
|
|
wlsc_vector_subtract(&tmp, &session->current); |
|
|
|
|
wlsc_vector_scalar(&tmp, friction); |
|
|
|
|
wlsc_vector_add(&force, &tmp); |
|
|
|
|
|
|
|
|
|
wlsc_vector_scalar(&force, step); |
|
|
|
|
wlsc_vector_add(&force, &s->current); |
|
|
|
|
wlsc_vector_subtract(&force, &s->previous); |
|
|
|
|
s->previous = s->current; |
|
|
|
|
wlsc_vector_add(&s->current, &force); |
|
|
|
|
wlsc_vector_add(&force, &session->current); |
|
|
|
|
wlsc_vector_subtract(&force, &session->previous); |
|
|
|
|
session->previous = session->current; |
|
|
|
|
wlsc_vector_add(&session->current, &force); |
|
|
|
|
|
|
|
|
|
wlsc_surface_update_matrix(s); |
|
|
|
|
wlsc_session_update_matrix(session); |
|
|
|
|
|
|
|
|
|
tmp = s->current; |
|
|
|
|
wlsc_vector_subtract(&tmp, &s->target); |
|
|
|
|
tmp = session->current; |
|
|
|
|
wlsc_vector_subtract(&tmp, &session->target); |
|
|
|
|
if (tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z > 0.001) { |
|
|
|
|
schedule_repaint(compositor); |
|
|
|
|
wlsc_compositor_schedule_repaint(compositor); |
|
|
|
|
} else { |
|
|
|
|
wl_list_remove(&session->animate.link); |
|
|
|
|
wl_list_init(&session->animate.link); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_session_activate(struct wlsc_compositor *compositor, struct wlsc_session *session) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_session *s; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
compositor->primary = session; |
|
|
|
|
if (wl_list_empty(&compositor->session_list)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
session->target.x = 0; |
|
|
|
|
session->target.y = 0; |
|
|
|
|
session->target.z = -600; |
|
|
|
|
session->target_angle = 0; |
|
|
|
|
wl_list_remove(&session->animate.link); |
|
|
|
|
wl_list_insert(compositor->animate_list.prev, &session->animate.link); |
|
|
|
|
|
|
|
|
|
i = 0; |
|
|
|
|
s = container_of(session->link.prev, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
while (&s->link != &compositor->session_list) { |
|
|
|
|
s->target.x = -1000 - 500 * i; |
|
|
|
|
s->target.y = 0; |
|
|
|
|
s->target.z = -2500; |
|
|
|
|
s->target_angle = M_PI / 4; |
|
|
|
|
wl_list_remove(&s->animate.link); |
|
|
|
|
wl_list_init(&s->animate.link); |
|
|
|
|
wl_list_insert(compositor->animate_list.prev, &s->animate.link); |
|
|
|
|
wlsc_surface_lower(s->surface); |
|
|
|
|
|
|
|
|
|
s = container_of(s->link.prev, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
i = 0; |
|
|
|
|
s = container_of(session->link.next, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
while (&s->link != &compositor->session_list) { |
|
|
|
|
s->target.x = 1000 + 500 * i; |
|
|
|
|
s->target.y = 0; |
|
|
|
|
s->target.z = -2500; |
|
|
|
|
s->target_angle = -M_PI / 4; |
|
|
|
|
wl_list_remove(&s->animate.link); |
|
|
|
|
wl_list_insert(compositor->animate_list.prev, &s->animate.link); |
|
|
|
|
wlsc_surface_lower(s->surface); |
|
|
|
|
|
|
|
|
|
s = container_of(s->link.next, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wlsc_compositor_schedule_repaint(compositor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_session_handle_surface_destroy(struct wlsc_listener *listener, |
|
|
|
|
struct wlsc_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_session *session = |
|
|
|
|
container_of(listener, struct wlsc_session, listener); |
|
|
|
|
struct wlsc_compositor *compositor; |
|
|
|
|
struct wlsc_session *primary; |
|
|
|
|
|
|
|
|
|
if (session->surface != surface) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
compositor = session->surface->compositor; |
|
|
|
|
if (compositor->primary == session) { |
|
|
|
|
printf("destroy session %p [%p, %p]\n", session, session->link.prev, session->link.next); |
|
|
|
|
if (session->link.next != &compositor->session_list) |
|
|
|
|
primary = container_of(session->link.next, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
else if (session->link.prev != &compositor->session_list) |
|
|
|
|
primary = container_of(session->link.prev, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
else |
|
|
|
|
primary = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
wl_list_remove(&session->animate.link); |
|
|
|
|
wl_list_remove(&session->link); |
|
|
|
|
wl_list_remove(&session->listener.link); |
|
|
|
|
|
|
|
|
|
if (compositor->primary == session) { |
|
|
|
|
printf("activating session %p\n", primary); |
|
|
|
|
wlsc_session_activate(compositor, primary); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
wlsc_session_init(struct wlsc_session *session, struct wlsc_surface *surface) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *c = surface->compositor; |
|
|
|
|
|
|
|
|
|
session->animate.animate = wl_session_animate; |
|
|
|
|
wl_list_init(&session->animate.link); |
|
|
|
|
wl_list_insert(c->session_list.prev, &session->link); |
|
|
|
|
|
|
|
|
|
session->surface = surface; |
|
|
|
|
session->current.x = 0; |
|
|
|
|
session->current.y = 0; |
|
|
|
|
session->current.z = 0; |
|
|
|
|
session->current_angle = 0; |
|
|
|
|
session->target.x = 0; |
|
|
|
|
session->target.y = 0; |
|
|
|
|
session->target.z = 0; |
|
|
|
|
session->target_angle = 0; |
|
|
|
|
session->previous_angle = 0; |
|
|
|
|
|
|
|
|
|
wlsc_session_update_matrix(session); |
|
|
|
|
|
|
|
|
|
session->listener.func = wlsc_session_handle_surface_destroy; |
|
|
|
|
wl_list_insert(c->surface_destroy_listener_list.prev, |
|
|
|
|
&session->listener.link); |
|
|
|
|
|
|
|
|
|
printf("added session %p [%p, %p]\n", session, session->link.prev, session->link.next); |
|
|
|
|
printf(" - prev [%p]\n", session->link.prev->prev); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
compositor_create_surface(struct wl_client *client, |
|
|
|
|
struct wl_compositor *compositor, uint32_t id) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor; |
|
|
|
|
struct wlsc_surface *es; |
|
|
|
|
struct wlsc_surface *surface; |
|
|
|
|
|
|
|
|
|
es = malloc(sizeof *es); |
|
|
|
|
if (es == NULL) |
|
|
|
|
surface = malloc(sizeof *surface); |
|
|
|
|
if (surface == NULL) |
|
|
|
|
/* FIXME: Send OOM event. */ |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
wlsc_surface_init(es, ec, NULL, 0, 0, 0, 0); |
|
|
|
|
es->animate.animate = animate_surface; |
|
|
|
|
wl_list_init(&es->animate.link); |
|
|
|
|
wlsc_surface_init(surface, ec, NULL, 0, 0, 0, 0); |
|
|
|
|
|
|
|
|
|
wl_list_insert(ec->surface_list.prev, &es->link); |
|
|
|
|
wl_client_add_surface(client, &es->base, |
|
|
|
|
wl_list_insert(ec->surface_list.prev, &surface->link); |
|
|
|
|
wl_client_add_surface(client, &surface->base, |
|
|
|
|
&surface_interface, id); |
|
|
|
|
|
|
|
|
|
wlsc_session_init(&surface->session, surface); |
|
|
|
|
wlsc_session_activate(ec, &surface->session); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
@ -855,7 +1001,7 @@ compositor_commit(struct wl_client *client, |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor; |
|
|
|
|
|
|
|
|
|
schedule_repaint(ec); |
|
|
|
|
wlsc_compositor_schedule_repaint(ec); |
|
|
|
|
wl_client_send_acknowledge(client, compositor, key, ec->current_frame); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -982,121 +1128,100 @@ notify_motion(struct wlsc_input_device *device, int x, int y) |
|
|
|
|
device->sprite->map.x = x - hotspot_x; |
|
|
|
|
device->sprite->map.y = y - hotspot_y; |
|
|
|
|
|
|
|
|
|
schedule_repaint(device->ec); |
|
|
|
|
wlsc_compositor_schedule_repaint(device->ec); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
notify_button(struct wlsc_input_device *device, |
|
|
|
|
int32_t button, int32_t state) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_surface *es; |
|
|
|
|
struct wlsc_compositor *ec = device->ec; |
|
|
|
|
struct wlsc_surface *surface; |
|
|
|
|
struct wlsc_compositor *compositor = device->ec; |
|
|
|
|
int32_t sx, sy; |
|
|
|
|
|
|
|
|
|
if (!ec->vt_active) |
|
|
|
|
if (!compositor->vt_active) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
es = pick_surface(device, &sx, &sy); |
|
|
|
|
if (es) { |
|
|
|
|
wl_list_remove(&es->link); |
|
|
|
|
wl_list_insert(device->ec->surface_list.prev, &es->link); |
|
|
|
|
surface = pick_surface(device, &sx, &sy); |
|
|
|
|
if (surface) { |
|
|
|
|
wlsc_surface_raise(surface); |
|
|
|
|
|
|
|
|
|
if (state) { |
|
|
|
|
/* FIXME: We need callbacks when the surfaces
|
|
|
|
|
* we reference here go away. */ |
|
|
|
|
device->grab++; |
|
|
|
|
device->grab_surface = es; |
|
|
|
|
wlsc_input_device_set_keyboard_focus(device, es); |
|
|
|
|
device->grab_surface = surface; |
|
|
|
|
wlsc_input_device_set_keyboard_focus(device, |
|
|
|
|
surface); |
|
|
|
|
} else { |
|
|
|
|
device->grab--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* FIXME: Swallow click on raise? */ |
|
|
|
|
wl_surface_post_event(&es->base, &device->base, |
|
|
|
|
wl_surface_post_event(&surface->base, &device->base, |
|
|
|
|
WL_INPUT_BUTTON, button, state, |
|
|
|
|
device->x, device->y, sx, sy); |
|
|
|
|
|
|
|
|
|
schedule_repaint(device->ec); |
|
|
|
|
wlsc_compositor_schedule_repaint(compositor); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void on_term_signal(int signal_number, void *data); |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
update_surface_targets(struct wlsc_compositor *compositor, int primary) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_surface *s; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
i = 0; |
|
|
|
|
s = container_of(compositor->surface_list.next, |
|
|
|
|
struct wlsc_surface, link); |
|
|
|
|
while (&s->link != &compositor->surface_list) { |
|
|
|
|
if (i < primary) { |
|
|
|
|
s->target.x = -400 + 500 * (i - primary); |
|
|
|
|
s->target.y = 0; |
|
|
|
|
s->target.z = -1500; |
|
|
|
|
s->target_angle = M_PI / 4; |
|
|
|
|
} else if (i == primary) { |
|
|
|
|
s->target.x = 0; |
|
|
|
|
s->target.y = 0; |
|
|
|
|
s->target.z = -1000; |
|
|
|
|
s->target_angle = 0; |
|
|
|
|
compositor->primary = s; |
|
|
|
|
} else { |
|
|
|
|
s->target.x = 400 + 500 * (i - primary); |
|
|
|
|
s->target.y = 0; |
|
|
|
|
s->target.z = -1500; |
|
|
|
|
s->target_angle = -M_PI / 4; |
|
|
|
|
} |
|
|
|
|
wl_list_remove(&s->animate.link); |
|
|
|
|
wl_list_insert(compositor->animate_list.prev, &s->animate.link); |
|
|
|
|
s = container_of(s->link.next, |
|
|
|
|
struct wlsc_surface, link); |
|
|
|
|
i++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
schedule_repaint(compositor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
notify_key(struct wlsc_input_device *device, |
|
|
|
|
uint32_t key, uint32_t state) |
|
|
|
|
{ |
|
|
|
|
struct wlsc_compositor *ec = device->ec; |
|
|
|
|
struct wlsc_compositor *compositor = device->ec; |
|
|
|
|
struct wlsc_session *s; |
|
|
|
|
uint32_t *k, *end; |
|
|
|
|
|
|
|
|
|
if (!ec->vt_active) |
|
|
|
|
if (!compositor->vt_active) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
switch (key | ec->meta_state) { |
|
|
|
|
switch (key | compositor->meta_state) { |
|
|
|
|
case KEY_EJECTCD | META_DOWN: |
|
|
|
|
on_term_signal(SIGTERM, ec); |
|
|
|
|
on_term_signal(SIGTERM, compositor); |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
case KEY_1 | META_DOWN: |
|
|
|
|
case KEY_2 | META_DOWN: |
|
|
|
|
case KEY_3 | META_DOWN: |
|
|
|
|
case KEY_4 | META_DOWN: |
|
|
|
|
case KEY_5 | META_DOWN: |
|
|
|
|
update_surface_targets(ec, key - KEY_1); |
|
|
|
|
case KEY_LEFT | META_DOWN: |
|
|
|
|
if (!compositor->primary || !state) |
|
|
|
|
break; |
|
|
|
|
s = container_of(compositor->primary->link.prev, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
if (&s->link != &compositor->session_list) { |
|
|
|
|
wlsc_session_activate(compositor, s); |
|
|
|
|
if (device->grab == 0) |
|
|
|
|
wlsc_input_device_set_keyboard_focus(device, ec->primary); |
|
|
|
|
device->keyboard_focus = ec->primary; |
|
|
|
|
wlsc_input_device_set_keyboard_focus(device, s->surface); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case KEY_RIGHT | META_DOWN: |
|
|
|
|
if (!compositor->primary || !state) |
|
|
|
|
break; |
|
|
|
|
s = container_of(compositor->primary->link.next, |
|
|
|
|
struct wlsc_session, link); |
|
|
|
|
if (&s->link != &compositor->session_list) { |
|
|
|
|
wlsc_session_activate(compositor, s); |
|
|
|
|
if (device->grab == 0) |
|
|
|
|
wlsc_input_device_set_keyboard_focus(device, s->surface); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
case KEY_LEFTMETA: |
|
|
|
|
case KEY_RIGHTMETA: |
|
|
|
|
case KEY_LEFTMETA | META_DOWN: |
|
|
|
|
case KEY_RIGHTMETA | META_DOWN: |
|
|
|
|
ec->meta_state = state ? META_DOWN : 0; |
|
|
|
|
if (state == 0 && ec->primary != NULL) { |
|
|
|
|
ec->primary->target.z = 0; |
|
|
|
|
wl_list_remove(&ec->primary->animate.link); |
|
|
|
|
wl_list_insert(&ec->animate_list, |
|
|
|
|
&ec->primary->animate.link); |
|
|
|
|
schedule_repaint(ec); |
|
|
|
|
compositor->meta_state = state ? META_DOWN : 0; |
|
|
|
|
|
|
|
|
|
if (state == 0 && compositor->primary) { |
|
|
|
|
s = compositor->primary; |
|
|
|
|
s->target.z = 0; |
|
|
|
|
wl_list_remove(&s->animate.link); |
|
|
|
|
wl_list_insert(compositor->animate_list.prev, &s->animate.link); |
|
|
|
|
wlsc_compositor_schedule_repaint(compositor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1542,9 +1667,10 @@ wlsc_compositor_create(struct wl_display *display) |
|
|
|
|
setup_tty(ec, loop); |
|
|
|
|
|
|
|
|
|
ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec); |
|
|
|
|
schedule_repaint(ec); |
|
|
|
|
wlsc_compositor_schedule_repaint(ec); |
|
|
|
|
|
|
|
|
|
wl_list_init(&ec->animate_list); |
|
|
|
|
wl_list_init(&ec->session_list); |
|
|
|
|
|
|
|
|
|
return ec; |
|
|
|
|
} |
|
|
|
|