#include "e.h"
#include "e_policy_wl.h"
+#include <wtz-screen-server-protocol.h>
/* E_Desk is a child object of E_Zone. A desk is essentially a background
* and an associated set of client windows. Each zone can have an arbitrary
}
}
}
+
+static void
+_e_desk_splitscreen_region_cb_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_desk_splitscreen_region_cb_assign_appid(struct wl_client *client,
+ struct wl_resource *resource, const char *appid)
+{
+ E_Desk_Group *edg;
+
+ if (!(edg = wl_resource_get_user_data(resource))) return;
+
+ // TODO: copy the appid string to the E_Desk_Group....
+ // call the E_DESK_GROUP_HOOK_ASSIGN_APPID hook
+ if (!e_desk_group_hook_call(edg, E_DESK_GROUP_HOOK_SET_APPID))
+ {
+ ERR("e_desk_zoom_set: fail get eout");
+ return;
+ }
+}
+
+static const struct wtz_splitscreen_region_interface
+ _e_desk_splitscreen_region_interface =
+{
+ _e_desk_splitscreen_region_cb_destroy,
+ _e_desk_splitscreen_region_cb_assign_appid,
+};
+
+static void
+_e_desk_splitscreen_region_cb_resource_destroy(struct wl_resource *resource)
+{
+ E_Desk *desk;
+ E_Desk_Group *edg;
+
+ if (!(edg = wl_resource_get_user_data(resource))) return;
+ if (!edg->desk) return;
+
+ desk = edg->desk;
+
+ desk->ss_region_resources =
+ eina_list_remove(desk->ss_region_resources, resource);
+}
+
+EINTERN Eina_Bool
+e_desk_splitscreen_regions_all_generate(E_Desk *desk, struct wl_client *client,
+ struct wl_resource *ss_res, uint32_t id)
+{
+ E_Desk_Group *edg;
+ struct wl_resource *ss_region_res;
+ Eina_List *l;
+ int i;
+
+ E_OBJECT_CHECK_RETURN(desk, EINA_FALSE);
+ E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, EINA_FALSE);
+
+ for (i = (E_DESK_GROUP_LAYER_COUNT - 1); i >= 0; i--)
+ {
+ EINA_LIST_FOREACH(desk->desk_group.list[i], l, edg)
+ {
+ ss_region_res = wl_resource_create(client,
+ &wtz_splitscreen_region_interface, 1, id);
+ if (!ss_region_res)
+ {
+ wl_resource_post_no_memory(ss_res);
+ return EINA_FALSE;
+ }
+
+ wl_resource_set_implementation(ss_region_res,
+ &_e_desk_splitscreen_region_interface, edg,
+ _e_desk_splitscreen_region_cb_resource_destroy);
+
+ desk->ss_region_resources = eina_list_append(
+ desk->ss_region_resources, ss_region_res);
+
+ // send the splitscreen_region sresources
+ wtz_splitscreen_send_region(ss_res,
+ ss_region_res, edg->name,
+ edg->x, edg->y, edg->w, edg->h);
+ }
+ }
+
+ return EINA_TRUE;
+}
#include "e.h"
+#include <wayland-server.h>
+#include <wtz-screen-server-protocol.h>
+
/* E_Zone is a child object of E_Comp. There is one zone per screen
* in a xinerama setup. Each zone has one or more desktops.
*/
static Eina_Inlist *_e_zone_hooks[] =
{
[E_ZONE_HOOK_DISPLAY_STATE_CHANGE] = NULL,
+ [E_ZONE_HOOK_SPLISCREEN_ACTIVATE] = NULL,
+ [E_ZONE_HOOK_SPLISCREEN_DEACTIVATE] = NULL,
};
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_DEL, ev, _e_zone_event_generic_free, NULL);
+
+ if (zone->global)
+ wl_global_destroy(zone->global);
}
static E_Zone_Edge
else
_e_zone_hooks_delete++;
}
+
+static void
+_e_zone_screen_capability_add(struct wl_resource *resource,
+ struct wl_array *capabilities, uint32_t cap)
+{
+ uint32_t *c;
+
+ c = wl_array_add(capabilities, sizeof(*c));
+ if (c)
+ *c = cap;
+ else
+ wl_resource_post_no_memory(resource);
+}
+
+static void
+_e_zone_splitscreen_cb_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_zone_splitscreen_cb_activate(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ E_Zone *zone;
+
+ if (!(zone = wl_resource_get_user_data(resource))) return;
+
+ // call the hook for activating the splitscreen in this zone
+ _e_zone_hook_call(E_ZONE_HOOK_SPLISCREEN_ACTIVATE, zone);
+}
+
+static void
+_e_zone_splitscreen_cb_deactivate(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ E_Zone *zone;
+
+ if (!(zone = wl_resource_get_user_data(resource))) return;
+
+ // call the hook for deactivating the splitscreen in this zone
+ _e_zone_hook_call(E_ZONE_HOOK_SPLISCREEN_DEACTIVATE, zone);
+}
+
+static const struct wtz_splitscreen_interface _e_zone_splitscreen_interface =
+{
+ _e_zone_splitscreen_cb_destroy,
+ _e_zone_splitscreen_cb_activate,
+ _e_zone_splitscreen_cb_deactivate,
+};
+
+static void
+_e_zone_splitscreen_cb_resource_destroy(struct wl_resource *resource)
+{
+ // TODO:
+}
+
+static void
+_e_zone_screen_cb_destroy(struct wl_client *client EINA_UNUSED,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_zone_screen_cb_get_splitscreen(struct wl_client *client,
+ struct wl_resource *resource, uint32_t id)
+{
+ E_Zone *zone;
+ E_Desk *desk;
+ struct wl_resource *ss_res;
+
+ if (!(zone = wl_resource_get_user_data(resource))) return;
+
+ if (!zone->splitscreen_enabled)
+ {
+ ELOGF("E_Zone", "Screen dose not support Splitscreen.", NULL);
+ wl_resource_post_error(resource, WTZ_SCREEN_ERROR_NOT_SUPPORTED,
+ "%d: wtz_screen@%d has no splitscreen capability",
+ id, wl_resource_get_id(resource));
+ return;
+ }
+
+ ss_res = wl_resource_create(client,
+ &wtz_splitscreen_interface, 1, id);
+ if (!ss_res)
+ {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ wl_resource_set_implementation(ss_res,
+ &_e_zone_splitscreen_interface, zone,
+ _e_zone_splitscreen_cb_resource_destroy);
+
+ // The splitscreen_regions are the e_desk_groups associated with this
+ // E_Zone(E_Desk) and these are already created by the e20 module with the
+ // specifc policy. So e20 sends the splitscreen_regions associated with each
+ // e_desk_group.
+ desk = e_desk_current_get(zone);
+ if (e_desk_splitscreen_regions_all_generate(desk, client, ss_res, id))
+ {
+ ELOGF("E_Zone", "e_desk_splitscreen_regions_all_generate() failed.",
+ NULL);
+ return;
+
+ }
+
+ ELOGF("E_Zone", "Create a splitscreen resource. zone_id:%d", NULL, zone->id);
+}
+
+static void
+_e_zone_screen_cb_set_client_side_decoration(struct wl_client *client,
+ struct wl_resource *resource, uint32_t enable)
+{
+ E_Zone *zone;
+
+ if (!(zone = wl_resource_get_user_data(resource))) return;
+
+ if (zone->csd_enabled != enable) zone->csd_enabled = enable;
+
+ // TODO: The currunt ecs(wtz_surface) in this zone(wtz_screen) can support
+ // client-side decoration. Therefore, do something(?) for them to get
+ // the client-side decoration. - [soolim]
+
+}
+
+static const struct wtz_screen_interface _e_zone_screen_interface =
+{
+ _e_zone_screen_cb_destroy,
+ _e_zone_screen_cb_get_splitscreen,
+ _e_zone_screen_cb_set_client_side_decoration,
+};
+
+static void
+_e_zone_screen_cb_unbind(struct wl_resource *resource)
+{
+ E_Zone *zone;
+
+ if (!(zone = wl_resource_get_user_data(resource))) return;
+
+ zone->resources = eina_list_remove(zone->resources, resource);
+}
+
+static void
+_e_zone_screen_cb_bind(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id)
+{
+ E_Zone *zone;
+ struct wl_resource *resource;
+ struct wl_array capabilities;
+
+ if (!(zone = data)) return;
+
+ resource =
+ wl_resource_create(client, &wtz_screen_interface, version, id);
+ if (!resource)
+ {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ zone->resources = eina_list_append(zone->resources, resource);
+
+ wl_resource_set_implementation(resource, &_e_zone_screen_interface, zone,
+ _e_zone_screen_cb_unbind);
+ wl_resource_set_user_data(resource, zone);
+
+ // send the size of the screen
+ // [TODO] calculate the size with base output resolution.
+ wtz_screen_send_size(resource, zone->w, zone->h);
+
+ // send the name of the screen
+ wtz_screen_send_name(resource, zone->name);
+
+ // send the capabilities of the screen
+ wl_array_init(&capabilities);
+ if (zone->splitscreen_enabled)
+ _e_zone_screen_capability_add(resource, &capabilities,
+ WTZ_SCREEN_CAPABILITY_SPLITSCREEN);
+ if (zone->csd_enabled)
+ _e_zone_screen_capability_add(resource, &capabilities,
+ WTZ_SCREEN_CAPABILITY_CLIENT_SIDE_DECORATION);
+ wtz_screen_send_capabilities(resource, &capabilities);
+
+ ELOGF("E_Zone", "Bound wtz_screen zone->id: %d Size: %dx%d", NULL,
+ zone->id, zone->w, zone->h);
+}
+
+EINTERN E_Zone *
+e_zone_screen_new(int num, int w, int h)
+{
+ E_Zone *zone;
+
+ zone = e_zone_new(num, num, 0, 0, w, h);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+
+ zone->global =
+ wl_global_create(e_comp_wl->wl.disp, &wtz_screen_interface,
+ 1, zone, _e_zone_screen_cb_bind);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(zone->global, NULL);
+
+ return zone;
+}
+
+E_API Eina_Bool
+e_zone_screen_splitscreen_enable(E_Zone *zone)
+{
+ E_OBJECT_CHECK_RETURN(zone, EINA_FALSE);
+ E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, EINA_FALSE);
+
+ if (zone->splitscreen_enabled)
+ {
+ ELOGF("E_Zone", "Splitscreen is already enabled. zone_id:%d", NULL,
+ zone->id);
+ return EINA_TRUE;
+ }
+
+ zone->splitscreen_enabled = EINA_TRUE;
+
+ return EINA_TRUE;
+}