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);
}
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);
struct input *keyboard_device;
uint32_t name;
enum window_buffer_type buffer_type;
- int mapped;
EGLImageKHR *image;
cairo_surface_t *cairo_surface, *pending_surface;
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,
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;
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;
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;
}
}
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
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);
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)
{
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
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
surface_attach,
surface_map_toplevel,
surface_map_transient,
+ surface_map_fullscreen,
surface_damage
};
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
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);
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);
<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