mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	Factor out session switching stuff to struct wlsc_session.
This commit is contained in:
		
							parent
							
								
									b22382bfdc
								
							
						
					
					
						commit
						8da19acab7
					
				
					 1 changed files with 275 additions and 149 deletions
				
			
		| 
						 | 
					@ -129,11 +129,17 @@ struct wlsc_compositor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t meta_state;
 | 
						uint32_t meta_state;
 | 
				
			||||||
	struct wl_list animate_list;
 | 
						struct wl_list animate_list;
 | 
				
			||||||
	struct wlsc_surface *primary;
 | 
					
 | 
				
			||||||
 | 
						struct wlsc_session *primary;
 | 
				
			||||||
 | 
						struct wl_list session_list;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define META_DOWN 256
 | 
					#define META_DOWN 256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlsc_vector {
 | 
				
			||||||
 | 
						GLdouble x, y, z;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlsc_animate {
 | 
					struct wlsc_animate {
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
	void (*animate)(struct wlsc_animate *animate, 
 | 
						void (*animate)(struct wlsc_animate *animate, 
 | 
				
			||||||
| 
						 | 
					@ -141,8 +147,13 @@ struct wlsc_animate {
 | 
				
			||||||
			uint32_t frame, uint32_t msecs);
 | 
								uint32_t frame, uint32_t msecs);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlsc_vector {
 | 
					struct wlsc_session {
 | 
				
			||||||
	GLdouble x, y, z;
 | 
						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 {
 | 
					struct wlsc_surface {
 | 
				
			||||||
| 
						 | 
					@ -156,9 +167,8 @@ struct wlsc_surface {
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
	struct wlsc_matrix matrix;
 | 
						struct wlsc_matrix matrix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlsc_vector target, current, previous;
 | 
						/* FIXME: This should be it's own object at some point. */
 | 
				
			||||||
	GLdouble target_angle, current_angle, previous_angle;
 | 
						struct wlsc_session session;
 | 
				
			||||||
	struct wlsc_animate animate;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *option_background = "background.jpg";
 | 
					static const char *option_background = "background.jpg";
 | 
				
			||||||
| 
						 | 
					@ -317,21 +327,6 @@ wlsc_matrix_rotate(struct wlsc_matrix *matrix,
 | 
				
			||||||
	wlsc_matrix_multiply(matrix, &rotate);
 | 
						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
 | 
					static void
 | 
				
			||||||
wlsc_surface_init(struct wlsc_surface *surface,
 | 
					wlsc_surface_init(struct wlsc_surface *surface,
 | 
				
			||||||
		  struct wlsc_compositor *compositor, struct wl_visual *visual,
 | 
							  struct wlsc_compositor *compositor, struct wl_visual *visual,
 | 
				
			||||||
| 
						 | 
					@ -345,17 +340,7 @@ wlsc_surface_init(struct wlsc_surface *surface,
 | 
				
			||||||
	surface->map.height = height;
 | 
						surface->map.height = height;
 | 
				
			||||||
	surface->surface = EGL_NO_SURFACE;
 | 
						surface->surface = EGL_NO_SURFACE;
 | 
				
			||||||
	surface->visual = visual;
 | 
						surface->visual = visual;
 | 
				
			||||||
	surface->current.x = 0;
 | 
						wlsc_matrix_init(&surface->matrix);
 | 
				
			||||||
	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);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlsc_surface *
 | 
					static struct wlsc_surface *
 | 
				
			||||||
| 
						 | 
					@ -391,17 +376,17 @@ static void
 | 
				
			||||||
wlsc_surface_destroy(struct wlsc_surface *surface,
 | 
					wlsc_surface_destroy(struct wlsc_surface *surface,
 | 
				
			||||||
		     struct wlsc_compositor *compositor)
 | 
							     struct wlsc_compositor *compositor)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_listener *l;
 | 
						struct wlsc_listener *l, *next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l = container_of(compositor->surface_destroy_listener_list.next,
 | 
						l = container_of(compositor->surface_destroy_listener_list.next,
 | 
				
			||||||
			 struct wlsc_listener, link);
 | 
								 struct wlsc_listener, link);
 | 
				
			||||||
	while (&l->link != &compositor->surface_destroy_listener_list) {
 | 
						while (&l->link != &compositor->surface_destroy_listener_list) {
 | 
				
			||||||
 | 
							next = container_of(l->link.next, struct wlsc_listener, link);
 | 
				
			||||||
		l->func(l, surface);
 | 
							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->link);
 | 
				
			||||||
	wl_list_remove(&surface->animate.link);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glDeleteTextures(1, &surface->texture);
 | 
						glDeleteTextures(1, &surface->texture);
 | 
				
			||||||
	if (surface->surface != EGL_NO_SURFACE)
 | 
						if (surface->surface != EGL_NO_SURFACE)
 | 
				
			||||||
| 
						 | 
					@ -555,6 +540,24 @@ wlsc_surface_draw(struct wlsc_surface *es)
 | 
				
			||||||
	glPopMatrix();
 | 
						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
 | 
					static void
 | 
				
			||||||
wlsc_vector_add(struct wlsc_vector *v1, struct wlsc_vector *v2)
 | 
					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);
 | 
							  output->height / s, -output->height / s, 1, 2 * s);
 | 
				
			||||||
	glMatrixMode(GL_MODELVIEW);
 | 
						glMatrixMode(GL_MODELVIEW);
 | 
				
			||||||
	glLoadIdentity();
 | 
						glLoadIdentity();
 | 
				
			||||||
	glClearColor(0, 0, 0.2, 1);
 | 
						glClearColor(0, 0, 0, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glTranslatef(-output->width / 2, -output->height / 2, -s / 2);
 | 
						glTranslatef(-output->width / 2, -output->height / 2, -s / 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -671,14 +674,14 @@ repaint(void *data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
schedule_repaint(struct wlsc_compositor *ec)
 | 
					wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wl_event_loop *loop;
 | 
						struct wl_event_loop *loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ec->repaint_needed = 1;
 | 
						compositor->repaint_needed = 1;
 | 
				
			||||||
	if (!ec->repaint_on_timeout) {
 | 
						if (!compositor->repaint_on_timeout) {
 | 
				
			||||||
		loop = wl_display_get_event_loop(ec->wl_display);
 | 
							loop = wl_display_get_event_loop(compositor->wl_display);
 | 
				
			||||||
		wl_event_loop_add_idle(loop, repaint, ec);
 | 
							wl_event_loop_add_idle(loop, repaint, compositor);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -691,7 +694,7 @@ surface_destroy(struct wl_client *client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlsc_surface_destroy(es, ec);
 | 
						wlsc_surface_destroy(es, ec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	schedule_repaint(ec);
 | 
						wlsc_compositor_schedule_repaint(ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -727,6 +730,9 @@ surface_attach(struct wl_client *client,
 | 
				
			||||||
	eglBindTexImage(ec->display, es->surface, GL_TEXTURE_2D);
 | 
						eglBindTexImage(ec->display, es->surface, GL_TEXTURE_2D);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					wlsc_session_update_matrix(struct wlsc_session *session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
surface_map(struct wl_client *client,
 | 
					surface_map(struct wl_client *client,
 | 
				
			||||||
	    struct wl_surface *surface,
 | 
						    struct wl_surface *surface,
 | 
				
			||||||
| 
						 | 
					@ -738,7 +744,8 @@ surface_map(struct wl_client *client,
 | 
				
			||||||
	es->map.y = y;
 | 
						es->map.y = y;
 | 
				
			||||||
	es->map.width = width;
 | 
						es->map.width = width;
 | 
				
			||||||
	es->map.height = height;
 | 
						es->map.height = height;
 | 
				
			||||||
	wlsc_surface_update_matrix(es);
 | 
					
 | 
				
			||||||
 | 
						wlsc_session_update_matrix(&es->session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -782,71 +789,210 @@ const static struct wl_surface_interface surface_interface = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
animate_surface(struct wlsc_animate *animate, 
 | 
					wlsc_session_update_matrix(struct wlsc_session *session)
 | 
				
			||||||
		struct wlsc_compositor *compositor,
 | 
					 | 
				
			||||||
		uint32_t frame, uint32_t msecs)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						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;
 | 
						struct wlsc_surface *s;
 | 
				
			||||||
	double angle_force, angle;
 | 
						double angle_force, angle;
 | 
				
			||||||
	struct wlsc_vector force, tmp;
 | 
						struct wlsc_vector force, tmp;
 | 
				
			||||||
	double step = 0.3;
 | 
						double step = 0.2;
 | 
				
			||||||
	double friction = 1;
 | 
						double friction = 1.5;
 | 
				
			||||||
	double spring = 0.2;
 | 
						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 = session->current_angle;
 | 
				
			||||||
	angle_force = (s->target_angle - angle) * spring +
 | 
						angle_force = (session->target_angle - angle) * spring +
 | 
				
			||||||
		(s->previous_angle - angle) * friction;
 | 
							(session->previous_angle - angle) * friction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s->current_angle = angle + (angle - s->previous_angle) + angle_force * step;
 | 
						session->current_angle =
 | 
				
			||||||
	s->previous_angle = angle;
 | 
							angle + (angle - session->previous_angle) + angle_force * step;
 | 
				
			||||||
 | 
						session->previous_angle = angle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	force = s->target;
 | 
						force = session->target;
 | 
				
			||||||
	wlsc_vector_subtract(&force, &s->current);
 | 
						wlsc_vector_subtract(&force, &session->current);
 | 
				
			||||||
	wlsc_vector_scalar(&force, spring);
 | 
						wlsc_vector_scalar(&force, spring);
 | 
				
			||||||
	tmp = s->previous;
 | 
						tmp = session->previous;
 | 
				
			||||||
	wlsc_vector_subtract(&tmp, &s->current);
 | 
						wlsc_vector_subtract(&tmp, &session->current);
 | 
				
			||||||
	wlsc_vector_scalar(&tmp, friction);
 | 
						wlsc_vector_scalar(&tmp, friction);
 | 
				
			||||||
	wlsc_vector_add(&force, &tmp);
 | 
						wlsc_vector_add(&force, &tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlsc_vector_scalar(&force, step);
 | 
						wlsc_vector_scalar(&force, step);
 | 
				
			||||||
	wlsc_vector_add(&force, &s->current);
 | 
						wlsc_vector_add(&force, &session->current);
 | 
				
			||||||
	wlsc_vector_subtract(&force, &s->previous);
 | 
						wlsc_vector_subtract(&force, &session->previous);
 | 
				
			||||||
	s->previous = s->current;
 | 
						session->previous = session->current;
 | 
				
			||||||
	wlsc_vector_add(&s->current, &force);
 | 
						wlsc_vector_add(&session->current, &force);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlsc_surface_update_matrix(s);
 | 
						wlsc_session_update_matrix(session);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	tmp = s->current;
 | 
						tmp = session->current;
 | 
				
			||||||
	wlsc_vector_subtract(&tmp, &s->target);
 | 
						wlsc_vector_subtract(&tmp, &session->target);
 | 
				
			||||||
	if (tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z > 0.001) {
 | 
						if (tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z > 0.001) {
 | 
				
			||||||
		schedule_repaint(compositor);
 | 
							wlsc_compositor_schedule_repaint(compositor);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		wl_list_remove(&s->animate.link);
 | 
							wl_list_remove(&session->animate.link);
 | 
				
			||||||
		wl_list_init(&s->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_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
 | 
					static void
 | 
				
			||||||
compositor_create_surface(struct wl_client *client,
 | 
					compositor_create_surface(struct wl_client *client,
 | 
				
			||||||
			  struct wl_compositor *compositor, uint32_t id)
 | 
								  struct wl_compositor *compositor, uint32_t id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
 | 
						struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
 | 
				
			||||||
	struct wlsc_surface *es;
 | 
						struct wlsc_surface *surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	es = malloc(sizeof *es);
 | 
						surface = malloc(sizeof *surface);
 | 
				
			||||||
	if (es == NULL)
 | 
						if (surface == NULL)
 | 
				
			||||||
		/* FIXME: Send OOM event. */
 | 
							/* FIXME: Send OOM event. */
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlsc_surface_init(es, ec, NULL, 0, 0, 0, 0);
 | 
						wlsc_surface_init(surface, ec, NULL, 0, 0, 0, 0);
 | 
				
			||||||
	es->animate.animate = animate_surface;
 | 
					 | 
				
			||||||
	wl_list_init(&es->animate.link);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(ec->surface_list.prev, &es->link);
 | 
						wl_list_insert(ec->surface_list.prev, &surface->link);
 | 
				
			||||||
	wl_client_add_surface(client, &es->base,
 | 
						wl_client_add_surface(client, &surface->base,
 | 
				
			||||||
			      &surface_interface, id);
 | 
								      &surface_interface, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlsc_session_init(&surface->session, surface);
 | 
				
			||||||
 | 
						wlsc_session_activate(ec, &surface->session);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -855,7 +1001,7 @@ compositor_commit(struct wl_client *client,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
 | 
						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);
 | 
						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.x = x - hotspot_x;
 | 
				
			||||||
	device->sprite->map.y = y - hotspot_y;
 | 
						device->sprite->map.y = y - hotspot_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	schedule_repaint(device->ec);
 | 
						wlsc_compositor_schedule_repaint(device->ec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
notify_button(struct wlsc_input_device *device,
 | 
					notify_button(struct wlsc_input_device *device,
 | 
				
			||||||
	      int32_t button, int32_t state)
 | 
						      int32_t button, int32_t state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct wlsc_surface *es;
 | 
						struct wlsc_surface *surface;
 | 
				
			||||||
	struct wlsc_compositor *ec = device->ec;
 | 
						struct wlsc_compositor *compositor = device->ec;
 | 
				
			||||||
	int32_t sx, sy;
 | 
						int32_t sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ec->vt_active)
 | 
						if (!compositor->vt_active)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	es = pick_surface(device, &sx, &sy);
 | 
						surface = pick_surface(device, &sx, &sy);
 | 
				
			||||||
	if (es) {
 | 
						if (surface) {
 | 
				
			||||||
		wl_list_remove(&es->link);
 | 
							wlsc_surface_raise(surface);
 | 
				
			||||||
		wl_list_insert(device->ec->surface_list.prev, &es->link);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (state) {
 | 
							if (state) {
 | 
				
			||||||
			/* FIXME: We need callbacks when the surfaces
 | 
					 | 
				
			||||||
			 * we reference here go away. */
 | 
					 | 
				
			||||||
			device->grab++;
 | 
								device->grab++;
 | 
				
			||||||
			device->grab_surface = es;
 | 
								device->grab_surface = surface;
 | 
				
			||||||
			wlsc_input_device_set_keyboard_focus(device, es);
 | 
								wlsc_input_device_set_keyboard_focus(device,
 | 
				
			||||||
 | 
												     surface);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			device->grab--;
 | 
								device->grab--;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* FIXME: Swallow click on raise? */
 | 
							/* 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,
 | 
									      WL_INPUT_BUTTON, button, state,
 | 
				
			||||||
				      device->x, device->y, sx, sy);
 | 
									      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 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
 | 
					void
 | 
				
			||||||
notify_key(struct wlsc_input_device *device,
 | 
					notify_key(struct wlsc_input_device *device,
 | 
				
			||||||
	   uint32_t key, uint32_t state)
 | 
						   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;
 | 
						uint32_t *k, *end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ec->vt_active)
 | 
						if (!compositor->vt_active)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (key | ec->meta_state) {
 | 
						switch (key | compositor->meta_state) {
 | 
				
			||||||
	case KEY_EJECTCD | META_DOWN:
 | 
						case KEY_EJECTCD | META_DOWN:
 | 
				
			||||||
		on_term_signal(SIGTERM, ec);
 | 
							on_term_signal(SIGTERM, compositor);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 	case KEY_1 | META_DOWN:
 | 
					 	case KEY_LEFT | META_DOWN:
 | 
				
			||||||
 	case KEY_2 | META_DOWN:
 | 
							if (!compositor->primary || !state)
 | 
				
			||||||
 	case KEY_3 | META_DOWN:
 | 
								break;
 | 
				
			||||||
 	case KEY_4 | META_DOWN:
 | 
							s = container_of(compositor->primary->link.prev,
 | 
				
			||||||
 	case KEY_5 | META_DOWN:
 | 
									 struct wlsc_session, link);
 | 
				
			||||||
		update_surface_targets(ec, key - KEY_1);
 | 
							if (&s->link != &compositor->session_list) {
 | 
				
			||||||
		if (device->grab == 0)
 | 
								wlsc_session_activate(compositor, s);
 | 
				
			||||||
			wlsc_input_device_set_keyboard_focus(device, ec->primary);
 | 
								if (device->grab == 0)
 | 
				
			||||||
			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;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case KEY_LEFTMETA:
 | 
						case KEY_LEFTMETA:
 | 
				
			||||||
	case KEY_RIGHTMETA:
 | 
						case KEY_RIGHTMETA:
 | 
				
			||||||
	case KEY_LEFTMETA | META_DOWN:
 | 
						case KEY_LEFTMETA | META_DOWN:
 | 
				
			||||||
	case KEY_RIGHTMETA | META_DOWN:
 | 
						case KEY_RIGHTMETA | META_DOWN:
 | 
				
			||||||
		ec->meta_state = state ? META_DOWN : 0;
 | 
							compositor->meta_state = state ? META_DOWN : 0;
 | 
				
			||||||
		if (state == 0 && ec->primary != NULL) {
 | 
					
 | 
				
			||||||
			ec->primary->target.z = 0;
 | 
							if (state == 0 && compositor->primary) {
 | 
				
			||||||
			wl_list_remove(&ec->primary->animate.link);
 | 
								s = compositor->primary;
 | 
				
			||||||
			wl_list_insert(&ec->animate_list,
 | 
								s->target.z = 0;
 | 
				
			||||||
				       &ec->primary->animate.link);
 | 
								wl_list_remove(&s->animate.link);
 | 
				
			||||||
			schedule_repaint(ec);
 | 
								wl_list_insert(compositor->animate_list.prev, &s->animate.link);
 | 
				
			||||||
 | 
								wlsc_compositor_schedule_repaint(compositor);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1542,9 +1667,10 @@ wlsc_compositor_create(struct wl_display *display)
 | 
				
			||||||
	setup_tty(ec, loop);
 | 
						setup_tty(ec, loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
 | 
						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->animate_list);
 | 
				
			||||||
 | 
						wl_list_init(&ec->session_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ec;
 | 
						return ec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue