diff options
-rw-r--r-- | protocol/agl-shell-desktop.xml | 2 | ||||
-rw-r--r-- | src/desktop.c | 5 | ||||
-rw-r--r-- | src/ivi-compositor.h | 34 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/shell.c | 176 |
5 files changed, 206 insertions, 13 deletions
diff --git a/protocol/agl-shell-desktop.xml b/protocol/agl-shell-desktop.xml index 05a3725..9ef4cca 100644 --- a/protocol/agl-shell-desktop.xml +++ b/protocol/agl-shell-desktop.xml @@ -35,6 +35,8 @@ <enum name="app_role"> <entry name="popup" value="0"/> <entry name="fullscreen" value="1"/> + <entry name="split_vertical" value="2"/> + <entry name="split_horizontal" value="3"/> </enum> <enum name="app_state"> diff --git a/src/desktop.c b/src/desktop.c index 07680b9..2ef6fee 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -93,10 +93,7 @@ desktop_surface_added(struct weston_desktop_surface *dsurface, void *userdata) weston_desktop_surface_set_user_data(dsurface, surface); if (ivi->shell_client.ready) { - if (ivi_check_pending_desktop_surface_popup(surface)) - ivi_set_desktop_surface_popup(surface); - else - ivi_set_desktop_surface(surface); + ivi_check_pending_desktop_surface(surface); } else { /* * We delay creating "normal" desktop surfaces until later, to diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index 91b5340..3c547aa 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -89,6 +89,8 @@ struct ivi_compositor { struct wl_list pending_surfaces; struct wl_list popup_pending_apps; + struct wl_list fullscreen_pending_apps; + struct wl_list split_pending_apps; struct weston_layer hidden; struct weston_layer background; @@ -143,6 +145,9 @@ enum ivi_surface_role { IVI_SURFACE_ROLE_BACKGROUND, IVI_SURFACE_ROLE_PANEL, IVI_SURFACE_ROLE_POPUP, + IVI_SURFACE_ROLE_FULLSCREEN, + IVI_SURFACE_ROLE_SPLIT_V, + IVI_SURFACE_ROLE_SPLIT_H, }; struct pending_popup { @@ -153,6 +158,19 @@ struct pending_popup { struct wl_list link; /** ivi_compositor::popup_pending_surfaces */ }; +struct pending_fullscreen { + struct ivi_output *ioutput; + char *app_id; + struct wl_list link; /** ivi_compositor::fullscreen_pending_apps */ +}; + +struct pending_split { + struct ivi_output *ioutput; + char *app_id; + uint32_t orientation; + struct wl_list link; /** ivi_compositor::split_pending_apps */ +}; + struct ivi_desktop_surface { struct ivi_output *pending_output; struct ivi_output *last_output; @@ -168,6 +186,15 @@ struct ivi_popup_surface { int y; }; +struct ivi_fullscreen_surface { + struct ivi_output *output; +}; + +struct ivi_split_surface { + struct ivi_output *output; + uint32_t orientation; +}; + struct ivi_panel_surface { struct ivi_output *output; enum agl_shell_edge edge; @@ -199,6 +226,8 @@ struct ivi_surface { struct ivi_background_surface bg; struct ivi_panel_surface panel; struct ivi_popup_surface popup; + struct ivi_fullscreen_surface fullscreen; + struct ivi_split_surface split; }; }; @@ -253,11 +282,8 @@ ivi_set_desktop_surface(struct ivi_surface *surface); /* * removes the pending popup one */ -bool -ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface); - void -ivi_set_desktop_surface_popup(struct ivi_surface *surface); +ivi_check_pending_desktop_surface(struct ivi_surface *surface); void ivi_reflow_outputs(struct ivi_compositor *ivi); @@ -1173,6 +1173,8 @@ int main(int argc, char *argv[]) wl_list_init(&ivi.surfaces); wl_list_init(&ivi.pending_surfaces); wl_list_init(&ivi.popup_pending_apps); + wl_list_init(&ivi.fullscreen_pending_apps); + wl_list_init(&ivi.split_pending_apps); wl_list_init(&ivi.desktop_clients); /* Prevent any clients we spawn getting our stdin */ diff --git a/src/shell.c b/src/shell.c index 527cdba..c132ae5 100644 --- a/src/shell.c +++ b/src/shell.c @@ -66,7 +66,7 @@ ivi_set_desktop_surface(struct ivi_surface *surface) } } -void +static void ivi_set_desktop_surface_popup(struct ivi_surface *surface) { struct ivi_compositor *ivi = surface->ivi; @@ -77,6 +77,30 @@ ivi_set_desktop_surface_popup(struct ivi_surface *surface) } static void +ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_NONE); + + surface->role = IVI_SURFACE_ROLE_FULLSCREEN; + wl_list_insert(&ivi->surfaces, &surface->link); +} + +static void +ivi_set_desktop_surface_split(struct ivi_surface *surface) +{ + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_NONE); + + if (surface->split.orientation == AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL) + surface->role = IVI_SURFACE_ROLE_SPLIT_V; + else + surface->role = IVI_SURFACE_ROLE_SPLIT_H; + + wl_list_insert(&ivi->surfaces, &surface->link); +} + +static void ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, int x, int y, const char *app_id) { @@ -95,6 +119,61 @@ ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, } static void +ivi_set_pending_desktop_surface_fullscreen(struct ivi_output *ioutput, + const char *app_id) +{ + struct ivi_compositor *ivi = ioutput->ivi; + size_t len_app_id = strlen(app_id); + + struct pending_fullscreen *fs = zalloc(sizeof(*fs)); + + fs->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + memcpy(fs->app_id, app_id, len_app_id); + + fs->ioutput = ioutput; + + wl_list_insert(&ivi->fullscreen_pending_apps, &fs->link); +} + +static void +ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput, + const char *app_id, uint32_t orientation) +{ + struct ivi_compositor *ivi = ioutput->ivi; + size_t len_app_id = strlen(app_id); + + if (orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL && + orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL) + return; + + struct pending_split *split = zalloc(sizeof(*split)); + + split->app_id = zalloc(sizeof(char) * (len_app_id + 1)); + memcpy(split->app_id, app_id, len_app_id); + + split->ioutput = ioutput; + split->orientation = orientation; + + wl_list_insert(&ivi->split_pending_apps, &split->link); +} + +static void +ivi_remove_pending_desktop_surface_split(struct pending_split *split) +{ + free(split->app_id); + wl_list_remove(&split->link); + free(split); +} + +static void +ivi_remove_pending_desktop_surface_fullscreen(struct pending_fullscreen *fs) +{ + free(fs->app_id); + wl_list_remove(&fs->link); + free(fs); +} + +static void ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup) { free(p_popup->app_id); @@ -102,7 +181,7 @@ ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup) free(p_popup); } -bool +static bool ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) { struct ivi_compositor *ivi = surface->ivi; @@ -110,13 +189,15 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) const char *_app_id = weston_desktop_surface_get_app_id(surface->dsurface); + if (wl_list_empty(&ivi->popup_pending_apps)) + return false; + wl_list_for_each_safe(p_popup, next_p_popup, &ivi->popup_pending_apps, link) { if (!strcmp(_app_id, p_popup->app_id)) { surface->popup.output = p_popup->ioutput; surface->popup.x = p_popup->x; surface->popup.y = p_popup->y; - ivi_remove_pending_desktop_surface_popup(p_popup); return true; } @@ -125,6 +206,80 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) return false; } +static bool +ivi_check_pending_desktop_surface_split(struct ivi_surface *surface) +{ + struct pending_split *split_surf, *next_split_surf; + struct ivi_compositor *ivi = surface->ivi; + const char *_app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + + if (wl_list_empty(&ivi->split_pending_apps)) + return false; + + wl_list_for_each_safe(split_surf, next_split_surf, + &ivi->split_pending_apps, link) { + if (!strcmp(_app_id, split_surf->app_id)) { + surface->split.output = split_surf->ioutput; + surface->split.orientation = split_surf->orientation; + ivi_remove_pending_desktop_surface_split(split_surf); + return true; + } + } + + return false; +} + +static bool +ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface) +{ + struct pending_fullscreen *fs_surf, *next_fs_surf; + struct ivi_compositor *ivi = surface->ivi; + const char *_app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + + if (wl_list_empty(&ivi->fullscreen_pending_apps)) + return false; + + wl_list_for_each_safe(fs_surf, next_fs_surf, + &ivi->fullscreen_pending_apps, link) { + if (!strcmp(_app_id, fs_surf->app_id)) { + surface->fullscreen.output = fs_surf->ioutput; + ivi_remove_pending_desktop_surface_fullscreen(fs_surf); + return true; + } + } + + return false; +} + +void +ivi_check_pending_desktop_surface(struct ivi_surface *surface) +{ + bool ret = false; + + ret = ivi_check_pending_desktop_surface_popup(surface); + if (ret) { + ivi_set_desktop_surface_popup(surface); + return; + } + + ret = ivi_check_pending_desktop_surface_split(surface); + if (ret) { + ivi_set_desktop_surface_split(surface); + return; + } + + ret = ivi_check_pending_desktop_surface_fullscreen(surface); + if (ret) { + ivi_set_desktop_surface_fullscreen(surface); + return; + } + + /* if we end up here means we have a regular desktop app */ + ivi_set_desktop_surface(surface); +} + void ivi_shell_init_black_fs(struct ivi_compositor *ivi) { @@ -597,9 +752,20 @@ shell_desktop_set_app_property(struct wl_client *client, struct weston_output *woutput = weston_head_get_output(head); struct ivi_output *output = to_ivi_output(woutput); - /* temporary store the app_id such that, when created to be check against */ - if (role == AGL_SHELL_DESKTOP_APP_ROLE_POPUP) + switch (role) { + case AGL_SHELL_DESKTOP_APP_ROLE_POPUP: ivi_set_pending_desktop_surface_popup(output, x, y, app_id); + break; + case AGL_SHELL_DESKTOP_APP_ROLE_FULLSCREEN: + ivi_set_pending_desktop_surface_fullscreen(output, app_id); + break; + case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL: + case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL: + ivi_set_pending_desktop_surface_split(output, app_id, role); + break; + default: + break; + } } static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = { |