Add initial basic support for fullscreen surfaces
This commit is contained in:
parent
5e4d83f499
commit
0ce245761c
@ -1017,6 +1017,10 @@ resize_handler(struct window *window,
|
||||
height = (pixel_height - 2 * terminal->margin) /
|
||||
(int32_t) terminal->extents.height;
|
||||
|
||||
if (terminal->fullscreen)
|
||||
window_set_child_size(terminal->window,
|
||||
pixel_width, pixel_height);
|
||||
|
||||
terminal_resize(terminal, width, height);
|
||||
}
|
||||
|
||||
@ -2283,7 +2287,6 @@ terminal_create(struct display *display, int fullscreen)
|
||||
terminal->display = display;
|
||||
terminal->margin = 5;
|
||||
|
||||
window_set_fullscreen(terminal->window, terminal->fullscreen);
|
||||
window_set_user_data(terminal->window, terminal);
|
||||
window_set_redraw_handler(terminal->window, redraw_handler);
|
||||
window_set_resize_handler(terminal->window, resize_handler);
|
||||
|
@ -99,7 +99,6 @@ struct window {
|
||||
struct input *keyboard_device;
|
||||
uint32_t name;
|
||||
enum window_buffer_type buffer_type;
|
||||
int mapped;
|
||||
|
||||
EGLImageKHR *image;
|
||||
cairo_surface_t *cairo_surface, *pending_surface;
|
||||
@ -599,15 +598,14 @@ window_attach_surface(struct window *window)
|
||||
wl_surface_attach(window->surface, buffer, x, y);
|
||||
wl_display_sync_callback(display->display, free_surface, window);
|
||||
|
||||
if (!window->mapped) {
|
||||
if (!window->parent)
|
||||
wl_surface_map_toplevel(window->surface);
|
||||
else
|
||||
wl_surface_map_transient(window->surface,
|
||||
window->parent->surface,
|
||||
window->x, window->y, 0);
|
||||
window->mapped = 1;
|
||||
}
|
||||
if (window->fullscreen)
|
||||
wl_surface_map_fullscreen(window->surface);
|
||||
else if (!window->parent)
|
||||
wl_surface_map_toplevel(window->surface);
|
||||
else
|
||||
wl_surface_map_transient(window->surface,
|
||||
window->parent->surface,
|
||||
window->x, window->y, 0);
|
||||
|
||||
wl_surface_damage(window->surface, 0, 0,
|
||||
window->allocation.width,
|
||||
@ -1086,10 +1084,10 @@ handle_configure(void *data, struct wl_shell *shell,
|
||||
struct window *window = wl_surface_get_user_data(surface);
|
||||
int32_t child_width, child_height;
|
||||
|
||||
/* FIXME this is probably the wrong place to check for width or
|
||||
height <= 0, but it prevents the compositor from crashing
|
||||
*/
|
||||
if(width <= 0 || height <= 0)
|
||||
/* FIXME: this is probably the wrong place to check for width
|
||||
* or height <= 0, but it prevents the compositor from crashing
|
||||
*/
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
window->resize_edges = edges;
|
||||
@ -1118,7 +1116,7 @@ void
|
||||
window_get_child_allocation(struct window *window,
|
||||
struct rectangle *allocation)
|
||||
{
|
||||
if (window->fullscreen && !window->decoration) {
|
||||
if (window->fullscreen || !window->decoration) {
|
||||
*allocation = window->allocation;
|
||||
} else {
|
||||
allocation->x = window->margin + 10;
|
||||
@ -1134,8 +1132,15 @@ void
|
||||
window_set_child_size(struct window *window, int32_t width, int32_t height)
|
||||
{
|
||||
if (!window->fullscreen) {
|
||||
window->allocation.x = 20 + window->margin;
|
||||
window->allocation.y = 60 + window->margin;
|
||||
window->allocation.width = width + 20 + window->margin * 2;
|
||||
window->allocation.height = height + 60 + window->margin * 2;
|
||||
} else {
|
||||
window->allocation.x = 0;
|
||||
window->allocation.y = 0;
|
||||
window->allocation.width = width;
|
||||
window->allocation.height = height;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1163,13 +1168,22 @@ window_schedule_redraw(struct window *window)
|
||||
void
|
||||
window_set_fullscreen(struct window *window, int fullscreen)
|
||||
{
|
||||
int32_t width, height;
|
||||
|
||||
if (window->fullscreen == fullscreen)
|
||||
return;
|
||||
|
||||
window->fullscreen = fullscreen;
|
||||
if (window->fullscreen) {
|
||||
window->saved_allocation = window->allocation;
|
||||
window->allocation = window->display->screen_allocation;
|
||||
width = window->display->screen_allocation.width;
|
||||
height = window->display->screen_allocation.height;
|
||||
} else {
|
||||
window->allocation = window->saved_allocation;
|
||||
width = window->saved_allocation.width - 20 - window->margin * 2;
|
||||
height = window->saved_allocation.height - 60 - window->margin * 2;
|
||||
}
|
||||
|
||||
(*window->resize_handler)(window, width, height, window->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -131,7 +131,7 @@ wlsc_surface_create(struct wlsc_compositor *compositor,
|
||||
|
||||
wl_list_init(&surface->surface.destroy_listener_list);
|
||||
wl_list_init(&surface->link);
|
||||
surface->mapped = 0;
|
||||
surface->map_type = WLSC_SURFACE_MAP_UNMAPPED;
|
||||
|
||||
glGenTextures(1, &surface->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, surface->texture);
|
||||
@ -403,13 +403,21 @@ wlsc_output_repaint(struct wlsc_output *output)
|
||||
|
||||
glViewport(0, 0, output->width, output->height);
|
||||
|
||||
if (output->background)
|
||||
wlsc_surface_draw(output->background, output);
|
||||
else
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
wl_list_for_each_reverse(es, &ec->surface_list, link)
|
||||
es = container_of(ec->surface_list.next, struct wlsc_surface, link);
|
||||
if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN &&
|
||||
es->fullscreen_output == output) {
|
||||
if (es->width < output->width || es->height < output->height)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
wlsc_surface_draw(es, output);
|
||||
} else {
|
||||
if (output->background)
|
||||
wlsc_surface_draw(output->background, output);
|
||||
else
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
wl_list_for_each_reverse(es, &ec->surface_list, link)
|
||||
wlsc_surface_draw(es, output);
|
||||
}
|
||||
|
||||
if (ec->focus)
|
||||
wl_list_for_each(eid, &ec->input_device_list, link)
|
||||
@ -475,16 +483,27 @@ surface_map_toplevel(struct wl_client *client,
|
||||
{
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
|
||||
if (es->mapped)
|
||||
switch (es->map_type) {
|
||||
case WLSC_SURFACE_MAP_UNMAPPED:
|
||||
es->x = 10 + random() % 400;
|
||||
es->y = 10 + random() % 400;
|
||||
wlsc_surface_update_matrix(es);
|
||||
wl_list_insert(&es->compositor->surface_list, &es->link);
|
||||
break;
|
||||
case WLSC_SURFACE_MAP_TOPLEVEL:
|
||||
return;
|
||||
case WLSC_SURFACE_MAP_FULLSCREEN:
|
||||
es->fullscreen_output = NULL;
|
||||
es->x = es->saved_x;
|
||||
es->y = es->saved_y;
|
||||
wlsc_surface_update_matrix(es);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
es->x = 10 + random() % 400;
|
||||
es->y = 10 + random() % 400;
|
||||
|
||||
wlsc_surface_update_matrix(es);
|
||||
wl_list_insert(&es->compositor->surface_list, &es->link);
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
es->mapped = 1;
|
||||
es->map_type = WLSC_SURFACE_MAP_TOPLEVEL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -495,16 +514,56 @@ surface_map_transient(struct wl_client *client,
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
struct wlsc_surface *pes = (struct wlsc_surface *) parent;
|
||||
|
||||
if (es->mapped)
|
||||
return;
|
||||
switch (es->map_type) {
|
||||
case WLSC_SURFACE_MAP_UNMAPPED:
|
||||
wl_list_insert(&es->compositor->surface_list, &es->link);
|
||||
break;
|
||||
case WLSC_SURFACE_MAP_FULLSCREEN:
|
||||
es->fullscreen_output = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
es->x = pes->x + x;
|
||||
es->y = pes->y + y;
|
||||
|
||||
wlsc_surface_update_matrix(es);
|
||||
wl_list_insert(&es->compositor->surface_list, &es->link);
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
es->mapped = 1;
|
||||
es->map_type = WLSC_SURFACE_MAP_TRANSIENT;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_map_fullscreen(struct wl_client *client, struct wl_surface *surface)
|
||||
{
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
struct wlsc_output *output;
|
||||
|
||||
switch (es->map_type) {
|
||||
case WLSC_SURFACE_MAP_UNMAPPED:
|
||||
es->x = 10 + random() % 400;
|
||||
es->y = 10 + random() % 400;
|
||||
wl_list_insert(&es->compositor->surface_list, &es->link);
|
||||
break;
|
||||
case WLSC_SURFACE_MAP_FULLSCREEN:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: Fullscreen on first output */
|
||||
/* FIXME: Handle output going away */
|
||||
output = container_of(es->compositor->output_list.next,
|
||||
struct wlsc_output, link);
|
||||
|
||||
es->saved_x = es->x;
|
||||
es->saved_y = es->y;
|
||||
es->x = (output->width - es->width) / 2;
|
||||
es->y = (output->height - es->height) / 2;
|
||||
es->fullscreen_output = output;
|
||||
wlsc_surface_update_matrix(es);
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
es->map_type = WLSC_SURFACE_MAP_FULLSCREEN;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -523,6 +582,7 @@ const static struct wl_surface_interface surface_interface = {
|
||||
surface_attach,
|
||||
surface_map_toplevel,
|
||||
surface_map_transient,
|
||||
surface_map_fullscreen,
|
||||
surface_damage
|
||||
};
|
||||
|
||||
|
@ -130,17 +130,26 @@ struct wlsc_vector {
|
||||
GLfloat f[4];
|
||||
};
|
||||
|
||||
enum wlsc_surface_map_type {
|
||||
WLSC_SURFACE_MAP_UNMAPPED,
|
||||
WLSC_SURFACE_MAP_TOPLEVEL,
|
||||
WLSC_SURFACE_MAP_TRANSIENT,
|
||||
WLSC_SURFACE_MAP_FULLSCREEN
|
||||
};
|
||||
|
||||
struct wlsc_surface {
|
||||
struct wl_surface surface;
|
||||
struct wlsc_compositor *compositor;
|
||||
GLuint texture;
|
||||
int32_t x, y, width, height;
|
||||
int32_t saved_x, saved_y;
|
||||
struct wl_list link;
|
||||
struct wlsc_matrix matrix;
|
||||
struct wlsc_matrix matrix_inv;
|
||||
struct wl_visual *visual;
|
||||
struct wl_buffer *buffer;
|
||||
int mapped;
|
||||
enum wlsc_surface_map_type map_type;
|
||||
struct wlsc_output *fullscreen_output;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -80,6 +80,8 @@ shell_move(struct wl_client *client, struct wl_shell *shell,
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
struct wlsc_move_grab *move;
|
||||
|
||||
/* FIXME: Reject if fullscreen */
|
||||
|
||||
move = malloc(sizeof *move);
|
||||
if (!move) {
|
||||
wl_client_post_no_memory(client);
|
||||
@ -174,6 +176,8 @@ shell_resize(struct wl_client *client, struct wl_shell *shell,
|
||||
enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
|
||||
/* FIXME: Reject if fullscreen */
|
||||
|
||||
resize = malloc(sizeof *resize);
|
||||
if (!resize) {
|
||||
wl_client_post_no_memory(client);
|
||||
|
@ -368,6 +368,16 @@
|
||||
<arg name="flags" type="uint"/>
|
||||
</request>
|
||||
|
||||
<!-- Map the surface as a fullscreen surface. There are a number
|
||||
of options here: on which output? if the surface size doesn't
|
||||
match the output size, do we scale, change resolution, or add
|
||||
black borders? is that something the client controls? what
|
||||
about transient surfaces, do they float on top of the
|
||||
fullscreen? what if there's already a fullscreen surface on
|
||||
the output, maybe you can only go fullscreen if you're
|
||||
active? -->
|
||||
<request name="map_fullscreen"/>
|
||||
|
||||
<!-- Notify the server that the attached buffer's contents have
|
||||
changed, and request a redraw. The arguments allow you to
|
||||
damage only a part of the surface, but the server may ignore
|
||||
|
Loading…
Reference in New Issue
Block a user