Notify clients on mode_switch()

This patch implements the notification of clients during mode_switch.
As discussed on IRC, clients are notified of mode_switch only when the
"native" mode is changed and activated. That means that if the native
mode is changed and the compositor had activated a temporary mode for
a fullscreen surface, the clients will be notified only when the native
mode is restored.
The scaling factor is treated the same way as modes.
This commit is contained in:
Hardening
2013-09-18 23:56:36 +02:00
committed by Kristian Høgsberg
parent ff39efa5c0
commit 57388e44e5
10 changed files with 117 additions and 34 deletions
-1
View File
@@ -1944,7 +1944,6 @@ create_output_for_connector(struct drm_compositor *ec,
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
output->base.connection_internal = 1; output->base.connection_internal = 1;
output->base.original_mode = output->base.current_mode;
output->base.start_repaint_loop = drm_output_start_repaint_loop; output->base.start_repaint_loop = drm_output_start_repaint_loop;
output->base.repaint = drm_output_repaint; output->base.repaint = drm_output_repaint;
output->base.destroy = drm_output_destroy; output->base.destroy = drm_output_destroy;
-1
View File
@@ -544,7 +544,6 @@ fbdev_output_create(struct fbdev_compositor *compositor,
wl_list_insert(&output->base.mode_list, &output->mode.link); wl_list_insert(&output->base.mode_list, &output->mode.link);
output->base.current_mode = &output->mode; output->base.current_mode = &output->mode;
output->base.original_mode = &output->mode;
output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
output->base.make = "unknown"; output->base.make = "unknown";
output->base.model = output->fb_info.id; output->base.model = output->fb_info.id;
-1
View File
@@ -120,7 +120,6 @@ headless_compositor_create_output(struct headless_compositor *c,
output->finish_frame_timer = output->finish_frame_timer =
wl_event_loop_add_timer(loop, finish_frame_handler, output); wl_event_loop_add_timer(loop, finish_frame_handler, output);
output->base.original_mode = output->base.current_mode;
output->base.start_repaint_loop = headless_output_start_repaint_loop; output->base.start_repaint_loop = headless_output_start_repaint_loop;
output->base.repaint = headless_output_repaint; output->base.repaint = headless_output_repaint;
output->base.destroy = headless_output_destroy; output->base.destroy = headless_output_destroy;
+14 -11
View File
@@ -372,9 +372,10 @@ rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode) {
if(local_mode == output->current_mode) if(local_mode == output->current_mode)
return 0; return 0;
output->current_mode->flags = 0; output->current_mode->flags &= ~WL_OUTPUT_MODE_CURRENT;
output->current_mode = local_mode; output->current_mode = local_mode;
output->current_mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; output->current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
pixman_renderer_output_destroy(output); pixman_renderer_output_destroy(output);
pixman_renderer_output_create(output); pixman_renderer_output_create(output);
@@ -466,7 +467,7 @@ rdp_compositor_create_output(struct rdp_compositor *c, int width, int height,
goto out_free_output_and_modes; goto out_free_output_and_modes;
} }
output->base.current_mode = currentMode; output->base.current_mode = output->base.native_mode = currentMode;
weston_output_init(&output->base, &c->base, 0, 0, width, height, weston_output_init(&output->base, &c->base, 0, 0, width, height,
WL_OUTPUT_TRANSFORM_NORMAL, 1); WL_OUTPUT_TRANSFORM_NORMAL, 1);
@@ -489,7 +490,6 @@ rdp_compositor_create_output(struct rdp_compositor *c, int width, int height,
loop = wl_display_get_event_loop(c->base.wl_display); loop = wl_display_get_event_loop(c->base.wl_display);
output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);
output->base.original_mode = output->base.current_mode;
output->base.start_repaint_loop = rdp_output_start_repaint_loop; output->base.start_repaint_loop = rdp_output_start_repaint_loop;
output->base.repaint = rdp_output_repaint; output->base.repaint = rdp_output_repaint;
output->base.destroy = rdp_output_destroy; output->base.destroy = rdp_output_destroy;
@@ -687,15 +687,18 @@ xf_peer_post_connect(freerdp_peer* client)
if (output->base.width != (int)settings->DesktopWidth || if (output->base.width != (int)settings->DesktopWidth ||
output->base.height != (int)settings->DesktopHeight) output->base.height != (int)settings->DesktopHeight)
{ {
if(!settings->DesktopResize) { struct weston_mode new_mode;
weston_log("client don't support desktopResize()\n"); struct weston_mode *target_mode;
new_mode.width = (int)settings->DesktopWidth;
new_mode.height = (int)settings->DesktopHeight;
target_mode = find_matching_mode(&output->base, &new_mode);
if (!target_mode) {
weston_log("client mode not found\n");
return FALSE; return FALSE;
} }
weston_output_switch_mode(&output->base, target_mode, 1, WESTON_MODE_SWITCH_SET_NATIVE);
/* force the client size */ output->base.width = new_mode.width;
settings->DesktopWidth = output->base.width; output->base.height = new_mode.height;
settings->DesktopHeight = output->base.height;
client->update->DesktopResize(client->context);
} }
weston_log("kbd_layout:%x kbd_type:%x kbd_subType:%x kbd_functionKeys:%x\n", weston_log("kbd_layout:%x kbd_type:%x kbd_subType:%x kbd_functionKeys:%x\n",
-1
View File
@@ -370,7 +370,6 @@ rpi_output_create(struct rpi_compositor *compositor, uint32_t transform)
wl_list_insert(&output->base.mode_list, &output->mode.link); wl_list_insert(&output->base.mode_list, &output->mode.link);
output->base.current_mode = &output->mode; output->base.current_mode = &output->mode;
output->base.original_mode = &output->mode;
output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
output->base.make = "unknown"; output->base.make = "unknown";
output->base.model = "unknown"; output->base.model = "unknown";
-1
View File
@@ -295,7 +295,6 @@ wayland_compositor_create_output(struct wayland_compositor *c,
&shell_surface_listener, output); &shell_surface_listener, output);
wl_shell_surface_set_toplevel(output->parent.shell_surface); wl_shell_surface_set_toplevel(output->parent.shell_surface);
output->base.original_mode = output->base.current_mode;
output->base.start_repaint_loop = wayland_output_start_repaint_loop; output->base.start_repaint_loop = wayland_output_start_repaint_loop;
output->base.repaint = wayland_output_repaint; output->base.repaint = wayland_output_repaint;
output->base.destroy = wayland_output_destroy; output->base.destroy = wayland_output_destroy;
-1
View File
@@ -892,7 +892,6 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
output->base.set_dpms = NULL; output->base.set_dpms = NULL;
output->base.switch_mode = NULL; output->base.switch_mode = NULL;
output->base.current_mode = &output->mode; output->base.current_mode = &output->mode;
output->base.original_mode = output->base.current_mode;
output->base.make = "xwayland"; output->base.make = "xwayland";
output->base.model = "none"; output->base.model = "none";
weston_output_init(&output->base, &c->base, weston_output_init(&output->base, &c->base,
+79 -4
View File
@@ -96,20 +96,76 @@ static void
weston_compositor_build_surface_list(struct weston_compositor *compositor); weston_compositor_build_surface_list(struct weston_compositor *compositor);
WL_EXPORT int WL_EXPORT int
weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode, int32_t scale) weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode,
int32_t scale, enum weston_mode_switch_op op)
{ {
struct weston_seat *seat; struct weston_seat *seat;
struct wl_resource *resource;
pixman_region32_t old_output_region; pixman_region32_t old_output_region;
int ret; int ret, notify_mode_changed, notify_scale_changed;
int temporary_mode, temporary_scale;
if (!output->switch_mode) if (!output->switch_mode)
return -1; return -1;
temporary_mode = (output->original_mode != 0);
temporary_scale = (output->current_scale != output->original_scale);
ret = 0;
notify_mode_changed = 0;
notify_scale_changed = 0;
switch(op) {
case WESTON_MODE_SWITCH_SET_NATIVE:
output->native_mode = mode;
if (!temporary_mode) {
notify_mode_changed = 1;
ret = output->switch_mode(output, mode);
if (ret < 0)
return ret;
}
output->native_scale = scale;
if(!temporary_scale)
notify_scale_changed = 1;
break;
case WESTON_MODE_SWITCH_SET_TEMPORARY:
if (!temporary_mode)
output->original_mode = output->native_mode;
if (!temporary_scale)
output->original_scale = output->native_scale;
ret = output->switch_mode(output, mode); ret = output->switch_mode(output, mode);
if (ret < 0) if (ret < 0)
return ret; return ret;
output->current_mode = mode;
output->current_scale = scale; output->current_scale = scale;
break;
case WESTON_MODE_SWITCH_RESTORE_NATIVE:
if (!temporary_mode) {
weston_log("already in the native mode\n");
return -1;
}
notify_mode_changed = (output->original_mode != output->native_mode);
ret = output->switch_mode(output, mode);
if (ret < 0)
return ret;
if (output->original_scale != output->native_scale) {
notify_scale_changed = 1;
scale = output->native_scale;
output->original_scale = scale;
}
output->original_mode = 0;
output->current_scale = output->native_scale;
break;
default:
weston_log("unknown weston_switch_mode_op %d\n", op);
break;
}
pixman_region32_init(&old_output_region); pixman_region32_init(&old_output_region);
pixman_region32_copy(&old_output_region, &output->region); pixman_region32_copy(&old_output_region, &output->region);
@@ -152,6 +208,25 @@ weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode
pixman_region32_fini(&old_output_region); pixman_region32_fini(&old_output_region);
/* notify clients of the changes */
if (notify_mode_changed || notify_scale_changed) {
wl_resource_for_each(resource, &output->resource_list) {
if(notify_mode_changed) {
wl_output_send_mode(resource,
mode->flags | WL_OUTPUT_MODE_CURRENT,
mode->width,
mode->height,
mode->refresh);
}
if (notify_scale_changed)
wl_output_send_scale(resource, scale);
if (wl_resource_get_version(resource) >= 2)
wl_output_send_done(resource);
}
}
return ret; return ret;
} }
@@ -1874,7 +1949,7 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
* If this commit would cause the surface to move by the * If this commit would cause the surface to move by the
* attach(dx, dy) parameters, the old damage region must be * attach(dx, dy) parameters, the old damage region must be
* translated to correspond to the new surface coordinate system * translated to correspond to the new surface coordinate system
* origin. * original_mode.
*/ */
pixman_region32_translate(&sub->cached.damage, pixman_region32_translate(&sub->cached.damage,
-surface->pending.sx, -surface->pending.sy); -surface->pending.sx, -surface->pending.sy);
@@ -2728,7 +2803,7 @@ weston_output_transform_scale_init(struct weston_output *output, uint32_t transf
break; break;
} }
output->current_scale = scale; output->native_scale = output->current_scale = scale;
output->width /= scale; output->width /= scale;
output->height /= scale; output->height /= scale;
} }
+11 -2
View File
@@ -174,6 +174,12 @@ enum dpms_enum {
WESTON_DPMS_OFF WESTON_DPMS_OFF
}; };
enum weston_mode_switch_op {
WESTON_MODE_SWITCH_SET_NATIVE,
WESTON_MODE_SWITCH_SET_TEMPORARY,
WESTON_MODE_SWITCH_RESTORE_NATIVE
};
struct weston_output { struct weston_output {
uint32_t id; uint32_t id;
char *name; char *name;
@@ -203,11 +209,13 @@ struct weston_output {
char *make, *model, *serial_number; char *make, *model, *serial_number;
uint32_t subpixel; uint32_t subpixel;
uint32_t transform; uint32_t transform;
int32_t native_scale;
int32_t current_scale; int32_t current_scale;
int32_t original_scale;
struct weston_mode *native_mode;
struct weston_mode *current_mode; struct weston_mode *current_mode;
struct weston_mode *original_mode; struct weston_mode *original_mode;
int32_t original_scale;
struct wl_list mode_list; struct wl_list mode_list;
void (*start_repaint_loop)(struct weston_output *output); void (*start_repaint_loop)(struct weston_output *output);
@@ -1211,7 +1219,8 @@ void
weston_surface_destroy(struct weston_surface *surface); weston_surface_destroy(struct weston_surface *surface);
int int
weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode, int32_t scale); weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode,
int32_t scale, enum weston_mode_switch_op op);
int int
noop_renderer_init(struct weston_compositor *ec); noop_renderer_init(struct weston_compositor *ec);
+7 -5
View File
@@ -1627,11 +1627,12 @@ get_default_output(struct weston_compositor *compositor)
static void static void
restore_output_mode(struct weston_output *output) restore_output_mode(struct weston_output *output)
{ {
if (output->current != output->origin || if (output->current_mode != output->original_mode ||
(int32_t)output->scale != output->origin_scale) (int32_t)output->current_scale != output->original_scale)
weston_output_switch_mode(output, weston_output_switch_mode(output,
output->origin, output->original_mode,
output->origin_scale); output->original_scale,
WESTON_MODE_SWITCH_RESTORE_NATIVE);
} }
static void static void
@@ -1958,7 +1959,8 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
surf_height * surface->buffer_scale, surf_height * surface->buffer_scale,
shsurf->fullscreen.framerate}; shsurf->fullscreen.framerate};
if (weston_output_switch_mode(output, &mode, surface->buffer_scale) == 0) { if (weston_output_switch_mode(output, &mode, surface->buffer_scale,
WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) {
weston_surface_set_position(surface, weston_surface_set_position(surface,
output->x - surf_x, output->x - surf_x,
output->y - surf_y); output->y - surf_y);