uint32_t crtc_id;
uint32_t conn_id;
- struct wl_signal destroy_signal;
- struct wl_signal mode_change_signal;
- struct wl_signal frame_signal;
-
int mode_count;
drmModeModeInfo *modes;
drmModeModeInfo *current_mode;
if (output->modes)
free(output->modes);
- wl_signal_emit(&output->destroy_signal, NULL);
-
free(output);
}
-static void
-drm_output_add_destroy_listener(void *o, struct wl_listener *listener)
-{
- drm_output_t *output = (drm_output_t *)o;
- wl_signal_add(&output->destroy_signal, listener);
-}
-
-static void
-drm_output_add_mode_change_listener(void *o, struct wl_listener *listener)
-{
- drm_output_t *output = (drm_output_t *)o;
- wl_signal_add(&output->mode_change_signal, listener);
-}
-
static int32_t
drm_output_get_subpixel_order(void *data)
{
/* TODO: Resize handleing. */
- wl_signal_emit(&output->mode_change_signal, NULL);
+ pepper_output_update_mode(output->base);
return PEPPER_TRUE;
}
}
pepper_renderer_attach_surface(((drm_output_t *)o)->renderer, surface, w, h);
}
-static void
-drm_output_add_frame_listener(void *o, struct wl_listener *listener)
-{
- drm_output_t *output = (drm_output_t *)o;
- wl_signal_add(&output->frame_signal, listener);
-}
-
struct pepper_output_backend drm_output_backend =
{
drm_output_destroy,
- drm_output_add_destroy_listener,
- drm_output_add_mode_change_listener,
drm_output_get_subpixel_order,
drm_output_get_maker_name,
drm_output_assign_planes,
drm_output_repaint,
drm_output_attach_surface,
- drm_output_add_frame_listener,
};
static struct udev_device *
output->drm = drm;
output->subpixel = conn->subpixel;
- wl_signal_init(&output->destroy_signal);
- wl_signal_init(&output->mode_change_signal);
- wl_signal_init(&output->frame_signal);
-
wl_list_insert(&drm->output_list, &output->link);
/* find crtc + connector */
if (!wl_list_empty(&drm->output_list))
{
drm_output_t *output, *next;
+
wl_list_for_each_safe(output, next, &drm->output_list, link)
- drm_output_destroy(output);
+ pepper_output_remove(output->base);
}
}
plane->output = NULL;
if (!output->page_flip_pending)
- wl_signal_emit(&output->frame_signal, NULL);
+ pepper_output_finish_frame(output->base, NULL);
}
static void
output->page_flip_pending = PEPPER_FALSE;
if (!output->vblank_pending)
- {
- wl_signal_emit(&output->frame_signal, NULL);
- }
+ pepper_output_finish_frame(output->base, NULL);
}
static int
if (output && conn->connection != DRM_MODE_CONNECTED)
{
- drm_output_destroy(output);
+ pepper_output_remove(output->base);
}
else if (!output && conn->connection == DRM_MODE_CONNECTED)
{
void
pepper_drm_output_destroy(pepper_drm_t *drm)
{
-
if (drm->renderer)
free(drm->renderer);
pixman_image_t *shadow_image;
pepper_bool_t use_shadow;
- struct wl_signal destroy_signal;
- struct wl_signal mode_change_signal;
- struct wl_signal frame_signal;
-
struct wl_event_source *frame_done_timer;
pepper_plane_t *primary_plane;
{
fbdev_output_t *output = (fbdev_output_t *)o;
- wl_signal_emit(&output->destroy_signal, NULL);
wl_list_remove(&output->link);
if (output->frame_done_timer)
free(output);
}
-static void
-fbdev_output_add_destroy_listener(void *o, struct wl_listener *listener)
-{
- fbdev_output_t *output = (fbdev_output_t *)o;
- wl_signal_add(&output->destroy_signal, listener);
-}
-
-static void
-fbdev_output_add_mode_change_listener(void *o, struct wl_listener *listener)
-{
- fbdev_output_t *output = (fbdev_output_t *)o;
- wl_signal_add(&output->mode_change_signal, listener);
-}
-
static int32_t
fbdev_output_get_subpixel_order(void *o)
{
pepper_renderer_attach_surface(((fbdev_output_t *)o)->renderer, surface, w, h);
}
-static void
-fbdev_output_add_frame_listener(void *o, struct wl_listener *listener)
-{
- fbdev_output_t *output = (fbdev_output_t *)o;
- wl_signal_add(&output->frame_signal, listener);
-}
-
struct pepper_output_backend fbdev_output_backend =
{
fbdev_output_destroy,
- fbdev_output_add_destroy_listener,
- fbdev_output_add_mode_change_listener,
fbdev_output_get_subpixel_order,
fbdev_output_get_maker_name,
fbdev_output_assign_planes,
fbdev_output_repaint,
fbdev_output_attach_surface,
- fbdev_output_add_frame_listener,
};
static pepper_bool_t
frame_done_handler(void* data)
{
fbdev_output_t *output = (fbdev_output_t *)data;
- wl_signal_emit(&output->frame_signal, NULL);
-
+ pepper_output_finish_frame(output->base, NULL);
return 1;
}
output->bpp = var_info.bits_per_pixel;
output->stride = output->w * (output->bpp / 8);
- wl_signal_init(&output->destroy_signal);
- wl_signal_init(&output->mode_change_signal);
- wl_signal_init(&output->frame_signal);
-
output->frame_buffer_pixels = mmap(NULL, output->h * output->stride,
PROT_WRITE, MAP_SHARED, fd, 0);
if (!output->frame_buffer_pixels)
}
static void
-handle_output_data_destroy(struct wl_listener *listener, void *data)
-{
- pepper_output_t *output = pepper_container_of(listener, pepper_output_t, data_destroy_listener);
- output->data = NULL;
- output->backend = NULL;
- pepper_output_destroy(output);
-}
-
-static void
-handle_mode_change(struct wl_listener *listener, void *data)
-{
- pepper_output_t *output = pepper_container_of(listener, pepper_output_t, mode_change_listener);
- output_update_mode(output);
- pepper_object_emit_event(&output->base, PEPPER_EVENT_OUTPUT_MODE_CHANGE, NULL);
-}
-
-static void
output_accumulate_damage(pepper_output_t *output)
{
pepper_list_t *l;
}
static void
-handle_output_frame(struct wl_listener *listener, void *data)
-{
- pepper_output_t *output = pepper_container_of(listener, pepper_output_t, frame.frame_listener);
-
- output->frame.pending = PEPPER_FALSE;
-
- /* TODO: Better repaint scheduling by putting a delay before repaint. */
- if (output->frame.scheduled)
- output_repaint(output);
-}
-
-static void
idle_repaint(void *data)
{
pepper_output_t *output = data;
pepper_plane_add_damage_region((pepper_plane_t *)l->item, region);
}
+PEPPER_API void
+pepper_output_finish_frame(pepper_output_t *output, struct timespec *ts)
+{
+ output->frame.pending = PEPPER_FALSE;
+
+ /* TODO: Better repaint scheduling by putting a delay before repaint. */
+ if (output->frame.scheduled)
+ output_repaint(output);
+}
+
+PEPPER_API void
+pepper_output_remove(pepper_output_t *output)
+{
+ pepper_output_destroy(output);
+}
+
+PEPPER_API void
+pepper_output_update_mode(pepper_output_t *output)
+{
+ output_update_mode(output);
+ pepper_object_emit_event(&output->base, PEPPER_EVENT_OUTPUT_MODE_CHANGE, NULL);
+}
+
PEPPER_API pepper_output_t *
pepper_compositor_add_output(pepper_compositor_t *compositor,
const pepper_output_backend_t *backend, const char *name, void *data)
pepper_list_insert(&compositor->output_list, &output->link);
output->link.item = output;
- /* Install listeners. */
- output->data_destroy_listener.notify = handle_output_data_destroy;
- backend->add_destroy_listener(data, &output->data_destroy_listener);
-
- output->mode_change_listener.notify = handle_mode_change;
- backend->add_mode_change_listener(data, &output->mode_change_listener);
-
- output->frame.frame_listener.notify = handle_output_frame;
- backend->add_frame_listener(data, &output->frame.frame_listener);
-
pepper_list_init(&output->plane_list);
pepper_object_emit_event(&compositor->base, PEPPER_EVENT_COMPOSITOR_OUTPUT_ADD, NULL);
output->compositor->output_id_allocator &= ~(1 << output->id);
pepper_list_remove(&output->link, NULL);
- if (output->backend && output->data)
- output->backend->destroy(output->data);
+ output->backend->destroy(output->data);
wl_global_destroy(output->global);
- wl_list_remove(&output->data_destroy_listener.link);
- wl_list_remove(&output->mode_change_listener.link);
- wl_list_remove(&output->frame.frame_listener.link);
pepper_object_fini(&output->base);
pepper_object_emit_event(&output->compositor->base,
pepper_output_backend_t *backend;
void *data;
- /* Listeners for backend-side events. */
- struct wl_listener data_destroy_listener;
- struct wl_listener mode_change_listener;
-
/* Frame state flags. */
struct {
pepper_bool_t scheduled;
pepper_bool_t pending;
- struct wl_listener frame_listener;
} frame;
pepper_list_t plane_list;
{
void (*destroy)(void *output);
- void (*add_destroy_listener)(void *output, struct wl_listener *listener);
- void (*add_mode_change_listener)(void *output, struct wl_listener *listener);
-
int32_t (*get_subpixel_order)(void *output);
const char * (*get_maker_name)(void *output);
const char * (*get_model_name)(void *output);
void (*assign_planes)(void *output, const pepper_list_t *view_list);
void (*repaint)(void *output, const pepper_list_t *plane_list);
void (*attach_surface)(void *output, pepper_surface_t *surface, int *w, int *h);
-
- void (*add_frame_listener)(void *output, struct wl_listener *listener);
};
PEPPER_API pepper_output_t *
PEPPER_API void
pepper_output_add_damage_region(pepper_output_t *output, pixman_region32_t *region);
+PEPPER_API void
+pepper_output_finish_frame(pepper_output_t *output, struct timespec *ts);
+
+PEPPER_API void
+pepper_output_remove(pepper_output_t *output);
+
+PEPPER_API void
+pepper_output_update_mode(pepper_output_t *output);
+
#ifdef __cplusplus
}
#endif
#define WL_HIDE_DEPRECATED
#include <wayland-server.h>
+#include <time.h>
+
#ifdef __cplusplus
extern "C" {
#endif
wl_event_source_check(conn->event_source);
wl_list_init(&conn->seat_list);
- wl_signal_init(&conn->destroy_signal);
+ wl_list_init(&conn->output_list);
conn->registry = wl_display_get_registry(conn->display);
wl_registry_add_listener(conn->registry, ®istry_listener, conn);
PEPPER_API void
pepper_wayland_destroy(pepper_wayland_t *conn)
{
- wl_signal_emit(&conn->destroy_signal, conn);
+ wayland_output_t *output, *tmp;
+
+ wl_list_for_each_safe(output, tmp, &conn->output_list, link)
+ pepper_output_destroy(output->base);
if (conn->pixman_renderer)
pepper_renderer_destroy(conn->pixman_renderer);
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_list seat_list;
+ struct wl_list output_list;
struct wl_signal destroy_signal;
pepper_output_t *base;
char name[32];
- struct wl_signal destroy_signal;
- struct wl_signal mode_change_signal;
- struct wl_signal frame_signal;
-
struct wl_listener conn_destroy_listener;
int32_t w, h;
#endif
pepper_plane_t *primary_plane;
+ struct wl_list link;
};
struct wayland_seat
struct wl_touch *wl_touch;
} touch;
- struct wl_list link;
+ struct wl_list link;
};
void
PEPPER_ASSERT(wl_list_empty(&output->shm.free_buffers));
PEPPER_ASSERT(wl_list_empty(&output->shm.attached_buffers));
- /* We are ready to emit mode change signal. */
- wl_signal_emit(&output->mode_change_signal, NULL);
+ pepper_output_update_mode(output->base);
}
static void
{
wayland_output_t *output = o;
- wl_signal_emit(&output->destroy_signal, output);
-
wl_list_remove(&output->conn_destroy_listener.link);
wl_surface_destroy(output->surface);
free(output);
}
-static void
-wayland_output_add_destroy_listener(void *o, struct wl_listener *listener)
-{
- wayland_output_t *output = o;
- wl_signal_add(&output->destroy_signal, listener);
-}
-
-static void
-wayland_output_add_mode_change_listener(void *o, struct wl_listener *listener)
-{
- wayland_output_t *output = o;
- wl_signal_add(&output->mode_change_signal, listener);
-}
-
static int32_t
wayland_output_get_subpixel_order(void *o)
{
/* TODO: Handle resize here. */
- wl_signal_emit(&output->mode_change_signal, output);
+ pepper_output_update_mode(output->base);
}
return PEPPER_TRUE;
wayland_output_t *output = data;
wl_callback_destroy(callback);
- wl_signal_emit(&output->frame_signal, NULL);
+ pepper_output_finish_frame(output->base, NULL);
}
static const struct wl_callback_listener frame_listener =
pepper_renderer_attach_surface(((wayland_output_t *)o)->renderer, surface, w, h);
}
-static void
-wayland_output_add_frame_listener(void *o, struct wl_listener *listener)
-{
- wayland_output_t *output = o;
- wl_signal_add(&output->frame_signal, listener);
-}
-
static const pepper_output_backend_t wayland_output_backend =
{
wayland_output_destroy,
- wayland_output_add_destroy_listener,
- wayland_output_add_mode_change_listener,
wayland_output_get_subpixel_order,
wayland_output_get_maker_name,
wayland_output_assign_planes,
wayland_output_repaint,
wayland_output_attach_surface,
- wayland_output_add_frame_listener,
};
static void
-handle_connection_destroy(struct wl_listener *listener, void *data)
-{
- wayland_output_t *output =
- pepper_container_of(listener, wayland_output_t, conn_destroy_listener);
-
- wayland_output_destroy(output);
-}
-
-static void
pixman_render_pre(wayland_output_t *output)
{
wayland_shm_buffer_t *buffer = NULL;
return NULL;
output->conn = conn;
-
- wl_signal_init(&output->destroy_signal);
- wl_signal_init(&output->mode_change_signal);
- wl_signal_init(&output->frame_signal);
-
output->w = w;
output->h = h;
return NULL;
}
- output->conn_destroy_listener.notify = handle_connection_destroy;
- wl_signal_add(&conn->destroy_signal, &output->conn_destroy_listener);
-
/* Create renderer. */
if (!init_renderer(output, renderer))
{
}
output->primary_plane = pepper_output_add_plane(output->base, NULL);
+ wl_list_insert(&conn->output_list, &output->link);
+
return output->base;
}
if ( window == output->window )
return output;
}
+
return NULL;
}
wl_event_source_check(connection->xcb_event_source);
wl_list_init(&connection->outputs);
- wl_signal_init(&connection->destroy_signal);
return connection;
}
PEPPER_API void
pepper_x11_destroy(pepper_x11_connection_t *conn)
{
- wl_signal_emit(&conn->destroy_signal, conn);
+ x11_output_t *output, *tmp;
+
+ x11_seat_destroy(conn->seat);
+
+ wl_list_for_each_safe(output, tmp, &conn->outputs, link)
+ x11_output_destroy(output);
if (conn->xcb_event_source)
wl_event_source_remove(conn->xcb_event_source);
xcb_flush(conn);
}
-static void
+void
x11_seat_destroy(void *data)
{
x11_seat_t *seat = (x11_seat_t *)data;
free(seat);
}
-static void
-handle_connection_destroy(struct wl_listener *listener, void *data)
-{
- x11_seat_t *seat = wl_container_of(listener, seat, conn_destroy_listener);
- x11_seat_destroy(seat);
-}
-
PEPPER_API pepper_bool_t
pepper_x11_input_create(pepper_x11_connection_t* conn)
{
/* XXX: if x-input-module used without x-output-module,
* need to create dummy window for input with output-size */
- seat->conn_destroy_listener.notify = handle_connection_destroy;
- wl_signal_add(&conn->destroy_signal, &seat->conn_destroy_listener);
-
seat->id = X11_BACKEND_INPUT_ID;
/* Init XKB extension */
pepper_render_target_t *target;
pepper_render_target_t *gl_target;
- struct wl_signal destroy_signal;
- struct wl_signal mode_change_signal;
- struct wl_signal frame_signal;
-
struct wl_event_source *frame_done_timer;
struct wl_listener conn_destroy_listener;
xcb_atom_t xkb_names;
} atom;
- struct wl_signal destroy_signal;
-
pepper_renderer_t *pixman_renderer;
pepper_renderer_t *gl_renderer;
};
void
x11_output_destroy(void *o);
+void
+x11_seat_destroy(void *data);
+
#endif /*X11_INTERNAL_H*/
frame_done_handler(void* data)
{
x11_output_t *output = data;
- wl_signal_emit(&output->frame_signal, NULL);
-
+ pepper_output_finish_frame(output->base, NULL);
return 1;
}
xcb_destroy_window(conn->xcb_connection, output->window);
- wl_signal_emit(&output->destroy_signal, output);
-
wl_list_remove(&output->link);
xcb_flush(conn->xcb_connection);
xcb_flush(output->connection->xcb_connection);
}
- wl_signal_emit(&output->mode_change_signal, output);
+ pepper_output_update_mode(output->base);
}
return PEPPER_TRUE;
}
static void
-x11_output_add_destroy_listener(void *o, struct wl_listener *listener)
-{
- x11_output_t *output = o;
- wl_signal_add(&output->destroy_signal, listener);
-}
-
-static void
-x11_output_add_mode_change_listener(void *o, struct wl_listener *listener)
-{
- x11_output_t *output = o;
- wl_signal_add(&output->mode_change_signal, listener);
-}
-
-static void
x11_output_assign_planes(void *o, const pepper_list_t *view_list)
{
x11_output_t *output = (x11_output_t *)o;
pepper_renderer_attach_surface(((x11_output_t *)o)->renderer, surface, w, h);
}
-static void
-x11_output_add_frame_listener(void *o, struct wl_listener *listener)
-{
- x11_output_t *output = o;
- wl_signal_add(&output->frame_signal, listener);
-}
-
/* X11 output backend to export for PePPer core */
static const pepper_output_backend_t x11_output_backend =
{
x11_output_destroy,
- x11_output_add_destroy_listener,
- x11_output_add_mode_change_listener,
x11_output_get_subpixel_order,
x11_output_get_maker_name,
x11_output_assign_planes,
x11_output_repaint,
x11_output_attach_surface,
- x11_output_add_frame_listener,
};
-static void
-handle_connection_destroy(struct wl_listener *listener, void *data)
-{
- x11_output_t *output = pepper_container_of(listener, x11_output_t, conn_destroy_listener);
- x11_output_destroy(output);
-}
-
PEPPER_API pepper_output_t *
pepper_x11_output_create(pepper_x11_connection_t *connection,
int32_t w,
output->window);
wl_list_insert(&connection->outputs, &output->link);
-
xcb_flush(connection->xcb_connection);
-
x11_output_wait_for_map(output);
}
- /* Init signals and listeners */
- wl_signal_init(&output->destroy_signal);
- wl_signal_init(&output->mode_change_signal);
- wl_signal_init(&output->frame_signal);
-
wldisplay = pepper_compositor_get_display(connection->compositor);
loop = wl_display_get_event_loop(wldisplay);
output->frame_done_timer = wl_event_loop_add_timer(loop, frame_done_handler, output);
- output->conn_destroy_listener.notify = handle_connection_destroy;
- wl_signal_add(&connection->destroy_signal, &output->conn_destroy_listener);
-
/* Init renderer */
renderer_init(output, renderer);