AC_SUBST(TELEPHONY_CFLAGS)
AC_SUBST(TELEPHONY_LIBS)
+# Check if system-controller (plugin) support should be enabled.
+AC_ARG_ENABLE(system-controller,
+ [ --enable-system-controller enable system-controller support],
+ [enable_systemctl=$enableval], [enable_systemctl=auto])
+
+if test "$enable_systemctl" != "no"; then
+ if test "$enable_systemctl" = "auto"; then
+ enable_systemctl="$enable_websockets"
+ else
+ if test "$enable_websockets" != "yes"; then
+ AC_MSG_ERROR([System controller requires websocket support.])
+ fi
+ fi
+else
+ AC_MSG_NOTICE([System controller support is disabled.])
+fi
+
+if test "$enable_systemctl" = "yes"; then
+ AC_MSG_NOTICE([System-controller support is enabled.])
+ AC_DEFINE([SYSTEMCTL_ENABLED], 1, [Enable system-controller support ?])
+ PKG_CHECK_MODULES(WAYLAND_CLIENT, wayland-client)
+else
+ AC_MSG_NOTICE([System-controller support is disabled.])
+fi
+
+AM_CONDITIONAL(SYSTEMCTL_ENABLED, [test "$enable_systemctl" = "yes"])
+AC_SUBST(SYSTEMCTL_ENABLED)
+AC_SUBST(WAYLAND_CLIENT_CFLAGS)
+AC_SUBST(WAYLAND_CLIENT_LIBS)
+
# Check if dlog support was enabled.
AC_ARG_ENABLE(dlog,
[ --enable-dlog enable dlog support],
AM_CONDITIONAL(RESOURCE_ASM_ENABLED, [test "$enable_resource_asm" = "yes"])
AC_SUBST(RESOURCE_ASM_ENABLED)
+PKG_CHECK_MODULES(AIL, ail, [have_ail=yes], [have_ail=no])
+if test "$have_ail" = "no" ; then
+ AC_MSG_ERROR([AIL development headers not found.])
+fi
+AC_SUBST(AIL_CFLAGS)
+AC_SUBST(AIL_LIBS)
+
+enable_ail="$have_ail"
+
+
# Set up murphy CFLAGS and LIBS.
MURPHY_CFLAGS=""
MURPHY_LIBS=""
echo "Websockets support: $enable_websockets"
echo "systemd support: $enable_systemd"
echo "Telephony support: $enable_telephony"
+echo "System controller support: $enable_systemctl"
+echo "AIL support: $enable_ail"
echo "Plugins:"
echo " - linked-in:"
for plugin in ${INTERNAL_PLUGINS:-none}; do
# system-controller
if SYSTEMCTL_ENABLED
-SYSTEMCTL_PLUGIN_SOURCES = plugins/system-controller/plugin-system-controller.c
-SYSTEMCTL_PLUGIN_CFLAGS = $(WEBSOCKETS_CFLAGS)
-SYSTEMCTL_PLUGIN_LIBS =
+SYSTEMCTL_DIR = plugins/system-controller
+SYSTEMCTL_PLUGIN_SOURCES = \
+ $(SYSTEMCTL_DIR)/plugin-system-controller.c \
+ $(SYSTEMCTL_DIR)/resource-manager/resource-manager.c \
+ $(SYSTEMCTL_DIR)/resource-manager/scripting-resource-manager.c \
+ $(SYSTEMCTL_DIR)/application/application.c \
+ $(SYSTEMCTL_DIR)/application/scripting-application.c \
+ $(SYSTEMCTL_DIR)/wayland/wayland.c \
+ $(SYSTEMCTL_DIR)/wayland/output.c \
+ $(SYSTEMCTL_DIR)/wayland/layer.c \
+ $(SYSTEMCTL_DIR)/wayland/area.c \
+ $(SYSTEMCTL_DIR)/wayland/window.c \
+ $(SYSTEMCTL_DIR)/wayland/animation.c \
+ $(SYSTEMCTL_DIR)/wayland/ico-window-manager.c \
+ $(SYSTEMCTL_DIR)/wayland/ico-input-manager.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-wayland.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-window-manager.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-animation.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-window.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-output.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-area.c \
+ $(SYSTEMCTL_DIR)/wayland/scripting-layer.c
+
+SYSTEMCTL_PLUGIN_CFLAGS = \
+ $(WEBSOCKETS_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) \
+ -Iico-uxf-weston-plugin \
+ -I$(top_builddir)/src/$(SYSTEMCTL_DIR)
+SYSTEMCTL_PLUGIN_LIBS = \
+ $(WEBSOCKET_LIBS) $(WAYLAND_CLIENT_LIBS) \
+ -lico-uxf-weston-plugin
if !DISABLED_PLUGIN_SYSTEMCTL
if BUILTIN_PLUGIN_SYSTEMCTL
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+ /* this includes application.h */
+#include "scripting-application.h"
+#include "wayland/area.h"
+
+static void init_applications(void);
+static mrp_wayland_area_t *area_find(const char *);
+
+mrp_htbl_t *applications;
+
+mrp_application_t *mrp_application_create(mrp_application_update_t *u,
+ void *scripting_data)
+{
+#define IF_PRESENT(u,n) (u->mask & MRP_WAYLAND_APP_ ## n ## _MASK)
+
+ mrp_application_update_mask_t mask;
+ mrp_application_t *app;
+ mrp_wayland_area_t *area;
+ mrp_wayland_t *wl;
+ char buf[4096];
+ void *it;
+
+ MRP_ASSERT(u && (u->mask & MRP_APPLICATION_APPID_MASK) && u->appid &&
+ (u->mask & MRP_APPLICATION_AREA_NAME_MASK) && u->area_name,
+ "invalid argument");
+
+ mask = u->mask;
+
+ if (!(app = mrp_allocz(sizeof(mrp_application_t)))) {
+ mrp_log_error("failed to create application '%s': out of memory",
+ u->appid);
+ return NULL;
+ }
+
+ app->appid = mrp_strdup(u->appid);
+
+ if (!applications) {
+ init_applications();
+ MRP_ASSERT(applications, "failed to initialize "
+ "hash table for applications");
+ }
+
+ if (!mrp_htbl_insert(applications, app->appid, app)) {
+ mrp_log_error("failed to create application '%s': "
+ "already exists", app->appid);
+ mrp_free(app);
+ return NULL;
+ }
+
+ app->area_name = mrp_strdup(u->area_name);
+
+ if ((area = area_find(app->area_name))) {
+ mask |= MRP_APPLICATION_AREA_MASK;
+ app->area = area;
+ }
+
+ if ((mask & MRP_APPLICATION_SCREEN_PRIVILEGE_MASK))
+ app->privileges.screen = u->privileges.screen;
+ if ((mask & MRP_APPLICATION_AUDIO_PRIVILEGE_MASK))
+ app->privileges.audio = u->privileges.audio;
+
+ if (!scripting_data)
+ scripting_data = mrp_application_scripting_app_create_from_c(app);
+
+ app->scripting_data = scripting_data;
+
+ mrp_application_print(app, mask, buf,sizeof(buf));
+ mrp_debug("application '%s' created%s", app->appid, buf);
+
+ if (app->scripting_data) {
+ mrp_wayland_foreach(wl, it) {
+ if (wl->application_update_callback) {
+ wl->application_update_callback(wl, MRP_APPLICATION_CREATE,
+ mask, app);
+ }
+ }
+ }
+
+ return app;
+
+#undef IF_PRESENT
+}
+
+void mrp_application_destroy(mrp_application_t *app)
+{
+ mrp_wayland_t *wl;
+ void *it;
+
+ if (app && app->appid) {
+ mrp_debug("destroying application '%s'", app->appid);
+
+ mrp_wayland_foreach(wl, it) {
+ if (wl->application_update_callback) {
+ wl->application_update_callback(wl, MRP_APPLICATION_DESTROY,
+ 0, app);
+ }
+ }
+
+ mrp_application_scripting_app_destroy_from_c(app);
+
+ if ((void *)app != mrp_htbl_remove(applications, app->appid, false)) {
+ mrp_log_error("failed to destroy application '%s': confused with "
+ "data structures", app->appid);
+ return;
+ }
+
+ mrp_free(app->appid);
+
+ free(app);
+ }
+}
+
+
+mrp_application_t *mrp_application_find(const char *appid)
+{
+ if (!appid)
+ return NULL;
+
+ return (mrp_application_t *)mrp_htbl_lookup(applications, (void *)appid);
+}
+
+
+size_t mrp_application_print(mrp_application_t *app,
+ mrp_application_update_mask_t mask,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ do{ if (p < e) { p += snprintf(p,e-p, "\n " fmt, ## args); } }while(0)
+
+ mrp_wayland_area_t *area;
+ char *p, *e;
+
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_APPLICATION_AREA_NAME_MASK))
+ PRINT("area_name: '%s'", app->area_name);
+ if ((mask & MRP_APPLICATION_AREA_MASK)) {
+ if (!(area = app->area))
+ PRINT("area: -1 - <unknown>");
+ else
+ PRINT("area: %d - '%s'", area->areaid, area->name);
+ }
+ if ((mask & MRP_APPLICATION_PRIVILEGES_MASK)) {
+ PRINT("privileges: screen=%s audio=%s",
+ mrp_application_privilege_str(app->privileges.screen),
+ mrp_application_privilege_str(app->privileges.audio));
+ }
+
+ return p - buf;
+
+#undef PRINT
+}
+
+
+void mrp_application_set_scripting_data(mrp_application_t *app, void *data)
+{
+ MRP_ASSERT(app, "Invalid Argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ app->scripting_data = data;
+}
+
+int mrp_application_foreach(mrp_htbl_iter_cb_t cb, void *user_data)
+{
+ return mrp_htbl_foreach(applications, cb, user_data);
+}
+
+
+
+const char *mrp_application_privilege_str(mrp_application_privilege_t priv)
+{
+ switch (priv) {
+ case MRP_APPLICATION_PRIVILEGE_NONE: return "none";
+ case MRP_APPLICATION_PRIVILEGE_CERTIFIED: return "certified";
+ case MRP_APPLICATION_PRIVILEGE_MANUFACTURER: return "manufacturer";
+ case MRP_APPLICATION_PRIVILEGE_SYSTEM: return "system";
+ case MRP_APPLICATION_PRIVILEGE_UNLIMITED: return "unlimited";
+ default: return "<unknown>";
+ }
+}
+
+
+static void init_applications(void)
+{
+ mrp_htbl_config_t cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.nentry = MRP_APPLICATION_MAX;
+ cfg.comp = mrp_string_comp;
+ cfg.hash = mrp_string_hash;
+ cfg.nbucket = MRP_APPLICATION_BUCKETS;
+
+ applications = mrp_htbl_create(&cfg);
+}
+
+static mrp_wayland_area_t *area_find(const char *fullname)
+{
+ mrp_wayland_t *wl;
+ mrp_wayland_area_t *area;
+ void *it;
+
+ mrp_wayland_foreach(wl, it) {
+ if ((area = mrp_wayland_area_find(wl, fullname)))
+ return area;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_APPLICATION_H__
+#define __MURPHY_APPLICATION_H__
+
+#include <sys/types.h>
+
+#include "data-types.h"
+
+#ifndef __MURPHY_WAYLAND_H__
+#error "do not include directly application.h; include wayland/wayland.h"
+#endif
+
+#define MRP_APPLICATION_MAX 500
+#define MRP_APPLICATION_BUCKETS (MRP_APPLICATION_MAX / 10)
+
+typedef enum mrp_application_operation_e mrp_application_operation_t;
+typedef enum mrp_application_privilege_e mrp_application_privilege_t;
+typedef enum mrp_application_update_mask_e mrp_application_update_mask_t;
+
+typedef struct mrp_application_s mrp_application_t;
+typedef struct mrp_application_update_s mrp_application_update_t;
+typedef struct mrp_application_privileges_s mrp_application_privileges_t;
+
+enum mrp_application_operation_e {
+ MRP_APPLICATION_OPERATION_NONE = 0,
+ MRP_APPLICATION_CREATE,
+ MRP_APPLICATION_DESTROY,
+};
+
+enum mrp_application_privilege_e {
+ MRP_APPLICATION_PRIVILEGE_NONE = 0,
+ MRP_APPLICATION_PRIVILEGE_CERTIFIED, /* 1 */
+ MRP_APPLICATION_PRIVILEGE_MANUFACTURER, /* 2 */
+ MRP_APPLICATION_PRIVILEGE_SYSTEM, /* 3 */
+ MRP_APPLICATION_PRIVILEGE_UNLIMITED, /* 4 */
+
+ MRP_APPLICATION_PRIVILEGE_MAX /* 5 */
+};
+
+struct mrp_application_privileges_s {
+ mrp_application_privilege_t screen;
+ mrp_application_privilege_t audio;
+};
+
+struct mrp_application_s {
+ char *appid;
+ char *area_name;
+
+ mrp_wayland_area_t *area;
+ mrp_application_privileges_t privileges;
+
+ void *scripting_data;
+};
+
+enum mrp_application_update_mask_e {
+ MRP_APPLICATION_APPID_MASK = 0x01,
+ MRP_APPLICATION_AREA_NAME_MASK = 0x02,
+ MRP_APPLICATION_AREA_MASK = 0x04,
+ MRP_APPLICATION_SCREEN_PRIVILEGE_MASK = 0x08,
+ MRP_APPLICATION_AUDIO_PRIVILEGE_MASK = 0x10,
+ MRP_APPLICATION_PRIVILEGES_MASK = 0x18,
+
+ MRP_APPLICATION_END_MASK = 0x20
+};
+
+struct mrp_application_update_s {
+ mrp_application_update_mask_t mask;
+ const char *appid;
+ const char *area_name;
+ mrp_application_privileges_t privileges;
+};
+
+mrp_application_t *mrp_application_create(mrp_application_update_t *u,
+ void *scripting_data);
+void mrp_application_destroy(mrp_application_t *app);
+
+mrp_application_t *mrp_application_find(const char *appid);
+
+size_t mrp_application_print(mrp_application_t *app,
+ mrp_application_update_mask_t mask,
+ char *buf, size_t len);
+
+void mrp_application_set_scripting_data(mrp_application_t *app, void *data);
+
+int mrp_application_foreach(mrp_htbl_iter_cb_t cb, void *user_data);
+
+const char *mrp_application_privilege_str(mrp_application_privilege_t priv);
+
+#endif /* __MURPHY_APPLICATION_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "wayland/wayland.h"
+#include "wayland/area.h"
+
+/* TODO: this shoud actually go to some common scripting */
+char *mrp_wayland_scripting_canonical_name(const char *, char *, size_t);
+
+
+#define APPLICATION_CLASS MRP_LUA_CLASS_SIMPLE(application)
+
+typedef enum mrp_sysctl_scripting_field_e field_t;
+typedef struct scripting_app_s scripting_app_t;
+
+
+struct scripting_app_s {
+ mrp_application_t *app;
+ char *id;
+};
+
+
+
+static int app_create_from_lua(lua_State *);
+static int app_getfield(lua_State *);
+static int app_setfield(lua_State *);
+static int app_stringify(lua_State *);
+static void app_destroy_from_lua(void *);
+
+static scripting_app_t *app_check(lua_State *, int);
+
+static mrp_application_privileges_t *priv_check(lua_State *, int);
+static void priv_free(mrp_application_privileges_t *);
+static int priv_push(lua_State *L, mrp_application_privileges_t *);
+
+static field_t field_check(lua_State *, int, const char **);
+static field_t field_name_to_type(const char *, ssize_t);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ application, /* class name */
+ scripting_app_t, /* userdata type */
+ app_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (app_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (app_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (app_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (app_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (app_stringify)
+ )
+);
+
+
+void mrp_application_scripting_init(lua_State *L)
+{
+ mrp_lua_create_object_class(L, APPLICATION_CLASS);
+}
+
+mrp_application_t *mrp_application_scripting_app_check(lua_State *L, int idx)
+{
+ scripting_app_t *a;
+ mrp_application_t *app;
+
+ if ((a = app_check(L, idx)) && (app = a->app)) {
+ MRP_ASSERT(app->scripting_data == (void *)a,
+ "confused with data structures");
+ return app;
+ }
+
+ return NULL;
+}
+
+mrp_application_t *mrp_application_scripting_app_unwrap(void *void_a)
+{
+ scripting_app_t *a = (scripting_app_t *)void_a;
+
+ if (a && mrp_lua_get_object_classdef(a) == APPLICATION_CLASS)
+ return a->app;
+
+ return NULL;
+}
+
+
+void *mrp_application_scripting_app_create_from_c(mrp_application_t *app)
+{
+ lua_State *L;
+ scripting_app_t *a;
+
+ MRP_ASSERT(app, "invald argument");
+
+ if (app->scripting_data)
+ a = app->scripting_data;
+ else {
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting application '%s': LUA is "
+ "not initialized", app->appid);
+ return NULL;
+ }
+
+ a = (scripting_app_t *)mrp_lua_create_object(L, APPLICATION_CLASS,
+ app->appid, 0);
+ if (!a) {
+ mrp_log_error("can't create scripting application '%s': "
+ "LUA object creation failed", app->appid);
+ }
+ else {
+ a->app = app;
+ mrp_application_set_scripting_data(app, a);
+ lua_pop(L, 1);
+ }
+ }
+
+ return a;
+}
+
+
+void mrp_application_scripting_app_destroy_from_c(mrp_application_t *app)
+{
+ lua_State *L;
+ scripting_app_t *a;
+
+ MRP_ASSERT(app, "invalid argument");
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't destroy scripting application '%s': "
+ "LUA is not initialized", app->appid);
+ return;
+ }
+
+ if ((a = app->scripting_data)) {
+ mrp_debug("destroy scripting application '%s'", app->appid);
+
+ a->app = NULL;
+ mrp_application_set_scripting_data(app, NULL);
+
+ mrp_lua_destroy_object(L, a->id,0, a);
+ }
+}
+
+
+static int app_create_from_lua(lua_State *L)
+{
+ mrp_application_update_t u;
+ mrp_application_t *app;
+ scripting_app_t *a;
+ size_t fldnamlen;
+ const char *fldnam;
+ const char *appid = NULL;
+ const char *arnam = "default";
+ mrp_application_privileges_t *privs = NULL;
+ char *id;
+ char buf[4096];
+
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ switch (field_name_to_type(fldnam, fldnamlen)) {
+
+ case APPID: appid = luaL_checkstring(L, -1); break;
+ case AREA: arnam = luaL_checkstring(L, -1); break;
+ case PRIVILEGES: privs = priv_check(L, -1); break;
+ default: luaL_error(L, "bad field '%s'", fldnam); break;
+ }
+ }
+
+ if (!appid)
+ luaL_error(L, "'appid' field is missing");
+
+
+ id = mrp_wayland_scripting_canonical_name(appid, buf, sizeof(buf));
+ a = (scripting_app_t*)mrp_lua_create_object(L, APPLICATION_CLASS, id, 0);
+
+ if (!(a))
+ luaL_error(L, "can't create scripting application '%s'", appid);
+
+ u.mask = MRP_APPLICATION_APPID_MASK | MRP_APPLICATION_AREA_NAME_MASK ;
+ u.appid = appid;
+ u.area_name = arnam;
+
+ if (privs) {
+ u.mask |= MRP_APPLICATION_PRIVILEGES_MASK;
+ u.privileges.screen = privs->screen;
+ u.privileges.audio = privs->audio;
+ priv_free(privs);
+ }
+
+ if ((app = mrp_application_create(&u, a))) {
+ a->app = app;
+ a->id = mrp_strdup(id);
+ }
+ else {
+ lua_pop(L, 1);
+ mrp_lua_destroy_object(L, id,0, a);
+ lua_pushnil(L);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int app_getfield(lua_State *L)
+{
+ scripting_app_t *a;
+ mrp_application_t *app;
+ mrp_wayland_area_t *area;
+ const char *fldnam;
+ field_t fld;
+
+ MRP_LUA_ENTER;
+
+ a = app_check(L, 1);
+ fld = field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ if (!a || !(app = a->app))
+ lua_pushnil(L);
+ else {
+ area = app->area;
+
+ switch (fld) {
+ case APPID: lua_pushstring(L, app->appid ? app->appid:""); break;
+ case AREA: lua_pushstring(L, area ? area->fullname:""); break;
+ case PRIVILEGES: priv_push(L, &app->privileges); break;
+ default: lua_pushnil(L); break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int app_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ app_check(L, 1);
+ luaL_error(L, "application objects are read-only");
+
+ lua_pop(L, 2);
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int app_stringify(lua_State *L)
+{
+#define ALL_FIELDS (MRP_APPLICATION_END_MASK - 1)
+
+ scripting_app_t *a;
+ mrp_application_t *app;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ a = app_check(L, 1);
+
+ if (!(app = a->app))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "application '%s'", app->appid);
+ p += mrp_application_print(app, ALL_FIELDS, p, e-p);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+
+#undef ALL_FIELDS
+}
+
+static void app_destroy_from_lua(void *data)
+{
+ scripting_app_t *a = (scripting_app_t *)data;
+ mrp_application_t *app;
+
+ MRP_LUA_ENTER;
+
+ if (a && (app = a->app)) {
+ a->app = NULL;
+ mrp_application_set_scripting_data(app, NULL);
+ mrp_free(a->id);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_app_t *app_check(lua_State *L, int idx)
+{
+ return (scripting_app_t *)mrp_lua_check_object(L, APPLICATION_CLASS, idx);
+}
+
+
+static mrp_application_privileges_t *priv_check(lua_State *L, int idx)
+{
+ mrp_application_privileges_t *priv;
+ int *p, v;
+ int screen = -1;
+ int audio = -1;
+ int n;
+ size_t fldnamlen, privnamlen;
+ const char *fldnam, *privnam;
+
+ idx = mrp_lua_absidx(L, idx);
+
+ luaL_checktype(L, idx, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, idx, fldnam, fldnamlen) {
+ switch (field_name_to_type(fldnam, fldnamlen)) {
+
+ case SCREEN:
+ p = &screen;
+ goto get_privilege;
+
+ case AUDIO:
+ p = &audio;
+ goto get_privilege;
+
+ default:
+ luaL_error(L, "bad field '%s'", fldnam);
+ break;
+
+ get_privilege:
+ v = -1;
+ if (lua_isnumber(L, -1)) {
+ n = lua_tointeger(L, -1);
+ if (n >= 0 && n < MRP_APPLICATION_PRIVILEGE_MAX)
+ v = n;
+ }
+ else if ((privnam = lua_tolstring(L, -1, &privnamlen))) {
+ switch (privnamlen) {
+ case 4:
+ if (!strcmp(privnam, "none"))
+ v = MRP_APPLICATION_PRIVILEGE_NONE;
+ break;
+ case 6:
+ if (!strcmp(privnam, "system"))
+ v = MRP_APPLICATION_PRIVILEGE_SYSTEM;
+ break;
+ case 9:
+ if (!strcmp(privnam, "unlimited"))
+ v = MRP_APPLICATION_PRIVILEGE_UNLIMITED;
+ else if (!strcmp(privnam, "certified"))
+ v = MRP_APPLICATION_PRIVILEGE_CERTIFIED;
+ break;
+ case 12:
+ if (!strcmp(privnam, "manufacturer"))
+ v = MRP_APPLICATION_PRIVILEGE_MANUFACTURER;
+ break;
+ default:
+ break;
+ } /* switch privnamlen */
+ }
+ *p = v;
+ break;
+ } /* switch fldnam */
+ } /* FOREACH_FIELD */
+
+ if (screen < 0)
+ luaL_error(L, "missing or invalid 'screen' field");
+ if (audio < 0)
+ luaL_error(L, "missing or invalid 'audio' field");
+
+ if ((priv = mrp_allocz(sizeof(*priv)))) {
+ priv->screen = screen;
+ priv->audio = audio;
+ }
+
+ return priv;
+}
+
+static void priv_free(mrp_application_privileges_t *priv)
+{
+ mrp_free(priv);
+}
+
+static int priv_push(lua_State *L, mrp_application_privileges_t *privs)
+{
+ if (!privs)
+ lua_pushnil(L);
+ else {
+ lua_createtable(L, 0, 2);
+
+ lua_pushstring(L, "screen");
+ lua_pushstring(L, mrp_application_privilege_str(privs->screen));
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "audio");
+ lua_pushstring(L, mrp_application_privilege_str(privs->audio));
+ lua_settable(L, -3);
+ }
+
+ return 1;
+}
+
+static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
+{
+ const char *fldnam;
+ size_t fldnamlen;
+ field_t fldtyp;
+
+ if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
+ fldtyp = 0;
+ else
+ fldtyp = field_name_to_type(fldnam, fldnamlen);
+
+ if (ret_fldnam)
+ *ret_fldnam = fldnam;
+
+ return fldtyp;
+}
+
+static field_t field_name_to_type(const char *name, ssize_t len)
+{
+ if (len < 0)
+ len = strlen(name);
+
+ switch (len) {
+
+ case 4:
+ if (!strcmp(name, "area"))
+ return AREA;
+ break;
+
+ case 5:
+ if (!strcmp(name, "appid"))
+ return APPID;
+ if (!strcmp(name, "audio"))
+ return AUDIO;
+ break;
+
+ case 6:
+ if (!strcmp(name, "screen"))
+ return SCREEN;
+ break;
+
+ case 10:
+ if (!strcmp(name, "privileges"))
+ return PRIVILEGES;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_APPLICATION_SCRIPTING_H__
+#define __MURPHY_APPLICATION_SCRIPTING_H__
+
+#include <lua.h>
+
+#include <murphy/core/lua-bindings/lua-json.h>
+
+#include "wayland/wayland.h"
+
+void mrp_application_scripting_init(lua_State *L);
+
+
+mrp_application_t *mrp_application_scripting_app_check(lua_State *L, int idx);
+mrp_application_t *mrp_application_scripting_app_unwrap(void *void_a);
+void *mrp_application_scripting_app_create_from_c(mrp_application_t *app);
+void mrp_application_scripting_app_destroy_from_c(mrp_application_t *app);
+
+
+
+#endif /* __MURPHY_APPLICTION_SCRIPTING_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__
+#define __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__
+
+typedef enum mrp_sysctl_scripting_field_e mrp_sysctl_scripting_field_t;
+
+enum mrp_sysctl_scripting_field_e {
+ /* 2 */ ID = 1,
+ /* 3 */ PID, TOP,
+ /* 4 */ AREA, FLIP, HIDE, LEFT, MAKE, MASK, MOVE, NAME, NODE, SIZE, SHOW,
+ /* 5 */ ALIGN, APPID, AUDIO, INDEX, INPUT, LAYER, MODEL, POS_X, POS_Y,
+ RAISE, RIGHT, WIDTH,
+ /* 6 */ ACTIVE, BOTTOM, HEIGHT, LAYERS, MAPPED, MIDDLE, OUTPUT, RESIZE,
+ ROTATE, SCREEN,
+ /* 7 */ CLASSES, DISPLAY, PIXEL_X, PIXEL_Y, SURFACE, VISIBLE,
+ /* 8 */ POSITION, SUBPIXEL, VERTICAL,
+ /* 9 */ LAYERTYPE, SHAREABLE,
+ /* 10 */ ATTRIBUTES, HORIZONTAL, KEEPRATIO, PRIVILEGES,
+ /* 11 */ AREA_CREATE, PIXEL_WIDTH,
+ /* 12 */ PIXEL_HEIGHT, LAYER_UPDATE,
+ /* 13 */ LAYER_REQUEST, OUTPUT_UPDATE, WINDOW_UPDATE,
+ /* 14 */ OUTPUT_REQUEST, WINDOW_MANAGER, WINDOW_REQUEST,
+};
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__ */
#include "system-controller.h"
+#include "resource-manager/scripting-resource-manager.h"
+#include "application/scripting-application.h"
+#include "wayland/scripting-wayland.h"
+
+
#define DEFAULT_ADDRESS "wsck:127.0.0.1:18081/ico_syc_protocol"
if ((sc->L = mrp_lua_get_lua_state()) == NULL)
return FALSE;
+ mrp_resmgr_scripting_init(sc->L);
+ mrp_application_scripting_init(sc->L);
+ mrp_wayland_scripting_init(sc->L);
+
mrp_lua_create_object_class(sc->L, SYSCTL_LUA_CLASS);
return mrp_lua_register_murphy_bindings(&bindings);
if (sc != NULL) {
mrp_list_init(&sc->clients);
- sc->id = 1;
- sc->ctx = plugin->ctx;
- sc->addr = plugin->args[ARG_ADDRESS].str;
+ sc->id = 1;
+ sc->ctx = plugin->ctx;
+ sc->addr = plugin->args[ARG_ADDRESS].str;
if (!transport_create(sc))
goto fail;
#define PLUGIN_VERSION MRP_VERSION_INT(0, 0, 1)
static mrp_plugin_arg_t plugin_args[] = {
- MRP_PLUGIN_ARGIDX(ARG_ADDRESS, STRING, "address", DEFAULT_ADDRESS)
+ MRP_PLUGIN_ARGIDX(ARG_ADDRESS, STRING, "address", DEFAULT_ADDRESS),
};
MURPHY_REGISTER_PLUGIN("system-controller",
--- /dev/null
+/*
+ * Copyright (c) 2012, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/common/debug.h>
+#include <murphy/core/plugin.h>
+#include <murphy/core/console.h>
+#include <murphy/core/event.h>
+#include <murphy/core/context.h>
+
+
+#include <murphy/resource/config-api.h>
+#include <murphy/resource/manager-api.h>
+#include <murphy/resource/client-api.h>
+#include <murphy/resource/protocol.h>
+
+#include "resource-manager.h"
+
+static int hash_compare(const void *, const void *);
+static uint32_t hash_function(const void *);
+
+mrp_resmgr_t *mrp_resmgr_create(void)
+{
+ mrp_resmgr_t *resmgr;
+ mrp_htbl_config_t cfg;
+
+ if (!(resmgr = mrp_allocz(sizeof(mrp_resmgr_t)))) {
+ mrp_log_error("system-controller: failed to allocate private data "
+ "resource manager");
+ return NULL;
+ }
+
+ cfg.nentry = MRP_RESMGR_RESOURCE_MAX;
+ cfg.comp = hash_compare;
+ cfg.hash = hash_function;
+ cfg.free = NULL;
+ cfg.nbucket = MRP_RESMGR_RESOURCE_BUCKETS;
+
+ resmgr->resources = mrp_htbl_create(&cfg);
+
+ return resmgr;
+}
+
+void mrp_resmgr_insert_resource(mrp_resmgr_t *resmgr,
+ mrp_zone_t *zone,
+ mrp_resource_t *key,
+ void *resource)
+{
+ uint32_t zoneid;
+
+ MRP_ASSERT(resmgr && zone && key && resource, "invalid argument");
+ MRP_ASSERT(resmgr->resources, "uninitialised data structure");
+
+ zoneid = mrp_zone_get_id(zone);
+
+ resmgr->zones |= ((mrp_zone_mask_t)1 << zoneid);
+
+ mrp_htbl_insert(resmgr->resources, key, resource);
+}
+
+void *mrp_resmgr_remove_resource(mrp_resmgr_t *resmgr,
+ mrp_zone_t *zone,
+ mrp_resource_t *key)
+{
+ MRP_ASSERT(resmgr && zone && key, "invalid argument");
+ MRP_ASSERT(resmgr->resources, "uninitialised data structure");
+
+ return mrp_htbl_remove(resmgr->resources, key, FALSE);
+}
+
+void *mrp_resmgr_lookup_resource(mrp_resmgr_t *resmgr, mrp_resource_t *key)
+{
+ MRP_ASSERT(resmgr && key, "invalid argument");
+ MRP_ASSERT(resmgr->resources, "uninitialised data structure");
+
+ return mrp_htbl_lookup(resmgr->resources, key);
+}
+
+static int hash_compare(const void *key1, const void *key2)
+{
+ if (key1 < key2)
+ return -1;
+ if (key1 > key2)
+ return 1;
+ return 0;
+}
+
+static uint32_t hash_function(const void *key)
+{
+ return (uint32_t)(((ptrdiff_t)key >> 4) & (ptrdiff_t)0xffffffff);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_H__
+#define __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_H__
+
+#include <sys/types.h>
+
+#include <murphy/common/hashtbl.h>
+
+#include <murphy/resource/data-types.h>
+
+#include "data-types.h"
+
+typedef enum mrp_sysctl_scripting_field_e mrp_resmgr_scripting_field_t;
+
+typedef struct mrp_resmgr_s mrp_resmgr_t;
+typedef struct mrp_resmgr_screen_s mrp_resmgr_screen_t;
+typedef struct mrp_resmgr_audio_s mrp_resmgr_audio_t;
+typedef struct mrp_resmgr_input_s mrp_resmgr_input_t;
+
+#define MRP_RESMGR_RESOURCE_MAX 256
+#define MRP_RESMGR_RESOURCE_BUCKETS (MRP_RESMGR_RESOURCE_MAX / 4)
+
+struct mrp_resmgr_s {
+ mrp_htbl_t *resources;
+ mrp_zone_mask_t zones;
+
+ mrp_resmgr_screen_t *screen;
+ mrp_resmgr_audio_t *audio;
+ mrp_resmgr_input_t *input;
+
+ void *scripting_data;
+};
+
+
+mrp_resmgr_t *mrp_resmgr_create(void);
+void mrp_resmgr_destroy(mrp_resmgr_t *resmgr);
+
+void mrp_resmgr_insert_resource(mrp_resmgr_t *resmgr, mrp_zone_t *zone,
+ mrp_resource_t *key, void *resource);
+void *mrp_resmgr_remove_resource(mrp_resmgr_t *resmgr, mrp_zone_t *zone,
+ mrp_resource_t *key);
+void *mrp_resmgr_lookup_resource(mrp_resmgr_t *resmgr, mrp_resource_t *key);
+
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-resource-manager.h"
+#include "wayland/scripting-wayland.h"
+
+#define RESOURCE_MANAGER_CLASS MRP_LUA_CLASS_SIMPLE(resource_manager)
+
+typedef struct scripting_resmgr_s scripting_resmgr_t;
+typedef struct funcbridge_def_s funcbridge_def_t;
+
+struct scripting_resmgr_s {
+ mrp_resmgr_t *resmgr;
+};
+
+struct funcbridge_def_s {
+ const char *name;
+ const char *sign;
+ mrp_funcbridge_cfunc_t func;
+ void *data;
+ mrp_funcbridge_t **ptr;
+};
+
+static int resmgr_create(lua_State *);
+static int resmgr_canonical_name(lua_State *);
+static int resmgr_getfield(lua_State *);
+static int resmgr_setfield(lua_State *);
+static void resmgr_destroy(void *);
+
+static scripting_resmgr_t *resmgr_check(lua_State *, int);
+
+static bool register_methods(lua_State *);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ resource_manager, /* class name */
+ scripting_resmgr_t, /* userdata type */
+ resmgr_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (resmgr_create)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (resmgr_create)
+ MRP_LUA_OVERRIDE_GETFIELD (resmgr_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (resmgr_setfield)
+ )
+);
+
+
+static mrp_funcbridge_t *area_create;
+
+
+void mrp_resmgr_scripting_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, RESOURCE_MANAGER_CLASS);
+ register_methods(L);
+}
+
+
+mrp_resmgr_t *mrp_resmgr_scripting_check(lua_State *L, int idx)
+{
+ scripting_resmgr_t *rm;
+ mrp_resmgr_t *resmgr;
+
+ if ((rm = resmgr_check(L, idx)) && (resmgr = rm->resmgr)) {
+ MRP_ASSERT(resmgr->scripting_data == (void *)rm,
+ "confused with data structures");
+ return resmgr;
+ }
+
+ return NULL;
+}
+
+mrp_resmgr_t *mrp_resmgr_scripting_unwrap(void *void_rm)
+{
+ scripting_resmgr_t *rm = (scripting_resmgr_t *)void_rm;
+
+ if (rm && mrp_lua_get_object_classdef(rm) == RESOURCE_MANAGER_CLASS)
+ return rm->resmgr;
+
+ return NULL;
+}
+
+static int resmgr_create(lua_State *L)
+{
+ mrp_resmgr_t *resmgr;
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_resmgr_t *rm;
+ int table;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ rm = (scripting_resmgr_t *)mrp_lua_create_object(L, RESOURCE_MANAGER_CLASS,
+ NULL, 1);
+
+ if (!rm)
+ luaL_error(L, "failed to create resource manager");
+
+ table = lua_gettop(L);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ switch (mrp_resmgr_scripting_field_name_to_type(fldnam, fldnamlen)) {
+
+ default:
+ lua_pushvalue(L, -2);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, table);
+ break;
+ }
+ }
+
+ if (!(resmgr = mrp_resmgr_create()))
+ luaL_error(L, "can't create resmgr object");
+
+ rm->resmgr = resmgr;
+
+ lua_settop(L, table);
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int resmgr_getfield(lua_State *L)
+{
+ scripting_resmgr_t *rm;
+ const char *fldnam;
+ mrp_resmgr_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_resmgr_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ rm = resmgr_check(L, 1);
+
+ if (!rm)
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+
+ case AREA_CREATE:
+ mrp_funcbridge_push(L, area_create);
+ break;
+
+ default:
+ lua_pushstring(L, fldnam);
+ lua_rawget(L, 1);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int resmgr_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ resmgr_check(L, 1);
+ luaL_error(L, "resource manager is read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static void resmgr_destroy(void *data)
+{
+ scripting_resmgr_t *rm = (scripting_resmgr_t *)data;
+
+ MRP_UNUSED(data);
+ MRP_UNUSED(rm);
+
+ MRP_LUA_ENTER;
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+static scripting_resmgr_t *resmgr_check(lua_State *L, int idx)
+{
+
+ return (scripting_resmgr_t*)mrp_lua_check_object(L, RESOURCE_MANAGER_CLASS,
+ idx);
+}
+
+
+static bool area_create_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+ mrp_wayland_area_t *area;
+ mrp_resmgr_t *resmgr;
+
+ MRP_UNUSED(L);
+ MRP_UNUSED(data);
+ MRP_UNUSED(ret_val);
+ MRP_ASSERT(signature && args && ret_type, "invalid argument");
+
+ *ret_type = MRP_FUNCBRIDGE_NO_DATA;
+
+ if (strcmp(signature, "oo")) {
+ mrp_log_error("bad signature: expected 'oo' got '%s'",signature);
+ return false;
+ }
+
+ if (!(resmgr = mrp_resmgr_scripting_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'resource_manager' class object");
+ return false;
+ }
+
+ if (!(area = mrp_wayland_scripting_area_unwrap(args[1].pointer))) {
+ mrp_log_error("argument 2 is not 'area' class object");
+ return false;
+ }
+
+
+ return true;
+}
+
+
+
+mrp_resmgr_scripting_field_t
+mrp_resmgr_scripting_field_check(lua_State *L,int idx,const char **ret_fldnam)
+{
+ const char *fldnam;
+ size_t fldnamlen;
+ mrp_resmgr_scripting_field_t fldtyp;
+
+ if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
+ fldtyp = 0;
+ else
+ fldtyp = mrp_resmgr_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (ret_fldnam)
+ *ret_fldnam = fldnam;
+
+ return fldtyp;
+}
+
+mrp_resmgr_scripting_field_t
+mrp_resmgr_scripting_field_name_to_type(const char *name, ssize_t len)
+{
+ if (len < 0)
+ len = strlen(name);
+
+ switch (len) {
+
+ case 4:
+ if (!strcmp(name, "name"))
+ return NAME;
+ break;
+
+ case 5:
+ switch (name[0]) {
+ case 'a':
+ if (!strcmp(name, "AUDIO"))
+ return AUDIO;
+ break;
+ case 'i':
+ if (!strcmp(name, "input"))
+ return INPUT;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 6:
+ if (!strcmp(name, "screen"))
+ return SCREEN;
+ break;
+
+ case 7:
+ if (!strcmp(name, "classes"))
+ return CLASSES;
+ break;
+
+ case 9:
+ if (!strcmp(name, "SHAREABLE"))
+ return SHAREABLE;
+ break;
+
+ case 10:
+ if (!strcmp(name, "attributes"))
+ return ATTRIBUTES;
+ break;
+
+ case 11:
+ if (!strcmp(name, "area_create"))
+ return AREA_CREATE;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static bool register_methods(lua_State *L)
+{
+#define FUNCBRIDGE(n,s,d) { #n, s, n##_bridge, d, &n }
+#define FUNCBRIDGE_END { NULL, NULL, NULL, NULL, NULL }
+
+ static funcbridge_def_t funcbridge_defs[] = {
+ FUNCBRIDGE(area_create , "oo" , NULL),
+ FUNCBRIDGE_END
+ };
+
+ mrp_funcbridge_t *f;
+ funcbridge_def_t *d;
+ bool success = true;
+
+ for (d = funcbridge_defs; d->name; d++) {
+ *(d->ptr) = f = mrp_funcbridge_create_cfunc(L, d->name, d->sign,
+ d->func, d->data);
+ if (!f) {
+ mrp_log_error("failed to register builtin function '%s'", d->name);
+ success = false;
+ }
+ }
+
+ return success;
+
+#undef FUNCBRIDGE_END
+#undef FUNCBRIDGE
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_SCRIPTING_H__
+#define __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_SCRIPTING_H__
+
+#include <lua.h>
+
+#include "resource-manager/resource-manager.h"
+
+void mrp_resmgr_scripting_init(lua_State *L);
+
+mrp_resmgr_t *mrp_resmgr_scripting_check(lua_State *L, int idx);
+mrp_resmgr_t *mrp_resmgr_scripting_unwrap(void *void_rm);
+
+
+mrp_resmgr_scripting_field_t
+mrp_resmgr_scripting_field_check(lua_State *, int, const char **);
+
+mrp_resmgr_scripting_field_t
+mrp_resmgr_scripting_field_name_to_type(const char *, ssize_t);
+
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_RESOURCE_MANAGER_SCRIPTING_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "animation.h"
+
+static const char *type_str(mrp_wayland_animation_type_t type);
+
+mrp_wayland_animation_t *mrp_wayland_animation_create(void)
+{
+ size_t size;
+ mrp_wayland_animation_t *anims;
+
+ size = sizeof(mrp_wayland_animation_t) * MRP_WAYLAND_ANIMATION_MAX;
+
+ if (!(anims = mrp_allocz(size)))
+ mrp_log_error("can't get memory for animation");
+
+ return anims;
+}
+
+void mrp_wayland_animation_destroy(mrp_wayland_animation_t *anims)
+{
+ int i;
+
+ if (anims) {
+ for (i = 0; i < MRP_WAYLAND_ANIMATION_MAX; i++)
+ mrp_free((void *)anims[i].name);
+ mrp_free(anims);
+ }
+}
+
+bool mrp_wayland_animation_set(mrp_wayland_animation_t *anims,
+ mrp_wayland_animation_type_t type,
+ const char *name,
+ int32_t time)
+{
+ mrp_wayland_animation_t *anim;
+
+ MRP_ASSERT(anims, "invalid argument");
+
+ if (type < 0 || type > MRP_WAYLAND_ANIMATION_MAX)
+ return false;
+
+ anim = anims + type;
+
+ mrp_free((void *)anim->name);
+
+ if (!name || !name[0] || time <= 0)
+ memset(anim, 0, sizeof(mrp_wayland_animation_t));
+ else {
+ anim->type = type;
+ anim->name = mrp_strdup(name);
+ anim->time = time;
+ }
+
+ return true;
+}
+
+size_t mrp_wayland_animation_print(mrp_wayland_animation_t *anims,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ mrp_wayland_animation_t *anim;
+ char *p, *e;
+ size_t i;
+ bool empty;
+
+ MRP_ASSERT(buf && len > 0, "invalid argument");
+
+ e = (p = buf) + len;
+ empty = true;
+
+ if (anims) {
+ for (i = 0; i < MRP_WAYLAND_ANIMATION_MAX; i++) {
+ anim = anims + i;
+
+ if (anim->name && anim->name[0]) {
+ PRINT("%s: '%s' %d", type_str(i), anim->name, anim->time);
+ empty = false;
+ }
+ }
+ }
+
+ if (empty)
+ PRINT("<none>");
+
+ return p - buf;
+
+#undef PRINT
+}
+
+static const char *type_str(mrp_wayland_animation_type_t type)
+{
+ const char *str;
+
+ switch (type) {
+ case MRP_WAYLAND_ANIMATION_HIDE: str = "hide"; break;
+ case MRP_WAYLAND_ANIMATION_SHOW: str = "show"; break;
+ case MRP_WAYLAND_ANIMATION_MOVE: str = "move"; break;
+ case MRP_WAYLAND_ANIMATION_RESIZE: str = "resize"; break;
+ default: str = "<not-supported>"; break;
+ }
+
+ return str;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_ANIMATION_H__
+#define __MURPHY_WAYLAND_ANIMATION_H__
+
+#include <sys/types.h>
+
+#include "wayland/wayland.h"
+
+
+enum mrp_wayland_animation_type_e {
+ MRP_WAYLAND_ANIMATION_HIDE = 0,
+ MRP_WAYLAND_ANIMATION_SHOW,
+ MRP_WAYLAND_ANIMATION_MOVE,
+ MRP_WAYLAND_ANIMATION_RESIZE,
+
+ MRP_WAYLAND_ANIMATION_MAX
+};
+
+struct mrp_wayland_animation_s {
+ mrp_wayland_animation_type_t type;
+ const char *name;
+ int32_t time;
+};
+
+mrp_wayland_animation_t *mrp_wayland_animation_create(void);
+void mrp_wayland_animation_destroy(mrp_wayland_animation_t *);
+
+bool mrp_wayland_animation_set(mrp_wayland_animation_t *anims,
+ mrp_wayland_animation_type_t type,
+ const char *name,
+ int32_t time);
+
+size_t mrp_wayland_animation_print(mrp_wayland_animation_t *anims,
+ char *buf, size_t len);
+
+
+#endif /* __MURPHY_WAYLAND_ANIMATION_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "area.h"
+#include "window-manager.h"
+#include "output.h"
+#include "scripting-wayland.h"
+
+
+static char *align_str(mrp_wayland_area_align_t, char *, size_t);
+
+static int set_area_for_applications(void *, void *, void *);
+
+
+
+mrp_wayland_area_t *mrp_wayland_area_create(mrp_wayland_t *wl,
+ mrp_wayland_area_update_t *u)
+{
+#define IF_PRESENT(u,n) (u->mask & MRP_WAYLAND_AREA_ ## n ## _MASK)
+
+ static mrp_wayland_area_align_t left_and_right =
+ MRP_WAYLAND_AREA_ALIGN_LEFT |
+ MRP_WAYLAND_AREA_ALIGN_RIGHT ;
+ static mrp_wayland_area_align_t top_and_bottom =
+ MRP_WAYLAND_AREA_ALIGN_LEFT |
+ MRP_WAYLAND_AREA_ALIGN_RIGHT ;
+
+
+ mrp_wayland_area_update_mask_t mask;
+ mrp_wayland_area_t *area;
+ char fullname[2048];
+ char buf[2048];
+
+ MRP_ASSERT(wl && u &&
+ (u->mask & MRP_WAYLAND_AREA_NAME_MASK) && u->name &&
+ (u->mask & MRP_WAYLAND_AREA_OUTPUT_MASK) &&
+ (u->mask & MRP_WAYLAND_AREA_WIDTH_MASK) &&
+ (u->mask & MRP_WAYLAND_AREA_HEIGHT_MASK),
+ "invalid argument");
+
+ if (!(area = mrp_allocz(sizeof(mrp_wayland_area_t)))) {
+ mrp_log_error("failed to create area %d: out of memory",
+ u->areaid);
+ return NULL;
+ }
+
+ snprintf(fullname, sizeof(fullname), "%s.%s",
+ u->output->outputname, u->name);
+
+ area->wl = wl;
+ area->wm = wl->wm;
+ area->name = mrp_strdup(u->name);
+ area->fullname = mrp_strdup(fullname);
+ area->output = u->output;
+ area->width = u->width;
+ area->height = u->height;
+
+ mask = u->mask | MRP_WAYLAND_AREA_FULLNAME_MASK;
+
+ area->areaid = IF_PRESENT(u, AREAID ) ? u->areaid : -1;
+ area->x = IF_PRESENT(u, X ) ? u->x : 0;
+ area->y = IF_PRESENT(u, Y ) ? u->y : 0;
+ area->keepratio = IF_PRESENT(u, KEEPRATIO) ? u->keepratio : false;
+ area->align = IF_PRESENT(u, ALIGN ) ? u->align : 0;
+
+ if ((area->align & MRP_WAYLAND_AREA_ALIGN_HMASK) == left_and_right)
+ area->align &= ~MRP_WAYLAND_AREA_ALIGN_HMASK; /* align middle */
+
+ if ((area->align & MRP_WAYLAND_AREA_ALIGN_VMASK) == top_and_bottom)
+ area->align &= ~MRP_WAYLAND_AREA_ALIGN_VMASK; /* align middle */
+
+ if (!mrp_htbl_insert(wl->areas, area->fullname, area)) {
+ mrp_log_error("failed to create area: already exists");
+ mrp_free(area->name);
+ mrp_free(area->fullname);
+ mrp_free(area);
+ return NULL;
+ }
+
+ if (wl->create_scripting_areas) {
+ area->scripting_data = mrp_wayland_scripting_area_create_from_c(NULL,
+ area);
+ }
+
+ mrp_wayland_area_print(area, mask, buf,sizeof(buf));
+ mrp_debug("area '%s' created%s", area->name, buf);
+
+ if (wl->area_update_callback)
+ wl->area_update_callback(wl, MRP_WAYLAND_AREA_CREATE, mask, area);
+
+ mrp_application_foreach(set_area_for_applications, area);
+
+ return area;
+
+#undef IF_PRESENT
+}
+
+void mrp_wayland_area_destroy(mrp_wayland_area_t *area)
+{
+ mrp_wayland_t *wl;
+ char buf[1024];
+
+ MRP_ASSERT(area && area->wl, "invalid argument");
+
+ wl = area->wl;
+
+ mrp_wayland_area_print(area, MRP_WAYLAND_AREA_AREAID_MASK,
+ buf, sizeof(buf));
+ mrp_debug("destroying area '%s'%s", area->name, buf);
+
+ if (wl->area_update_callback)
+ wl->area_update_callback(wl, MRP_WAYLAND_AREA_DESTROY, 0, area);
+
+ if ((void *)area != mrp_htbl_remove(wl->areas, area->name, false)) {
+ mrp_log_error("failed to destroy area '%s': confused with "
+ "data structures", area->name);
+ return;
+ }
+
+ mrp_free(area->name);
+
+ free(area);
+}
+
+
+mrp_wayland_area_t *mrp_wayland_area_find(mrp_wayland_t *wl,
+ const char *fullname)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ return (mrp_wayland_area_t*)mrp_htbl_lookup(wl->areas, (void *)fullname);
+}
+
+
+size_t mrp_wayland_area_print(mrp_wayland_area_t *area,
+ mrp_wayland_area_update_mask_t mask,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ mrp_wayland_output_t *out;
+ char *p, *e;
+ char as[256];
+
+ out = area->output;
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_AREA_AREAID_MASK))
+ PRINT("areaid: %d", area->areaid);
+ if ((mask & MRP_WAYLAND_AREA_NAME_MASK))
+ PRINT("name: '%s'", area->name);
+ if ((mask & MRP_WAYLAND_AREA_FULLNAME_MASK))
+ PRINT("fullname: '%s'", area->fullname);
+ if ((mask & MRP_WAYLAND_AREA_OUTPUT_MASK))
+ PRINT("output: '%s'", out ? out->outputname : "<not set>");
+ if ((mask & MRP_WAYLAND_AREA_POSITION_MASK))
+ PRINT("position: %d,%d", area->x, area->y);
+ if ((mask & MRP_WAYLAND_AREA_SIZE_MASK))
+ PRINT("size: %dx%d", area->width, area->height);
+ if ((mask & MRP_WAYLAND_AREA_KEEPRATIO_MASK))
+ PRINT("keepratio: %s", area->keepratio ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_AREA_ALIGN_MASK))
+ PRINT("align: 0x%x =%s", area->align, align_str(area->align,
+ as, sizeof(as)));
+ return p - buf;
+
+#undef PRINT
+}
+
+const char *mrp_wayland_area_align_str(mrp_wayland_area_align_t align)
+{
+ switch (align) {
+ case MRP_WAYLAND_AREA_ALIGN_LEFT: return "left";
+ case MRP_WAYLAND_AREA_ALIGN_RIGHT: return "right";
+ case MRP_WAYLAND_AREA_ALIGN_TOP: return "top";
+ case MRP_WAYLAND_AREA_ALIGN_BOTTOM: return "bottom";
+ default: return "middle";
+ }
+}
+
+void mrp_wayland_area_set_scripting_data(mrp_wayland_area_t *area, void *data)
+{
+ MRP_ASSERT(area, "Invalid Argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ area->scripting_data = data;
+}
+
+
+static char *align_str(mrp_wayland_area_align_t align, char *buf, size_t len)
+{
+#define PRINT(fmt, args... ) \
+ if (p < e) { p += snprintf(p, e-p, " " fmt , ## args); }
+
+ typedef struct {
+ mrp_wayland_area_align_t mask;
+ const char *name;
+ } map_t;
+
+ static map_t hmap[] = {
+ { MRP_WAYLAND_AREA_ALIGN_LEFT , "left" },
+ { MRP_WAYLAND_AREA_ALIGN_MIDDLE , "hmiddle" },
+ { MRP_WAYLAND_AREA_ALIGN_RIGHT , "right" },
+ { 0, NULL }
+ };
+ static map_t vmap[] = {
+ { MRP_WAYLAND_AREA_ALIGN_TOP , "top" },
+ { MRP_WAYLAND_AREA_ALIGN_MIDDLE , "vmiddle" },
+ { MRP_WAYLAND_AREA_ALIGN_BOTTOM , "bottom" },
+ { 0, NULL }
+ };
+
+ mrp_wayland_area_align_t halign, valign;
+ map_t *m;
+ char *p, *e;
+
+ halign = align & MRP_WAYLAND_AREA_ALIGN_HMASK;
+ valign = align & MRP_WAYLAND_AREA_ALIGN_VMASK;
+
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ for (m = hmap; m->name; m++) {
+ if ((halign == m->mask)) {
+ PRINT("%s", m->name);
+ align &= ~m->mask;
+ break;
+ }
+ }
+
+ for (m = vmap; m->name; m++) {
+ if ((valign == m->mask)) {
+ PRINT("%s", m->name);
+ align &= ~m->mask;
+ break;
+ }
+ }
+
+ if (align)
+ PRINT("<unknown 0x%x>", align);
+
+ return buf;
+
+#undef PRINT
+}
+
+
+static int set_area_for_applications(void *key, void *object, void *ud)
+{
+ mrp_application_t *app = (mrp_application_t *)object;
+ mrp_wayland_area_t *area = (mrp_wayland_area_t *)ud;
+
+ MRP_UNUSED(key);
+
+ if (!strcmp(app->area_name, area->fullname)) {
+ mrp_debug("set area '%s' for app '%s'", area->name, app->appid);
+ app->area = area;
+ }
+
+ return MRP_HTBL_ITER_MORE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_AREA_H__
+#define __MURPHY_WAYLAND_AREA_H__
+
+#include <sys/types.h>
+
+#include "wayland/wayland.h"
+
+enum mrp_wayland_area_operation_e {
+ MRP_WAYLAND_AREA_OPERATION_NONE = 0,
+ MRP_WAYLAND_AREA_CREATE,
+ MRP_WAYLAND_AREA_DESTROY,
+};
+
+enum mrp_wayland_area_align_e {
+ MRP_WAYLAND_AREA_ALIGN_MIDDLE = 0x00,
+
+ MRP_WAYLAND_AREA_ALIGN_HMASK = 0x03,
+ MRP_WAYLAND_AREA_ALIGN_LEFT = 0x01,
+ MRP_WAYLAND_AREA_ALIGN_RIGHT = 0x02,
+
+ MRP_WAYLAND_AREA_ALIGN_VMASK = 0x0C,
+ MRP_WAYLAND_AREA_ALIGN_TOP = 0x04,
+ MRP_WAYLAND_AREA_ALIGN_BOTTOM = 0x08,
+
+ MRP_WAYLAND_AREA_ALIGN_END_MASK = 0x10
+};
+
+struct mrp_wayland_area_s {
+ mrp_wayland_t *wl;
+ mrp_wayland_window_manager_t *wm;
+
+ int32_t areaid;
+ char *name;
+ char *fullname;
+ mrp_wayland_output_t *output;
+ int32_t x, y;
+ int32_t width, height;
+ bool keepratio;
+ mrp_wayland_area_align_t align;
+
+ void *scripting_data;
+};
+
+
+enum mrp_wayland_area_update_mask_e {
+ MRP_WAYLAND_AREA_AREAID_MASK = 0x0001,
+ MRP_WAYLAND_AREA_NAME_MASK = 0x0002,
+ MRP_WAYLAND_AREA_FULLNAME_MASK = 0x0004,
+ MRP_WAYLAND_AREA_OUTPUT_MASK = 0x0008,
+ MRP_WAYLAND_AREA_X_MASK = 0x0010,
+ MRP_WAYLAND_AREA_Y_MASK = 0x0020,
+ MRP_WAYLAND_AREA_POSITION_MASK = 0x0030,
+ MRP_WAYLAND_AREA_WIDTH_MASK = 0x0040,
+ MRP_WAYLAND_AREA_HEIGHT_MASK = 0x0080,
+ MRP_WAYLAND_AREA_SIZE_MASK = 0x00C0,
+ MRP_WAYLAND_AREA_KEEPRATIO_MASK = 0x0100,
+ MRP_WAYLAND_AREA_ALIGN_MASK = 0x0200,
+
+ MRP_WAYLAND_AREA_END_MASK = 0x0400
+};
+
+
+struct mrp_wayland_area_update_s {
+ mrp_wayland_area_update_mask_t mask;
+ int32_t areaid;
+ const char *name;
+ mrp_wayland_output_t *output;
+ int32_t x, y;
+ int32_t width, height;
+ bool keepratio;
+ mrp_wayland_area_align_t align;
+};
+
+mrp_wayland_area_t *mrp_wayland_area_create(mrp_wayland_t *wl,
+ mrp_wayland_area_update_t *u);
+void mrp_wayland_area_destroy(mrp_wayland_area_t *area);
+
+mrp_wayland_area_t *mrp_wayland_area_find(mrp_wayland_t *wl,
+ const char *fullname);
+
+size_t mrp_wayland_area_print(mrp_wayland_area_t *area,
+ mrp_wayland_area_update_mask_t mask,
+ char *buf, size_t len);
+
+const char *mrp_wayland_area_align_str(mrp_wayland_area_align_t align);
+
+void mrp_wayland_area_set_scripting_data(mrp_wayland_area_t *area, void *data);
+
+
+#endif /* __MURPHY_WAYLAND_AREA_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include <wayland-util.h>
+#include <ico-uxf-weston-plugin/ico_input_mgr-client-protocol.h>
+
+#include "ico-input-manager.h"
+#include "input-manager.h"
+
+typedef struct exinput_s exinput_t;
+typedef struct device_s device_t;
+
+struct mrp_ico_input_manager_s {
+ MRP_WAYLAND_INPUT_MANAGER_COMMON;
+};
+
+struct exinput_s {
+ MRP_WAYLAND_OBJECT_COMMON;
+};
+
+struct device_s {
+ MRP_WAYLAND_OBJECT_COMMON;
+};
+
+
+static bool input_manager_constructor(mrp_wayland_t *, mrp_wayland_object_t *);
+static bool exinput_constructor(mrp_wayland_t *, mrp_wayland_object_t *);
+static void exinput_destructor(mrp_wayland_object_t *);
+static bool device_constructor(mrp_wayland_t *, mrp_wayland_object_t *);
+static void device_destructor(mrp_wayland_object_t *);
+
+
+static bool input_manager_constructor(mrp_wayland_t *,mrp_wayland_object_t *);
+
+static void exinput_capabilities_callback(void *, struct ico_exinput *,
+ const char *, int32_t,
+ const char *, int32_t,
+ const char *, int32_t);
+static void exinput_code_callback(void *, struct ico_exinput *, const char *,
+ int32_t, const char *, int32_t);
+static void exinput_input_callback(void *, struct ico_exinput *, uint32_t,
+ const char *, int32_t, int32_t, int32_t);
+static void device_input_regions_callback(void *,
+ struct ico_input_mgr_device *,
+ struct wl_array *);
+
+
+bool mrp_ico_input_manager_register(mrp_wayland_t *wl)
+{
+ mrp_wayland_factory_t factory;
+
+ factory.size = sizeof(mrp_ico_input_manager_t);
+ factory.interface = &ico_input_mgr_control_interface;
+ factory.constructor = input_manager_constructor;
+ factory.destructor = NULL;
+ mrp_wayland_register_interface(wl, &factory);
+
+ factory.size = sizeof(exinput_t);
+ factory.interface = &ico_exinput_interface;
+ factory.constructor = exinput_constructor;
+ factory.destructor = exinput_destructor;
+ mrp_wayland_register_interface(wl, &factory);
+
+ factory.size = sizeof(device_t);
+ factory.interface = &ico_input_mgr_device_interface;
+ factory.constructor = device_constructor;
+ factory.destructor = device_destructor;
+ mrp_wayland_register_interface(wl, &factory);
+
+ return true;
+}
+
+static bool input_manager_constructor(mrp_wayland_t *wl,
+ mrp_wayland_object_t *obj)
+{
+ mrp_ico_input_manager_t *im = (mrp_ico_input_manager_t *)obj;
+
+ MRP_ASSERT(im, "invalid argument");
+
+ wl->im = (mrp_wayland_input_manager_t *)im;
+
+ return true;
+}
+
+static bool exinput_constructor(mrp_wayland_t *wl, mrp_wayland_object_t *obj)
+{
+ static struct ico_exinput_listener listener = {
+ .capabilities = exinput_capabilities_callback,
+ .code = exinput_code_callback,
+ .input = exinput_input_callback
+ };
+
+ exinput_t *xinp = (exinput_t *)obj;
+ int sts;
+
+ MRP_UNUSED(wl);
+
+ sts = ico_exinput_add_listener((struct ico_exinput *)xinp->proxy,
+ &listener, xinp);
+ if (sts < 0)
+ return false;
+
+ return true;
+}
+
+static void exinput_destructor(mrp_wayland_object_t *obj)
+{
+ exinput_t *xinp = (exinput_t *)obj;
+
+ MRP_UNUSED(xinp);
+}
+
+static bool device_constructor(mrp_wayland_t *wl, mrp_wayland_object_t *obj)
+{
+ static struct ico_input_mgr_device_listener listener = {
+ .input_regions = NULL
+ };
+
+ device_t *dev = (device_t *)obj;
+ int sts;
+
+ MRP_UNUSED(wl);
+ MRP_UNUSED(device_input_regions_callback);
+
+ sts = ico_input_mgr_device_add_listener((struct ico_input_mgr_device *)dev,
+ &listener, dev);
+ if (sts < 0)
+ return false;
+
+ return true;
+}
+
+static void device_destructor(mrp_wayland_object_t *obj)
+{
+ device_t *dev = (device_t *)obj;
+
+ MRP_UNUSED(dev);
+}
+
+
+
+static void exinput_capabilities_callback(void *data,
+ struct ico_exinput *ico_exinput,
+ const char *device,
+ int32_t type,
+ const char *swname,
+ int32_t input,
+ const char *codename,
+ int32_t code)
+{
+ exinput_t *xinp = (exinput_t *)data;
+
+ MRP_ASSERT(xinp && xinp->interface && xinp->interface->wl,
+ "invalid argument");
+ MRP_ASSERT(ico_exinput == (struct ico_exinput *)xinp->proxy,
+ "confused with data structures");
+
+ mrp_debug("exinput_capabilities_callback(device='%s', type=%d,"
+ "swname='%s', input=%d, codename='%s', code=%d)",
+ device, type, swname, input, codename, code);
+
+}
+
+
+static void exinput_code_callback(void *data,
+ struct ico_exinput *ico_exinput,
+ const char *device,
+ int32_t input,
+ const char *codename,
+ int32_t code)
+{
+ exinput_t *xinp = (exinput_t *)data;
+
+ MRP_ASSERT(xinp && xinp->interface && xinp->interface->wl,
+ "invalid argument");
+ MRP_ASSERT(ico_exinput == (struct ico_exinput *)xinp->proxy,
+ "confused with data structures");
+
+ mrp_debug("exinput_code_callback(device='%s', input=%d, "
+ "codename='%s', code=%d)",
+ device, input, codename, code);
+}
+
+
+static void exinput_input_callback(void *data,
+ struct ico_exinput *ico_exinput,
+ uint32_t time,
+ const char *device,
+ int32_t input,
+ int32_t code,
+ int32_t state)
+{
+ exinput_t *xinp = (exinput_t *)data;
+
+ MRP_ASSERT(xinp && xinp->interface && xinp->interface->wl,
+ "invalid argument");
+ MRP_ASSERT(ico_exinput == (struct ico_exinput *)xinp->proxy,
+ "confused with data structures");
+
+ mrp_debug("exinput_input_callback(time=%u, device='%s', "
+ "input=%d, code=%d, state=%d)",
+ time, device, input, code, state);
+}
+
+
+static void device_input_regions_callback(void *data,
+ struct ico_input_mgr_device *
+ ico_input_device,
+ struct wl_array *regions)
+{
+ device_t *dev = (device_t *)data;
+
+ MRP_UNUSED(regions);
+
+ MRP_ASSERT(dev && dev->interface && dev->interface->wl,
+ "invalid argument");
+ MRP_ASSERT(ico_input_device == (struct ico_input_mgr_device *)dev->proxy,
+ "confused with data structures");
+
+ mrp_debug("device_input_regions_callback()");
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_ICO_INPUT_MANAGER_H__
+#define __MURPHY_ICO_INPUT_MANAGER_H__
+
+#include "wayland/wayland.h"
+
+typedef struct mrp_ico_input_manager_s mrp_ico_input_manager_t;
+
+bool mrp_ico_input_manager_register(mrp_wayland_t *wl);
+
+#endif /* __MURPHY_ICO_INPUT_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include <ico-uxf-weston-plugin/ico_window_mgr-client-protocol.h>
+
+#include "ico-window-manager.h"
+#include "layer.h"
+#include "output.h"
+#include "animation.h"
+#include "window.h"
+#include "window-manager.h"
+#include "area.h"
+
+#define MAX_COORDINATE 16383
+
+#define SURFACE_TO_NODE(s) (((s) >> 16) & 0xFF)
+#define SURFACE_TO_HOST(s) (((s) >> 24) & 0xFF)
+
+struct mrp_ico_window_manager_s {
+ MRP_WAYLAND_WINDOW_MANAGER_COMMON;
+};
+
+
+static bool window_manager_constructor(mrp_wayland_t *,mrp_wayland_object_t *);
+
+static void window_created_callback(void *, struct ico_window_mgr *, uint32_t,
+ const char *,int32_t,const char *,int32_t);
+static void window_name_callback(void *, struct ico_window_mgr *,
+ uint32_t, const char *);
+static void window_destroyed_callback(void *,struct ico_window_mgr *,uint32_t);
+static void window_visible_callback(void *, struct ico_window_mgr *, uint32_t,
+ int32_t, int32_t, int32_t);
+static void window_configure_callback(void *, struct ico_window_mgr *,uint32_t,
+ uint32_t, int32_t, uint32_t, int32_t,
+ int32_t, int32_t,int32_t, int32_t);
+static void window_active_callback(void *, struct ico_window_mgr *, uint32_t,
+ int32_t);
+static void layer_visible_callback(void *, struct ico_window_mgr *,
+ uint32_t, int32_t);
+static void app_surfaces_callback(void *, struct ico_window_mgr *,
+ const char *, int32_t, struct wl_array *);
+static void map_surface_callback(void *, struct ico_window_mgr *, int32_t,
+ uint32_t, uint32_t, uint32_t,
+ int32_t,int32_t, int32_t, uint32_t);
+
+
+static void layer_request(mrp_wayland_layer_t *,
+ mrp_wayland_layer_update_t *);
+
+static mrp_wayland_window_t *find_window(mrp_ico_window_manager_t *, int32_t,
+ const char *);
+static int32_t set_window_animation(mrp_wayland_window_t *,
+ mrp_wayland_animation_type_t,
+ mrp_wayland_animation_t *);
+static void set_window_area(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *,
+ mrp_wayland_animation_t *);
+static void set_window_geometry(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *,
+ mrp_wayland_animation_t *);
+static void set_window_alignment(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *);
+static void set_window_visible(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *,
+ mrp_wayland_animation_t *);
+static void set_window_active(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *);
+static void set_window_mapped(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *,
+ uint32_t);
+static void set_window_layer(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *);
+static void window_request(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *,
+ mrp_wayland_animation_t *, uint32_t);
+
+static mrp_wayland_layer_type_t get_layer_type(uint32_t);
+
+
+bool mrp_ico_window_manager_register(mrp_wayland_t *wl)
+{
+ mrp_wayland_factory_t factory;
+
+ factory.size = sizeof(mrp_ico_window_manager_t);
+ factory.interface = &ico_window_mgr_interface;
+ factory.constructor = window_manager_constructor;
+ factory.destructor = NULL;
+
+ mrp_wayland_register_interface(wl, &factory);
+
+ return true;
+}
+
+static bool window_manager_constructor(mrp_wayland_t *wl,
+ mrp_wayland_object_t *obj)
+{
+ static struct ico_window_mgr_listener listener = {
+ .window_created = window_created_callback,
+ .window_name = window_name_callback,
+ .window_destroyed = window_destroyed_callback,
+ .window_visible = window_visible_callback,
+ .window_configure = window_configure_callback,
+ .window_active = window_active_callback,
+ .layer_visible = layer_visible_callback,
+ .app_surfaces = app_surfaces_callback,
+ .map_surface = map_surface_callback
+ };
+
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)obj;
+ int sts;
+
+ MRP_ASSERT(wm, "invalid argument");
+
+ wm->layer_request = layer_request;
+ wm->window_request = window_request;
+
+ sts = ico_window_mgr_add_listener((struct ico_window_mgr *)wm->proxy,
+ &listener, wm);
+
+ if (sts < 0)
+ return false;
+
+ ico_window_mgr_declare_manager((struct ico_window_mgr *)wm->proxy,
+ ICO_WINDOW_MGR_DECLARE_MANAGER_MANAGER);
+
+ mrp_wayland_register_window_manager(wl, (mrp_wayland_window_manager_t*)wm);
+
+ return true;
+}
+
+
+static void window_created_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid,
+ const char *winname,
+ int32_t pid,
+ const char *appid,
+ int32_t layertype)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_t *wl;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ wl = wm->interface->wl;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_SURFACEID_MASK |
+ MRP_WAYLAND_WINDOW_NAME_MASK |
+ MRP_WAYLAND_WINDOW_APPID_MASK |
+ MRP_WAYLAND_WINDOW_PID_MASK |
+ MRP_WAYLAND_WINDOW_LAYERTYPE_MASK ;
+
+ u.surfaceid = surfaceid;
+ u.name = winname ? winname : "";
+ u.appid = appid ? appid : "";
+ u.pid = pid;
+ u.layertype = get_layer_type(layertype);
+
+ mrp_debug("surfaceid=%d, winname='%s' pid=%d appid='%s' layertype='%d'",
+ u.surfaceid, u.name, u.pid, u.appid, u.layertype);
+
+ mrp_wayland_window_create(wl, &u);
+}
+
+static void window_name_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid,
+ const char *winname)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_window_t *win;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(wm && wm->interface, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ if (!winname) {
+ mrp_log_error("Missing window name in %s()", __FUNCTION__);
+ return;
+ }
+
+ mrp_debug("surfaceid=%d, winname='%s'", surfaceid, winname);
+
+ if (!(win = find_window(wm, surfaceid, "update")))
+ return;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_NAME_MASK;
+ u.name = winname;
+
+ mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_NAMECHANGE, &u);
+}
+
+static void window_destroyed_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_window_t *win;
+
+ MRP_ASSERT(wm && wm->interface, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ mrp_debug("surfaceid=%d", surfaceid);
+
+ if (!(win = find_window(wm, surfaceid, "destruction")))
+ return;
+
+ mrp_wayland_window_destroy(win);
+}
+
+static void window_visible_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid,
+ int32_t visible,
+ int32_t raise,
+ int32_t hint)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_window_t *win;
+ mrp_wayland_window_update_t u;
+
+ MRP_UNUSED(hint);
+
+ MRP_ASSERT(wm && wm->interface, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ mrp_debug("surfaceid=%d visible=%d raise=%d hint=%d",
+ surfaceid, visible, raise, hint);
+
+ if (!(win = find_window(wm, surfaceid, "visibility update")))
+ return;
+
+ memset(&u, 0, sizeof(u));
+ if (visible != ICO_WINDOW_MGR_V_NOCHANGE) {
+ u.mask |= MRP_WAYLAND_WINDOW_VISIBLE_MASK;
+ u.visible = visible ? true : false;
+ }
+ if (raise != ICO_WINDOW_MGR_V_NOCHANGE) {
+ u.mask |= MRP_WAYLAND_WINDOW_RAISE_MASK;
+ u.raise = raise ? true : false;
+ }
+
+ if (u.mask)
+ mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_VISIBLE, &u);
+ else
+ mrp_debug("nothing to do");
+}
+
+static void window_configure_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid,
+ uint32_t node,
+ int32_t layertype,
+ uint32_t layer,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height,
+ int32_t hint)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_window_t *win;
+ mrp_wayland_t *wl;
+ mrp_wayland_window_update_t u;
+
+ MRP_UNUSED(layertype);
+ MRP_UNUSED(hint);
+
+ MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ wl = wm->interface->wl;
+
+ mrp_debug("surfaceid=%d node=%u layertype=%d layer=%u position=%d,%d "
+ "size=%dx%d hint=%d", surfaceid, node, layertype, layer,
+ x,y, width,height, hint);
+
+ if (!(win = find_window(wm, surfaceid, "configuration update")))
+ return;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_NODEID_MASK |
+ MRP_WAYLAND_WINDOW_LAYERTYPE_MASK ;
+ u.nodeid = node;
+ u.layertype = layertype;
+
+ if (hint == ICO_WINDOW_MGR_HINT_CHANGE) {
+ if (x <= MAX_COORDINATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_X_MASK;
+ u.x = x;
+ }
+ if (y <= MAX_COORDINATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_Y_MASK;
+ u.y = y;
+ }
+ if (width <= MAX_COORDINATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_WIDTH_MASK;
+ u.width = width;
+ }
+ if (height <= MAX_COORDINATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_HEIGHT_MASK;
+ u.height = height;
+ }
+ }
+
+ if (!(u.layer = mrp_wayland_layer_find(wl, layer)))
+ mrp_log_error("can't find layer %u", layer);
+ else
+ u.mask |= MRP_WAYLAND_WINDOW_LAYER_MASK;
+
+ mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_CONFIGURE, &u);
+}
+
+static void window_active_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t surfaceid,
+ int32_t active)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_window_t *win;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(wm && wm->interface, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ mrp_debug("surfaceid=%u active=%d", surfaceid, active);
+
+ if (!(win = find_window(wm, surfaceid, "state update")))
+ return;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_ACTIVE_MASK;
+ u.active = 0;
+
+ if ((active & MRP_WAYLAND_WINDOW_ACTIVE_POINTER))
+ u.active |= ICO_WINDOW_MGR_ACTIVE_POINTER;
+ if ((active & MRP_WAYLAND_WINDOW_ACTIVE_KEYBOARD))
+ u.active |= ICO_WINDOW_MGR_ACTIVE_KEYBOARD;
+ if ((active & MRP_WAYLAND_WINDOW_ACTIVE_SELECTED))
+ u.active |= ICO_WINDOW_MGR_ACTIVE_SELECTED;
+
+ mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_ACTIVE, &u);
+}
+
+static void layer_visible_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ uint32_t layerid,
+ int32_t visible)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+ mrp_wayland_t *wl;
+ mrp_wayland_layer_t *layer;
+ mrp_wayland_layer_update_t u;
+
+ MRP_ASSERT(wm && wm->interface && wm->interface->wl, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ wl = wm->interface->wl;
+
+ mrp_debug("layerid=%u visible=%d", layerid, visible);
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_VISIBLE_MASK;
+ u.visible = visible;
+
+ if (!(layer = mrp_wayland_layer_find(wl, layerid))) {
+ mrp_log_error("can't find layer %u", layerid);
+ return;
+ }
+
+ mrp_wayland_layer_update(layer, MRP_WAYLAND_LAYER_VISIBLE, &u);
+}
+
+static void app_surfaces_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ const char *appid,
+ int32_t pid,
+ struct wl_array *surfaces)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+
+ MRP_UNUSED(pid);
+ MRP_UNUSED(surfaces);
+
+ MRP_ASSERT(wm, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ mrp_debug("app '%s' surfaces:",
+ appid);
+}
+
+static void map_surface_callback(void *data,
+ struct ico_window_mgr *ico_window_mgr,
+ int32_t event,
+ uint32_t surfaceid,
+ uint32_t type,
+ uint32_t target,
+ int32_t width,
+ int32_t height,
+ int32_t stride,
+ uint32_t format)
+{
+ mrp_ico_window_manager_t *wm = (mrp_ico_window_manager_t *)data;
+
+ MRP_UNUSED(event);
+ MRP_UNUSED(type);
+ MRP_UNUSED(target);
+ MRP_UNUSED(width);
+ MRP_UNUSED(height);
+ MRP_UNUSED(stride);
+ MRP_UNUSED(format);
+
+ MRP_ASSERT(wm, "invalid argument");
+ MRP_ASSERT(ico_window_mgr == (struct ico_window_mgr *)wm->proxy,
+ "confused with data structures");
+
+ mrp_debug("event=%d surfaceid=%u type=%d target=%d size=%dx%d stride=%d "
+ "format=%u", event, surfaceid, type, target, width,height,
+ stride, format);
+}
+
+static void set_layer_visible(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_update_t *u)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ mrp_wayland_layer_update_mask_t mask;
+ int32_t visible;
+ bool need_visibility_change;
+
+ ico_window_mgr = (struct ico_window_mgr *)layer->wm->proxy;
+ mask = u->mask;
+
+ need_visibility_change = false;
+ if (!(mask & MRP_WAYLAND_LAYER_VISIBLE_MASK) ||
+ (u->visible && layer->visible) || (!u->visible && !layer->visible))
+ {
+ visible = ICO_WINDOW_MGR_V_NOCHANGE;
+ }
+ else {
+ visible = u->visible ? ICO_WINDOW_MGR_VISIBLE_SHOW :
+ ICO_WINDOW_MGR_VISIBLE_HIDE;
+ need_visibility_change = true;
+ }
+
+ if (!need_visibility_change) {
+ mrp_debug("nothing to do");
+ return;
+ }
+
+ mrp_debug("calling ico_window_mgr_set_layer_visible(layer=%d, visible=%d)",
+ layer->layerid, visible);
+
+ ico_window_mgr_set_layer_visible(ico_window_mgr, layer->layerid, visible);
+}
+
+static void layer_request(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_update_t *u)
+{
+ mrp_wayland_t *wl;
+ mrp_wayland_layer_update_mask_t mask;
+ char buf[2048];
+
+ MRP_ASSERT(layer && layer->wm && layer->wm->proxy &&
+ layer->wm->interface && layer->wm->interface->wl,
+ "invalid argument");
+
+ wl = layer->wm->interface->wl;
+ mask = u->mask;
+
+ mrp_wayland_layer_request_print(u, buf, sizeof(buf));
+ mrp_debug("request for layer %d update:%s", layer->layerid, buf);
+
+ while (mask) {
+ if ((mask & MRP_WAYLAND_LAYER_VISIBLE_MASK)) {
+ set_layer_visible(layer, u);
+ mask &= ~MRP_WAYLAND_LAYER_VISIBLE_MASK;
+ }
+ else {
+ mask = 0;
+ }
+ }
+
+ mrp_wayland_flush(wl);
+}
+
+
+static mrp_wayland_window_t *find_window(mrp_ico_window_manager_t *wm,
+ int32_t surfaceid,
+ const char *operation)
+{
+ mrp_wayland_t *wl;
+ mrp_wayland_window_t *win = NULL;
+
+ if (!(wm->interface) || !(wl = wm->interface->wl) ||
+ !(win = mrp_wayland_window_find(wl, surfaceid)))
+ {
+ mrp_log_error("window %d not found. No %s", surfaceid, operation);
+ }
+
+ return win;
+}
+
+static int32_t set_window_animation(mrp_wayland_window_t *win,
+ mrp_wayland_animation_type_t type,
+ mrp_wayland_animation_t *anims)
+{
+ static int32_t ico_types[MRP_WAYLAND_ANIMATION_MAX] = {
+ [MRP_WAYLAND_ANIMATION_HIDE] = ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE,
+ [MRP_WAYLAND_ANIMATION_SHOW] = ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW,
+ [MRP_WAYLAND_ANIMATION_MOVE] = ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE,
+ [MRP_WAYLAND_ANIMATION_RESIZE] = ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE
+ };
+
+ struct ico_window_mgr *ico_window_mgr;
+ mrp_wayland_animation_t *a;
+ int32_t flags;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+ flags = ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE;
+
+ if (anims && type >= 0 && type < MRP_WAYLAND_ANIMATION_MAX) {
+ a = anims + type;
+
+ if (a->name && a->name[0] && a->time > 0) {
+ mrp_debug("calling ico_window_mgr_set_animation"
+ "(surfaceid=%d type=%d, animation='%s' time=%d)",
+ win->surfaceid, ico_types[type], a->name, a->time);
+
+ ico_window_mgr_set_animation(ico_window_mgr, win->surfaceid,
+ ico_types[type], a->name, a->time);
+ flags = ICO_WINDOW_MGR_FLAGS_ANIMATION;
+ }
+ }
+
+ return flags;
+}
+
+static void set_window_area(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims)
+{
+ mrp_wayland_area_t *area;
+ mrp_wayland_output_t *output;
+
+ if (!(area = u->area)) {
+ mrp_log_error("system-controller: request for area change but "
+ "no area defined");
+ return;
+ }
+
+ output = area->output;
+
+ MRP_ASSERT(output, "confused withdata structures");
+
+ if (win->nodeid != output->outputid) {
+ u->mask |= MRP_WAYLAND_WINDOW_NODEID_MASK;
+ u->nodeid = output->outputid;
+ }
+
+ u->mask |= MRP_WAYLAND_WINDOW_POSITION_MASK | MRP_WAYLAND_WINDOW_SIZE_MASK;
+
+ u->x = area->x;
+ u->y = area->y;
+
+ u->width = area->width;
+ u->height = area->height;
+
+ set_window_geometry(win, u, anims);
+}
+
+
+static void set_window_geometry(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ mrp_wayland_window_update_mask_t mask;
+ int32_t node;
+ int32_t x, y;
+ int32_t width, height;
+ int32_t flags;
+ bool first_time;
+ bool need_nodechanging;
+ bool need_positioning;
+ bool need_resizing;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+ mask = u->mask;
+ flags = ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE;
+ first_time = win->nodeid < 0;
+
+ node = (mask & MRP_WAYLAND_WINDOW_NODEID_MASK) ? u->nodeid : win->nodeid;
+ if (node < 0)
+ node = SURFACE_TO_NODE(win->surfaceid);
+ need_nodechanging = (mask & MRP_WAYLAND_WINDOW_NODEID_MASK) ||
+ node != win->nodeid;
+
+ need_positioning = false;
+ if (!(mask & MRP_WAYLAND_WINDOW_X_MASK) || (u->x == win->x)) {
+ if (!first_time)
+ x = ICO_WINDOW_MGR_V_NOCHANGE;
+ else {
+ x = win->x;
+ need_positioning = true;
+ }
+ }
+ else {
+ x = u->x;
+ need_positioning = true;
+ }
+ if (!(mask & MRP_WAYLAND_WINDOW_Y_MASK) || (u->y == win->y)) {
+ if (!first_time)
+ y = ICO_WINDOW_MGR_V_NOCHANGE;
+ else {
+ y = win->y;
+ need_positioning = true;
+ }
+ }
+ else {
+ y = u->y;
+ need_positioning = true;
+ }
+
+ need_resizing = false;
+ if (!(mask & MRP_WAYLAND_WINDOW_WIDTH_MASK) || (u->width == win->width)) {
+ if (!first_time)
+ width = ICO_WINDOW_MGR_V_NOCHANGE;
+ else {
+ width = win->width;
+ need_positioning = true;
+ }
+ }
+ else {
+ width = u->width;
+ need_resizing = true;
+ }
+ if (!(mask&MRP_WAYLAND_WINDOW_HEIGHT_MASK) || (u->height == win->height)) {
+ if (!first_time)
+ height = ICO_WINDOW_MGR_V_NOCHANGE;
+ else {
+ height = win->height;
+ need_positioning = true;
+ }
+ }
+ else {
+ height = u->height;
+ need_resizing = true;
+ }
+
+ if (!need_nodechanging && !need_positioning && !need_resizing) {
+ mrp_debug("nothing to do");
+ return;
+ }
+
+ flags = ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE;
+ if (need_positioning)
+ flags |= set_window_animation(win, MRP_WAYLAND_ANIMATION_MOVE, anims);
+ if (need_resizing)
+ flags |= set_window_animation(win, MRP_WAYLAND_ANIMATION_RESIZE,anims);
+ if ((flags & ~ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE))
+ flags &= ~ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE;
+
+ mrp_debug("calling ico_window_mgr_set_positionsize"
+ "(surfaceid=%d, node=%u position=%d,%d size=%dx%d flags=%d)",
+ win->surfaceid, node, x,y, width,height, flags);
+
+ ico_window_mgr_set_positionsize(ico_window_mgr, win->surfaceid, node,
+ x,y, width,height, flags);
+}
+
+static void set_window_alignment(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ mrp_wayland_area_t *area;
+ uint32_t attrs;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+
+ if (!(area = u->area)) {
+ mrp_log_error("attempt to set NULL area");
+ return;
+ }
+
+ if (win->area) {
+ if (win->area->keepratio == area->keepratio &&
+ win->area->align == area->align)
+ {
+ mrp_debug("nothing to do");
+ return;
+ }
+ }
+
+ win->area = area;
+
+ if (!area->keepratio)
+ attrs = 0;
+ else {
+ attrs = ICO_WINDOW_MGR_ATTR_FIXED_ASPECT;
+
+ switch ((area->align & MRP_WAYLAND_AREA_ALIGN_HMASK)) {
+ case MRP_WAYLAND_AREA_ALIGN_LEFT:
+ attrs |= ICO_WINDOW_MGR_ATTR_ALIGN_LEFT;
+ break;
+ case MRP_WAYLAND_AREA_ALIGN_RIGHT:
+ attrs |= ICO_WINDOW_MGR_ATTR_ALIGN_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ switch ((area->align & MRP_WAYLAND_AREA_ALIGN_VMASK)) {
+ case MRP_WAYLAND_AREA_ALIGN_TOP:
+ attrs |= ICO_WINDOW_MGR_ATTR_ALIGN_TOP;
+ break;
+ case MRP_WAYLAND_AREA_ALIGN_BOTTOM:
+ attrs |= ICO_WINDOW_MGR_ATTR_ALIGN_BOTTOM;
+ break;
+ default:
+ break;
+ }
+ }
+
+ mrp_debug("calling ico_window_mgr_set_attributes(surfaceid=%d attrs=0x%x)",
+ win->surfaceid, attrs);
+
+ ico_window_mgr_set_attributes(ico_window_mgr, win->surfaceid, attrs);
+
+ return;
+}
+
+static void set_window_visible(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ mrp_wayland_window_update_mask_t mask;
+ mrp_wayland_animation_type_t anim_type;
+ int32_t visible;
+ int32_t raise;
+ int32_t flags;
+ bool need_visibility_change;
+ bool need_raising;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+ mask = u->mask;
+
+ need_visibility_change = false;
+ if (!(mask & MRP_WAYLAND_WINDOW_VISIBLE_MASK) ||
+ (u->visible && win->visible) || (!u->visible && !win->visible))
+ {
+ visible = ICO_WINDOW_MGR_V_NOCHANGE;
+ anim_type = 0;
+ }
+ else {
+ visible = u->visible ? ICO_WINDOW_MGR_VISIBLE_SHOW :
+ ICO_WINDOW_MGR_VISIBLE_HIDE;
+ anim_type = visible ? MRP_WAYLAND_ANIMATION_SHOW :
+ MRP_WAYLAND_ANIMATION_HIDE;
+ win->visible = u->visible;
+ need_visibility_change = true;
+ }
+
+ need_raising = false;
+ if (!(mask & MRP_WAYLAND_WINDOW_RAISE_MASK) ||
+ (u->raise && win->raise) || (!u->raise && !win->raise))
+ {
+ raise = ICO_WINDOW_MGR_V_NOCHANGE;
+ }
+ else {
+ raise = u->raise ? ICO_WINDOW_MGR_RAISE_RAISE :
+ ICO_WINDOW_MGR_RAISE_LOWER;
+ win->raise = u->raise;
+ need_raising = true;
+ }
+
+ if (!need_visibility_change && !need_raising) {
+ mrp_debug("nothing to do");
+ return;
+ }
+
+ if (need_visibility_change)
+ flags = set_window_animation(win, anim_type, anims);
+ else
+ flags = ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE;
+
+ mrp_debug("calling ico_window_mgr_set_visible"
+ "(surfaceid=%d, visible=%d, raise=%d, flags=%d)",
+ win->surfaceid, visible, raise, flags);
+
+ ico_window_mgr_set_visible(ico_window_mgr, win->surfaceid,
+ visible, raise, flags);
+}
+
+static void set_window_active(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ int32_t active;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+ active = 0;
+
+ if (u->active == win->active)
+ mrp_debug("nothing to do");
+ else {
+ if ((u->active & MRP_WAYLAND_WINDOW_ACTIVE_POINTER))
+ active |= ICO_WINDOW_MGR_ACTIVE_POINTER;
+ if ((u->active & MRP_WAYLAND_WINDOW_ACTIVE_KEYBOARD))
+ active |= ICO_WINDOW_MGR_ACTIVE_KEYBOARD;
+ if ((u->active & MRP_WAYLAND_WINDOW_ACTIVE_SELECTED))
+ active |= ICO_WINDOW_MGR_ACTIVE_SELECTED;
+
+ mrp_debug("calling ico_window_mgr_set_active"
+ "(surfaceid=%d, active=0x%x)",
+ win->surfaceid, active);
+
+ ico_window_mgr_set_active(ico_window_mgr, win->surfaceid, active);
+ }
+}
+
+static void set_window_mapped(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u,
+ uint32_t framerate)
+{
+ struct ico_window_mgr *ico_window_mgr;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+
+ if ((u->mapped && win->mapped) || (!u->mapped && !win->mapped))
+ mrp_debug("nothing to do");
+ else {
+ if (u->mapped) {
+ mrp_debug("calling ico_window_mgr_map_surface"
+ "(surfaceid=%d, framerate=%u)",
+ win->surfaceid, framerate);
+
+ ico_window_mgr_map_surface(ico_window_mgr, win->surfaceid,
+ framerate);
+ }
+ else {
+ mrp_debug("calling ico_window_mgr_unmap_surface(surfaceid=%d)",
+ win->surfaceid);
+
+ ico_window_mgr_unmap_surface(ico_window_mgr, win->surfaceid);
+ }
+ }
+}
+
+static void set_window_layer(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u)
+{
+ struct ico_window_mgr *ico_window_mgr;
+ uint32_t layer;
+
+ ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
+
+ if (win->layer && (u->layer == win->layer)) {
+ mrp_debug("nothing to do");
+ }
+ else {
+ layer = u->layer->layerid;
+
+ mrp_debug("calling ico_window_mgr_set_window_layer"
+ "(surfaceid=%d, layer=%u)", win->surfaceid, layer);
+
+ ico_window_mgr_set_window_layer(ico_window_mgr, win->surfaceid, layer);
+ }
+}
+
+static void window_request(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims,
+ uint32_t framerate)
+{
+ static mrp_wayland_window_update_mask_t visible_mask =
+ MRP_WAYLAND_WINDOW_VISIBLE_MASK |
+ MRP_WAYLAND_WINDOW_RAISE_MASK ;
+ static mrp_wayland_window_update_mask_t active_mask =
+ MRP_WAYLAND_WINDOW_ACTIVE_MASK;
+ static mrp_wayland_window_update_mask_t mapped_mask =
+ MRP_WAYLAND_WINDOW_MAPPED_MASK;
+ static mrp_wayland_window_update_mask_t area_mask =
+ MRP_WAYLAND_WINDOW_AREA_MASK;
+ static mrp_wayland_window_update_mask_t geometry_mask =
+ MRP_WAYLAND_WINDOW_NODEID_MASK |
+ MRP_WAYLAND_WINDOW_POSITION_MASK |
+ MRP_WAYLAND_WINDOW_SIZE_MASK ;
+ static mrp_wayland_window_update_mask_t layer_mask =
+ MRP_WAYLAND_WINDOW_LAYER_MASK;
+ static mrp_wayland_window_update_mask_t align_mask =
+ MRP_WAYLAND_WINDOW_AREA_MASK;
+
+ mrp_wayland_t *wl;
+ mrp_wayland_window_update_mask_t mask;
+ char wbuf[2048];
+ char abuf[1024];
+
+ MRP_ASSERT(win && win->wm && win->wm->proxy && win->wm->interface &&
+ win->wm->interface->wl, "invalid argument");
+
+ wl = win->wm->interface->wl;
+ mask = u->mask;
+
+ mrp_wayland_window_request_print(u, wbuf, sizeof(wbuf));
+ mrp_wayland_animation_print(anims, abuf, sizeof(abuf));
+ mrp_debug("request for window %d update:%s\n animations:%s",
+ win->surfaceid, wbuf, abuf);
+
+ while (mask) {
+ if ((mask & layer_mask)) {
+ set_window_layer(win, u);
+ mask &= ~layer_mask;
+ }
+ else if ((mask & mapped_mask)) {
+ set_window_mapped(win, u, framerate);
+ mask &= ~mapped_mask;
+ }
+ else if ((mask & area_mask)) {
+ set_window_area(win, u, anims);
+ mask &= ~(area_mask | geometry_mask);
+ }
+ else if ((mask & geometry_mask)) {
+ set_window_geometry(win, u, anims);
+ mask &= ~geometry_mask;
+ }
+ else if ((mask & align_mask)) {
+ set_window_alignment(win, u);
+ mask &= ~align_mask;
+ }
+ else if ((mask & visible_mask)) {
+ set_window_visible(win, u, anims);
+ mask &= ~visible_mask;
+ }
+ else if ((mask & active_mask)) {
+ set_window_active(win, u);
+ mask &= ~active_mask;
+ }
+ else {
+ mask = 0;
+ }
+ }
+
+ mrp_wayland_flush(wl);
+}
+
+static mrp_wayland_layer_type_t get_layer_type(uint32_t layertype)
+{
+ switch (layertype) {
+
+ case ICO_WINDOW_MGR_LAYERTYPE_BACKGROUND:
+ return MRP_WAYLAND_LAYER_BACKGROUND;
+
+ case ICO_WINDOW_MGR_LAYERTYPE_NORMAL:
+ return MRP_WAYLAND_LAYER_APPLICATION;
+
+ case ICO_WINDOW_MGR_LAYERTYPE_FULLSCREEN:
+ case ICO_WINDOW_MGR_LAYERTYPE_INPUTPANEL:
+ return MRP_WAYLAND_LAYER_INPUT;
+
+ case ICO_WINDOW_MGR_LAYERTYPE_TOUCH:
+ return MRP_WAYLAND_LAYER_TOUCH;
+
+ case ICO_WINDOW_MGR_LAYERTYPE_CURSOR:
+ return MRP_WAYLAND_LAYER_CURSOR;
+
+ case ICO_WINDOW_MGR_LAYERTYPE_STARTUP:
+ return MRP_WAYLAND_LAYER_STARTUP;
+
+ default:
+ return MRP_WAYLAND_LAYER_TYPE_UNKNOWN;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_ICO_WINDOW_MANAGER_H__
+#define __MURPHY_ICO_WINDOW_MANAGER_H__
+
+#include "wayland/wayland.h"
+
+typedef struct mrp_ico_window_manager_s mrp_ico_window_manager_t;
+
+bool mrp_ico_window_manager_register(mrp_wayland_t *wl);
+
+#endif /* __MURPHY_ICO_WINDOW_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_INPUT_MANAGER_H__
+#define __MURPHY_WAYLAND_INPUT_MANAGER_H__
+
+#include <sys/types.h>
+
+#include "wayland/wayland.h"
+
+#define MRP_WAYLAND_INPUT_MANAGER_COMMON \
+ MRP_WAYLAND_OBJECT_COMMON
+
+struct mrp_wayland_input_manager_s {
+ MRP_WAYLAND_INPUT_MANAGER_COMMON;
+};
+
+#endif /* __MURPHY_WAYLAND_INPUT_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "layer.h"
+#include "window-manager.h"
+#include "scripting-wayland.h"
+
+static mrp_wayland_layer_update_mask_t update(mrp_wayland_layer_t *,
+ mrp_wayland_layer_update_t *);
+
+
+mrp_wayland_layer_t *mrp_wayland_layer_create(mrp_wayland_t *wl,
+ mrp_wayland_layer_update_t *u)
+{
+ mrp_wayland_layer_t *layer;
+ mrp_wayland_layer_update_mask_t mask;
+ char buf[2048];
+
+ MRP_ASSERT(wl && u && (u->mask & MRP_WAYLAND_LAYER_LAYERID_MASK),
+ "invalid argument");
+
+ if (!(layer = mrp_allocz(sizeof(mrp_wayland_layer_t)))) {
+ mrp_log_error("failed to create layer %d: out of memory",
+ u->layerid);
+ return NULL;
+ }
+
+ layer->wl = wl;
+ layer->wm = wl->wm;
+ layer->layerid = u->layerid;
+
+ if (!mrp_htbl_insert(wl->layers, &layer->layerid, layer)) {
+ mrp_log_error("failed to create layer: already exists");
+ mrp_free(layer);
+ return NULL;
+ }
+
+ if (!(u->mask & MRP_WAYLAND_LAYER_NAME_MASK)) {
+ snprintf(buf, sizeof(buf), "layer-%d", layer->layerid);
+
+ u->mask |= MRP_WAYLAND_LAYER_NAME_MASK;
+ u->name = buf;
+ }
+
+ mask = update(layer, u);
+
+ if (wl->create_scripting_layers)
+ layer->scripting_data = mrp_wayland_scripting_layer_create_from_c(NULL,
+ layer);
+ mrp_wayland_layer_print(layer, mask, buf,sizeof(buf));
+ mrp_debug("layer %d created%s", layer->layerid, buf);
+
+ if (wl->layer_update_callback)
+ wl->layer_update_callback(wl, MRP_WAYLAND_LAYER_CREATE, mask, layer);
+
+ return layer;
+}
+
+void mrp_wayland_layer_destroy(mrp_wayland_layer_t *layer)
+{
+ mrp_wayland_t *wl;
+ char buf[1024];
+
+ MRP_ASSERT(layer && layer->wl, "invalid argument");
+
+ wl = layer->wl;
+
+ mrp_wayland_layer_print(layer, MRP_WAYLAND_LAYER_NAME_MASK,
+ buf, sizeof(buf));
+ mrp_debug("destroying layer %d%s", layer->layerid, buf);
+
+ if (wl->layer_update_callback)
+ wl->layer_update_callback(wl, MRP_WAYLAND_LAYER_DESTROY, 0, layer);
+
+ mrp_free(layer->name);
+
+ if ((void *)layer != mrp_htbl_remove(wl->layers, &layer->layerid, false)) {
+ mrp_log_error("failed to destroy layer %d: confused with "
+ "data structures", layer->layerid);
+ return;
+ }
+
+ free(layer);
+}
+
+mrp_wayland_layer_t *mrp_wayland_layer_find(mrp_wayland_t *wl, int32_t layerid)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ return (mrp_wayland_layer_t*)mrp_htbl_lookup(wl->layers,&layerid);
+}
+
+void mrp_wayland_layer_visibility_request(mrp_wayland_layer_t *layer,
+ int32_t visible)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_layer_update_t u;
+
+ MRP_ASSERT(layer && layer->wl, "invalid arguent");
+
+ if (!(wm = layer->wm))
+ mrp_debug("ignoring layer visibility request: no window-manager");
+ else {
+ memset(&u, 0, sizeof(u));
+
+ if (visible >= 0) {
+ u.mask |= MRP_WAYLAND_LAYER_VISIBLE_MASK;
+ u.visible = visible ? true : false;
+ }
+
+ wm->layer_request(layer, &u);
+ }
+}
+
+void mrp_wayland_layer_request(mrp_wayland_t *wl,mrp_wayland_layer_update_t *u)
+{
+ mrp_wayland_layer_t *layer;
+ mrp_wayland_window_manager_t *wm;
+
+ MRP_ASSERT(wl && u, "invalid arguments");
+
+ if (!(u->mask & MRP_WAYLAND_LAYER_LAYERID_MASK) ||
+ !(layer = mrp_wayland_layer_find(wl, u->layerid)))
+ {
+ mrp_debug("can't find layer %u: request rejected", u->layerid);
+ return;
+ }
+
+ MRP_ASSERT(wl == layer->wl, "confused with data structures");
+
+ if ((wm = layer->wm))
+ wm->layer_request(layer, u);
+}
+
+void mrp_wayland_layer_update(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_operation_t oper,
+ mrp_wayland_layer_update_t *u)
+{
+ mrp_wayland_t *wl;
+ int32_t layerid;
+ mrp_wayland_layer_update_mask_t mask;
+ char buf[2048];
+
+ MRP_ASSERT(layer && layer->wl && u, "invalid argument");
+
+ wl = layer->wl;
+
+ layerid = layer->layerid;
+
+ if ((u->mask & MRP_WAYLAND_LAYER_LAYERID_MASK)) {
+ if (u->layerid != layerid) {
+ mrp_log_error("attempt to change layerid to %d of "
+ "existing layer %d", u->layerid, layerid);
+ return;
+ }
+ }
+
+ mask = update(layer, u);
+
+ if (!mask)
+ mrp_debug("layer %d update requested but nothing changed", layerid);
+ else {
+ mrp_wayland_layer_print(layer, mask, buf,sizeof(buf));
+ mrp_debug("layer %d updated%s", layerid, buf);
+
+ if (wl->layer_update_callback)
+ wl->layer_update_callback(wl, oper, mask, layer);
+ }
+}
+
+size_t mrp_wayland_layer_print(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_update_mask_t mask,
+ char *buf,
+ size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ char *p, *e;
+
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_LAYER_NAME_MASK))
+ PRINT("name: '%s'", layer->name);
+ if ((mask & MRP_WAYLAND_LAYER_TYPE_MASK))
+ PRINT("type: %s", mrp_wayland_layer_type_str(layer->type));
+ if ((mask & MRP_WAYLAND_LAYER_VISIBLE_MASK))
+ PRINT("visible: %s", layer->visible ? "yes" : "no");
+
+ return p - buf;
+
+#undef PRINT
+}
+
+size_t mrp_wayland_layer_request_print(mrp_wayland_layer_update_t *u,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ mrp_wayland_layer_update_mask_t mask;
+ char *p, *e;
+
+ mask = u->mask;
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_LAYER_NAME_MASK))
+ PRINT("name: '%s'", u->name);
+ if ((mask & MRP_WAYLAND_LAYER_TYPE_MASK))
+ PRINT("type: %s", mrp_wayland_layer_type_str(u->type));
+ if ((mask & MRP_WAYLAND_LAYER_VISIBLE_MASK))
+ PRINT("visible: %s", u->visible ? "yes" : "no");
+
+ return p - buf;
+
+#undef PRINT
+}
+
+const char *
+mrp_wayland_layer_update_mask_str(mrp_wayland_layer_update_mask_t mask)
+{
+ switch (mask) {
+ case MRP_WAYLAND_LAYER_LAYERID_MASK: return "layerid";
+ case MRP_WAYLAND_LAYER_NAME_MASK: return "name";
+ case MRP_WAYLAND_LAYER_TYPE_MASK: return "type";
+ case MRP_WAYLAND_LAYER_VISIBLE_MASK: return "visible";
+ default: return "<unknown>";
+ }
+}
+
+const char *mrp_wayland_layer_type_str(mrp_wayland_layer_type_t type)
+{
+ switch (type) {
+ case MRP_WAYLAND_LAYER_BACKGROUND: return "background";
+ case MRP_WAYLAND_LAYER_APPLICATION: return "application";
+ case MRP_WAYLAND_LAYER_INPUT: return "input";
+ case MRP_WAYLAND_LAYER_TOUCH: return "touch";
+ case MRP_WAYLAND_LAYER_CURSOR: return "cursor";
+ case MRP_WAYLAND_LAYER_STARTUP: return "startup";
+ default: return "<unknown>";
+ }
+}
+
+void mrp_wayland_layer_set_scripting_data(mrp_wayland_layer_t *layer,
+ void *data)
+{
+ MRP_ASSERT(layer, "Invalid Argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ layer->scripting_data = data;
+}
+
+
+static mrp_wayland_layer_update_mask_t update(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_update_t *u)
+{
+ mrp_wayland_layer_update_mask_t mask = 0;
+
+ if ((u->mask & MRP_WAYLAND_LAYER_NAME_MASK)) {
+ if (!layer->name || strcmp(u->name, layer->name)) {
+ mask |= MRP_WAYLAND_LAYER_NAME_MASK;
+ mrp_free(layer->name);
+ layer->name = mrp_strdup(u->name);
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_LAYER_TYPE_MASK)) {
+ if (u->type != layer->type) {
+ mask |= MRP_WAYLAND_LAYER_TYPE_MASK;
+ layer->type = u->type;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_LAYER_VISIBLE_MASK)) {
+ if ((u->visible && !layer->visible)||(!u->visible && layer->visible)) {
+ mask |= MRP_WAYLAND_LAYER_VISIBLE_MASK;
+ layer->visible = u->visible;
+ }
+ }
+
+ return mask;
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_LAYER_H__
+#define __MURPHY_WAYLAND_LAYER_H__
+
+#include <sys/types.h>
+
+#include "wayland/wayland.h"
+
+enum mrp_wayland_layer_type_e {
+ MRP_WAYLAND_LAYER_TYPE_UNKNOWN = 0,
+ MRP_WAYLAND_LAYER_BACKGROUND, /* 1 */
+ MRP_WAYLAND_LAYER_APPLICATION, /* 2 */
+ MRP_WAYLAND_LAYER_INPUT, /* 3 */
+ MRP_WAYLAND_LAYER_TOUCH, /* 4 */
+ MRP_WAYLAND_LAYER_CURSOR, /* 5 */
+ MRP_WAYLAND_LAYER_STARTUP, /* 6 */
+
+ MRP_WAYLAND_LAYER_TYPE_MAX
+};
+
+enum mrp_wayland_layer_operation_e {
+ MRP_WAYLAND_LAYER_OPERATION_NONE = 0,
+ MRP_WAYLAND_LAYER_CREATE,
+ MRP_WAYLAND_LAYER_DESTROY,
+ MRP_WAYLAND_LAYER_VISIBLE
+};
+
+struct mrp_wayland_layer_s {
+ mrp_wayland_t *wl;
+ mrp_wayland_window_manager_t *wm;
+
+ int32_t layerid;
+ char *name;
+ mrp_wayland_layer_type_t type;
+ bool visible;
+
+ void *scripting_data;
+};
+
+
+enum mrp_wayland_layer_update_mask_e {
+ MRP_WAYLAND_LAYER_LAYERID_MASK = 0x0001,
+ MRP_WAYLAND_LAYER_NAME_MASK = 0x0002,
+ MRP_WAYLAND_LAYER_TYPE_MASK = 0x0004,
+ MRP_WAYLAND_LAYER_VISIBLE_MASK = 0x0008,
+
+ MRP_WAYLAND_LAYER_END_MASK = 0x0010
+};
+
+
+struct mrp_wayland_layer_update_s {
+ mrp_wayland_layer_update_mask_t mask;
+ int32_t layerid;
+ const char *name;
+ mrp_wayland_layer_type_t type;
+ bool visible;
+};
+
+mrp_wayland_layer_t *mrp_wayland_layer_create(mrp_wayland_t *wl,
+ mrp_wayland_layer_update_t *u);
+void mrp_wayland_layer_destroy(mrp_wayland_layer_t *layer);
+
+mrp_wayland_layer_t *mrp_wayland_layer_find(mrp_wayland_t *wl,
+ int32_t layerid);
+
+void mrp_wayland_layer_visibility_request(mrp_wayland_layer_t *layer,
+ int32_t visible);
+
+void mrp_wayland_layer_request(mrp_wayland_t *wl,
+ mrp_wayland_layer_update_t *u);
+void mrp_wayland_layer_update(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_operation_t oper,
+ mrp_wayland_layer_update_t *u);
+
+size_t mrp_wayland_layer_print(mrp_wayland_layer_t *layer,
+ mrp_wayland_layer_update_mask_t mask,
+ char *buf,
+ size_t len);
+size_t mrp_wayland_layer_request_print(mrp_wayland_layer_update_t *u,
+ char *buf, size_t len);
+
+const char *mrp_wayland_layer_update_mask_str(mrp_wayland_layer_update_mask_t
+ mask);
+const char *mrp_wayland_layer_type_str(mrp_wayland_layer_type_t type);
+
+void mrp_wayland_layer_set_scripting_data(mrp_wayland_layer_t *layer,
+ void *data);
+
+
+#endif /* __MURPHY_WAYLAND_LAYER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "output.h"
+#include "area.h"
+#include "scripting-wayland.h"
+
+typedef struct {
+ mrp_wayland_output_t *output;
+ int count;
+} output_iterator_helper_t;
+
+static bool output_constructor(mrp_wayland_t *, mrp_wayland_object_t *);
+
+static void geometry_callback(void *, struct wl_output *,
+ int32_t,int32_t, int32_t,int32_t, int32_t,
+ const char *, const char *, int32_t);
+static void mode_callback(void *, struct wl_output *, uint32_t,
+ int32_t,int32_t, int32_t);
+static void done_callback(void *, struct wl_output *);
+static void scale_callback(void *, struct wl_output *, int32_t);
+
+static void check_if_ready(mrp_wayland_t *, mrp_wayland_output_t *);
+static int print_area(void *, void *, void *);
+
+
+bool mrp_wayland_output_register(mrp_wayland_t *wl)
+{
+ mrp_wayland_factory_t factory;
+
+ factory.size = sizeof(mrp_wayland_output_t);
+ factory.interface = &wl_output_interface;
+ factory.constructor = output_constructor;
+ factory.destructor = NULL;
+
+ mrp_wayland_register_interface(wl, &factory);
+
+ return true;
+}
+
+mrp_wayland_output_t *mrp_wayland_output_find(mrp_wayland_t *wl,uint32_t index)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ return (mrp_wayland_output_t *)mrp_htbl_lookup(wl->outputs, &index);
+}
+
+void mrp_wayland_output_request(mrp_wayland_t *wl,
+ mrp_wayland_output_update_t *u)
+{
+ mrp_wayland_output_t *out;
+ mrp_wayland_output_update_mask_t mask;
+ char buf[4096];
+
+ MRP_ASSERT(wl && u, "invalid arguments");
+
+ if (!(u->mask & MRP_WAYLAND_OUTPUT_INDEX_MASK) ||
+ !(out = mrp_wayland_output_find(wl, u->index)))
+ {
+ mrp_debug("can't find output %u: request rejected", u->index);
+ return;
+ }
+
+ mrp_wayland_output_request_print(u, buf, sizeof(buf));
+ mrp_debug("request for output %u update:%s", out->index, buf);
+
+ mask = 0;
+
+ if ((u->mask & MRP_WAYLAND_OUTPUT_OUTPUTID_MASK)) {
+ if (u->outputid < 0) {
+ mrp_log_error("system-controller: refuse to set output ID %d",
+ u->outputid);
+ }
+ else {
+ if (u->outputid != out->outputid) {
+ mask |= MRP_WAYLAND_OUTPUT_OUTPUTID_MASK;
+ out->outputid = u->outputid;
+ }
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_OUTPUT_NAME_MASK)) {
+ if (u->outputname && strcmp(u->outputname, out->outputname)) {
+ mask |= MRP_WAYLAND_OUTPUT_NAME_MASK;
+ mrp_free(out->outputname);
+ out->outputname = mrp_strdup(u->outputname);
+ }
+ }
+
+ if (wl->output_update_callback) {
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_USER_REQUEST,
+ mask, out);
+ }
+}
+
+static bool output_constructor(mrp_wayland_t *wl, mrp_wayland_object_t *obj)
+{
+ static uint32_t index;
+ static struct wl_output_listener listener = {
+ .geometry = geometry_callback,
+ .mode = mode_callback,
+ .done = done_callback,
+ .scale = scale_callback
+ };
+
+ char name[256];
+ char buf[4096];
+
+ mrp_wayland_output_t *out = (mrp_wayland_output_t *)obj;
+ int sts;
+
+ MRP_ASSERT(out, "invalid argument");
+
+ snprintf(name, sizeof(name), "%s:%u", wl->display_name, index);
+
+ out->index = index++;
+ out->outputid = -1;
+ out->outputname = mrp_strdup(name);
+
+ if (!mrp_htbl_insert(wl->outputs, &out->index, out)) {
+ mrp_log_error("failed to create output: already exists");
+ mrp_free(out);
+ return NULL;
+ }
+
+ sts = wl_output_add_listener((struct wl_output *)out->proxy,&listener,out);
+
+ if (sts < 0)
+ mrp_log_error("failed to add listener to output %d", out->index);
+ else {
+ if (wl->create_scripting_outputs) {
+ out->scripting_data =
+ mrp_wayland_scripting_output_create_from_c(NULL, out);
+ }
+
+ mrp_wayland_output_print(out, MRP_WAYLAND_OUTPUT_NAME_MASK,
+ buf, sizeof(buf));
+ mrp_debug("output %u created%s", out->index, buf);
+
+ if (wl->output_update_callback) {
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_CREATE,
+ MRP_WAYLAND_OUTPUT_NAME_MASK, out);
+ }
+ }
+
+ return (sts < 0) ? false : true;
+}
+
+static void geometry_callback(void *data,
+ struct wl_output *wl_output,
+ int32_t pixel_x,
+ int32_t pixel_y,
+ int32_t physical_width,
+ int32_t physical_height,
+ int32_t subpixel,
+ const char *make,
+ const char *model,
+ int32_t transform)
+{
+#define UPDATE_INTEGER_FIELD(_f,_m) \
+ if (out->_f != _f) { \
+ mask |= MRP_WAYLAND_OUTPUT_ ## _m ## _MASK; \
+ out->_f = _f; \
+ }
+#define UPDATE_STRING_FIELD(_f,_m) \
+ if (!out->_f || strcmp(out->_f, _f)) { \
+ mrp_free((void *)out->_f); \
+ mask |= MRP_WAYLAND_OUTPUT_ ## _m ## _MASK; \
+ out->_f = mrp_strdup(_f ? _f : "<unknown>"); \
+ }
+
+ mrp_wayland_output_t *out = (mrp_wayland_output_t *)data;
+ mrp_wayland_output_update_mask_t mask = 0;
+ mrp_wayland_t *wl;
+ uint32_t rotate;
+ bool flip;
+ int32_t width, height;
+ char buf[4096];
+
+ MRP_UNUSED(transform);
+
+ MRP_ASSERT(out && out->interface && out->interface->wl,"invalid argument");
+ MRP_ASSERT(wl_output == (struct wl_output *)out->proxy,
+ "confused with data structures");
+
+ wl = out->interface->wl;
+
+ mrp_debug("x=%d y=%d width=%d height=%d subpixel=%d make='%s' model='%s' "
+ "transorm=%d", pixel_x,pixel_y, physical_width,physical_height,
+ subpixel, make ? make : "", model ? model : "");
+
+ switch (transform) {
+ default:
+ case WL_OUTPUT_TRANSFORM_NORMAL: rotate = 0; flip = false; break;
+ case WL_OUTPUT_TRANSFORM_90: rotate = 90; flip = false; break;
+ case WL_OUTPUT_TRANSFORM_180: rotate = 180; flip = false; break;
+ case WL_OUTPUT_TRANSFORM_270: rotate = 270; flip = false; break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED: rotate = 0; flip = true; break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90: rotate = 90; flip = true; break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180: rotate = 180; flip = true; break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270: rotate = 270; flip = true; break;
+ };
+
+ UPDATE_INTEGER_FIELD (pixel_x, PIXEL_X);
+ UPDATE_INTEGER_FIELD (pixel_y, PIXEL_Y);
+ UPDATE_INTEGER_FIELD (physical_width, PHYSICAL_WIDTH);
+ UPDATE_INTEGER_FIELD (physical_height, PHYSICAL_HEIGHT);
+ UPDATE_INTEGER_FIELD (subpixel, SUBPIXEL);
+ UPDATE_STRING_FIELD (make, MAKE);
+ UPDATE_STRING_FIELD (model, MODEL);
+ UPDATE_INTEGER_FIELD (rotate, ROTATE);
+ UPDATE_INTEGER_FIELD (flip, FLIP);
+
+ if (rotate == 90 || rotate == 270) {
+ if (out->pixel_width > 0 && out->pixel_height > 0) {
+ width = out->pixel_height;
+ height = out->pixel_width;
+
+ UPDATE_INTEGER_FIELD (width, WIDTH);
+ UPDATE_INTEGER_FIELD (height, HEIGHT);
+ }
+ }
+
+ mrp_wayland_output_print(out, mask, buf,sizeof(buf));
+ mrp_debug("output %u configure%s", out->index, buf);
+
+ if (wl->output_update_callback)
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_CONFIGURE, mask,out);
+
+ check_if_ready(wl, out);
+
+#undef UPDATE_STRING_FIELD
+#undef UPDATE_INTEGER_FIELD
+}
+
+static void mode_callback(void *data,
+ struct wl_output *wl_output,
+ uint32_t flags,
+ int32_t pixel_width,
+ int32_t pixel_height,
+ int32_t refresh)
+{
+#define UPDATE_INTEGER_FIELD(_f,_m) \
+ if (out->_f != _f) { \
+ mask |= MRP_WAYLAND_OUTPUT_ ## _m ## _MASK; \
+ out->_f = _f; \
+ }
+#define UPDATE_STRING_FIELD(_f,_m) \
+ if (!out->_f || strcmp(out->_f, _f)) { \
+ mrp_free((void *)out->_f); \
+ mask |= MRP_WAYLAND_OUTPUT_ ## _m ## _MASK; \
+ out->_f = mrp_strdup(_f ? _f : "<unknown>"); \
+ }
+
+ mrp_wayland_output_t *out = (mrp_wayland_output_t *)data;
+ mrp_wayland_output_update_mask_t mask = 0;
+ int32_t width;
+ int32_t height;
+ mrp_wayland_t *wl;
+
+ MRP_ASSERT(out && out->interface && out->interface->wl,"invalid argument");
+ MRP_ASSERT(wl_output == (struct wl_output *)out->proxy,
+ "confused with data structures");
+
+ wl = out->interface->wl;
+
+ mrp_debug("flags=0x%x width=%d height=%d refresh=%d",
+ flags, pixel_width,pixel_height, refresh);
+
+ if (out->rotate == 90 || out->rotate == 270) {
+ width = pixel_height;
+ height = pixel_width;
+ }
+ else {
+ width = pixel_width;
+ height = pixel_height;
+ }
+
+ if (!(flags & WL_OUTPUT_MODE_CURRENT)) {
+ mrp_debug("ignoring mode %dx%d@%d on output %u",
+ width,height, refresh/1000, out->index);
+ return;
+ }
+
+ UPDATE_INTEGER_FIELD (pixel_width, PIXEL_WIDTH);
+ UPDATE_INTEGER_FIELD (pixel_height, PIXEL_HEIGHT);
+ UPDATE_INTEGER_FIELD (width, WIDTH);
+ UPDATE_INTEGER_FIELD (height, HEIGHT);
+ UPDATE_INTEGER_FIELD (refresh, REFRESH);
+
+ if (wl->output_update_callback)
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_CONFIGURE, mask,out);
+
+ check_if_ready(wl, out);
+
+#undef UPDATE_STRING_FIELD
+#undef UPDATE_INTEGER_FIELD
+}
+
+static void done_callback(void *data, struct wl_output *wl_output)
+{
+ mrp_wayland_output_t *out = (mrp_wayland_output_t *)data;
+ mrp_wayland_t *wl;
+
+ MRP_ASSERT(out && out->interface && out->interface->wl,
+ "invalid argument");
+ MRP_ASSERT(wl_output == (struct wl_output *)out->proxy,
+ "confused with data structures");
+
+ wl = out->interface->wl;
+
+ mrp_debug("output %u update is done", out->index);
+
+ if (wl->output_update_callback)
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_DONE, -1, out);
+}
+
+static void scale_callback(void *data,
+ struct wl_output *wl_output,
+ int32_t factor)
+{
+ mrp_wayland_output_t *out = (mrp_wayland_output_t *)data;
+
+ MRP_UNUSED(factor);
+
+ MRP_ASSERT(out, "invalid argument");
+ MRP_ASSERT(wl_output == (struct wl_output *)out->proxy,
+ "confused with data structures");
+
+ mrp_debug("output %u scale:",
+ out->index);
+}
+
+static void check_if_ready(mrp_wayland_t *wl, mrp_wayland_output_t *out)
+{
+ output_iterator_helper_t helper;
+ char buf[4096];
+
+ MRP_ASSERT(wl && out, "invalid argument");
+
+ if (!out->initialized && out->width > 0 && out->height > 0 &&
+ out->physical_width > 0 && out->physical_height > 0)
+ {
+ out->initialized = true;
+
+ mrp_wayland_output_print(out, -1, buf,sizeof(buf));
+ mrp_log_info("system-controller: found output %u%s", out->index, buf);
+
+ if (wl->output_update_callback)
+ wl->output_update_callback(wl, MRP_WAYLAND_OUTPUT_DONE, -1, out);
+
+ /* list the areas that belong to this output */
+ memset(&helper, 0, sizeof(helper));
+ helper.output = out;
+
+ mrp_htbl_foreach(wl->areas, print_area, &helper);
+
+ if (helper.count == 0) {
+ mrp_log_info("system-controller: output '%s' has no areas",
+ out->outputname);
+ }
+ }
+}
+
+static int print_area(void *key, void *object, void *ud)
+{
+ output_iterator_helper_t *helper = (output_iterator_helper_t *)ud;
+ mrp_wayland_area_t *area = (mrp_wayland_area_t *)object;
+ char buf[4096];
+
+ MRP_UNUSED(key);
+
+ MRP_ASSERT(helper && helper->output && area,
+ "confused with data structures");
+
+ if (helper->output == area->output) {
+ helper->count++;
+
+ mrp_wayland_area_print(area, -1, buf, sizeof(buf));
+ mrp_log_info("system-controller: area for output '%s'%s",
+ helper->output->outputname, buf);
+ }
+
+ return MRP_HTBL_ITER_MORE;
+}
+
+size_t mrp_wayland_output_print(mrp_wayland_output_t *out,
+ mrp_wayland_output_update_mask_t mask,
+ char *buf,
+ size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ char *p, *e;
+
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_OUTPUT_OUTPUTID_MASK))
+ PRINT("id: %d", out->outputid);
+ if ((mask & MRP_WAYLAND_OUTPUT_NAME_MASK))
+ PRINT("outputname: '%s'", out->outputname ? out->outputname : "");
+ if ((mask & MRP_WAYLAND_OUTPUT_PIXEL_POSITION_MASK))
+ PRINT("pixel_position: %d,%d", out->pixel_x, out->pixel_y);
+ if ((mask & MRP_WAYLAND_OUTPUT_PHYSICAL_SIZE_MASK))
+ PRINT("physical_size: %dx%d mm", out->physical_width,
+ out->physical_height);
+ if ((mask & MRP_WAYLAND_OUTPUT_PIXEL_SIZE_MASK))
+ PRINT("pixel_size: %dx%d pixel", out->pixel_width, out->pixel_height);
+ if ((mask & MRP_WAYLAND_OUTPUT_SIZE_MASK))
+ PRINT("size: %dx%d pixel", out->width, out->height);
+ if ((mask & MRP_WAYLAND_OUTPUT_SUBPIXEL_MASK))
+ PRINT("subpixel: %d", out->subpixel);
+ if ((mask & MRP_WAYLAND_OUTPUT_ROTATE_MASK))
+ PRINT("rotate: %u degrees", out->rotate);
+ if ((mask & MRP_WAYLAND_OUTPUT_FLIP_MASK))
+ PRINT("flip: %s", out->flip ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_OUTPUT_MONITOR_MASK)) {
+ PRINT("monitor: %s manufactured by %s",
+ out->model ? out->model: "<unknown>",
+ out->make ? out->make : "<unknown>");
+ }
+ if ((mask & MRP_WAYLAND_OUTPUT_REFRESH_MASK))
+ PRINT("refresh: %d Hz", out->refresh / 1000);
+
+ return p - buf;
+
+#undef PRINT
+}
+
+
+size_t mrp_wayland_output_request_print(mrp_wayland_output_update_t *u,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ mrp_wayland_output_update_mask_t mask;
+ char *p, *e;
+
+ mask = u->mask;
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_OUTPUT_NAME_MASK))
+ PRINT("outputname: '%s'", u->outputname);
+
+ return p - buf;
+
+#undef PRINT
+}
+
+
+const char *
+mrp_wayland_output_update_mask_str(mrp_wayland_output_update_mask_t mask)
+{
+ switch (mask) {
+ case MRP_WAYLAND_OUTPUT_INDEX_MASK: return "index";
+ case MRP_WAYLAND_OUTPUT_OUTPUTID_MASK: return "id";
+ case MRP_WAYLAND_OUTPUT_NAME_MASK: return "name";
+ case MRP_WAYLAND_OUTPUT_PIXEL_X_MASK: return "pixel_x";
+ case MRP_WAYLAND_OUTPUT_PIXEL_Y_MASK: return "pixel_y";
+ case MRP_WAYLAND_OUTPUT_PIXEL_POSITION_MASK: return "pixel_position";
+ case MRP_WAYLAND_OUTPUT_PHYSICAL_WIDTH_MASK: return "physical_width";
+ case MRP_WAYLAND_OUTPUT_PHYSICAL_HEIGHT_MASK: return "physical_height";
+ case MRP_WAYLAND_OUTPUT_PHYSICAL_SIZE_MASK: return "physical_size";
+ case MRP_WAYLAND_OUTPUT_PIXEL_WIDTH_MASK: return "pixel_width";
+ case MRP_WAYLAND_OUTPUT_PIXEL_HEIGHT_MASK: return "pixel_height";
+ case MRP_WAYLAND_OUTPUT_PIXEL_SIZE_MASK: return "pixel_size";
+ case MRP_WAYLAND_OUTPUT_WIDTH_MASK: return "width";
+ case MRP_WAYLAND_OUTPUT_HEIGHT_MASK: return "height";
+ case MRP_WAYLAND_OUTPUT_SIZE_MASK: return "size";
+ case MRP_WAYLAND_OUTPUT_SUBPIXEL_MASK: return "subpixel";
+ case MRP_WAYLAND_OUTPUT_MAKE_MASK: return "make";
+ case MRP_WAYLAND_OUTPUT_MODEL_MASK: return "model";
+ case MRP_WAYLAND_OUTPUT_ROTATE_MASK: return "rotate";
+ case MRP_WAYLAND_OUTPUT_FLIP_MASK: return "flip";
+ case MRP_WAYLAND_OUTPUT_REFRESH_MASK: return "refresh";
+ default: return "<unknown>";
+ }
+}
+
+void mrp_wayland_output_set_scripting_data(mrp_wayland_output_t *out,
+ void *data)
+{
+ MRP_ASSERT(out, "Invalid Argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ out->scripting_data = data;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_OUTPUT_H__
+#define __MURPHY_WAYLAND_OUTPUT_H__
+
+#include "wayland/wayland.h"
+
+enum mrp_wayland_output_operation_e {
+ MRP_WAYLAND_OUTPUT_OPERATION_NONE = 0,
+ MRP_WAYLAND_OUTPUT_CREATE, /* 1 */
+ MRP_WAYLAND_OUTPUT_DESTROY, /* 2 */
+ MRP_WAYLAND_OUTPUT_CONFIGURE, /* 3 */
+ MRP_WAYLAND_OUTPUT_MODE, /* 4 */
+ MRP_WAYLAND_OUTPUT_DONE, /* 5 */
+ MRP_WAYLAND_OUTPUT_USER_REQUEST, /* 6 */
+};
+
+
+struct mrp_wayland_output_s {
+ MRP_WAYLAND_OBJECT_COMMON;
+
+ uint32_t index;
+ int32_t outputid;
+ char *outputname;
+
+ int32_t pixel_x, pixel_y;
+ int32_t physical_width, physical_height;
+ int32_t pixel_width, pixel_height;
+ int32_t width, height; /* pixel measures after rotation & flip */
+ int32_t subpixel;
+ char *make;
+ char *model;
+ uint32_t rotate;
+ bool flip;
+ int32_t refresh;
+
+ bool initialized;
+
+ void *scripting_data;
+};
+
+enum mrp_wayland_output_update_mask_e {
+ MRP_WAYLAND_OUTPUT_INDEX_MASK = 0x00001,
+ MRP_WAYLAND_OUTPUT_OUTPUTID_MASK = 0x00002,
+ MRP_WAYLAND_OUTPUT_NAME_MASK = 0x00004,
+ MRP_WAYLAND_OUTPUT_PIXEL_X_MASK = 0x00008,
+ MRP_WAYLAND_OUTPUT_PIXEL_Y_MASK = 0x00010,
+ MRP_WAYLAND_OUTPUT_PIXEL_POSITION_MASK = 0x00018,
+ MRP_WAYLAND_OUTPUT_PHYSICAL_WIDTH_MASK = 0x00020,
+ MRP_WAYLAND_OUTPUT_PHYSICAL_HEIGHT_MASK = 0x00040,
+ MRP_WAYLAND_OUTPUT_PHYSICAL_SIZE_MASK = 0x00060,
+ MRP_WAYLAND_OUTPUT_PIXEL_WIDTH_MASK = 0x00080,
+ MRP_WAYLAND_OUTPUT_PIXEL_HEIGHT_MASK = 0x00100,
+ MRP_WAYLAND_OUTPUT_PIXEL_SIZE_MASK = 0x00180,
+ MRP_WAYLAND_OUTPUT_WIDTH_MASK = 0x00200,
+ MRP_WAYLAND_OUTPUT_HEIGHT_MASK = 0x00400,
+ MRP_WAYLAND_OUTPUT_SIZE_MASK = 0x00600,
+ MRP_WAYLAND_OUTPUT_SUBPIXEL_MASK = 0x00800,
+ MRP_WAYLAND_OUTPUT_MAKE_MASK = 0x01000,
+ MRP_WAYLAND_OUTPUT_MODEL_MASK = 0x02000,
+ MRP_WAYLAND_OUTPUT_MONITOR_MASK = 0x03000,
+ MRP_WAYLAND_OUTPUT_ROTATE_MASK = 0x04000,
+ MRP_WAYLAND_OUTPUT_FLIP_MASK = 0x08000,
+ MRP_WAYLAND_OUTPUT_REFRESH_MASK = 0x10000,
+
+ MRP_WAYLAND_OUTPUT_END_MASK = 0x20000
+};
+
+struct mrp_wayland_output_update_s {
+ mrp_wayland_output_update_mask_t mask;
+ uint32_t index;
+ int32_t outputid;
+ const char *outputname;
+};
+
+bool mrp_wayland_output_register(mrp_wayland_t *wl);
+
+mrp_wayland_output_t *mrp_wayland_output_find(mrp_wayland_t *wl,
+ uint32_t index);
+
+void mrp_wayland_output_request(mrp_wayland_t *wl,
+ mrp_wayland_output_update_t *u);
+
+size_t mrp_wayland_output_print(mrp_wayland_output_t *out,
+ mrp_wayland_output_update_mask_t mask,
+ char *buf, size_t len);
+
+size_t mrp_wayland_output_request_print(mrp_wayland_output_update_t *u,
+ char *buf, size_t len);
+
+const char *mrp_wayland_output_update_mask_str(
+ mrp_wayland_output_update_mask_t mask);
+
+void mrp_wayland_output_set_scripting_data(mrp_wayland_output_t *out,
+ void *data);
+
+#endif /* __MURPHY_WAYLAND_OUTPUT_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "animation.h"
+
+#define ANIMATION_CLASS MRP_LUA_CLASS_SIMPLE(animation)
+
+typedef struct scripting_animation_s scripting_animation_t;
+typedef struct animation_def_s animation_def_t;
+
+struct scripting_animation_s {
+ mrp_wayland_animation_t *anims;
+};
+
+
+struct animation_def_s {
+ const char *name;
+ int32_t time;
+};
+
+
+static int animation_create(lua_State *);
+static int animation_getfield(lua_State *);
+static int animation_setfield(lua_State *);
+static void animation_destroy(void *);
+
+static scripting_animation_t *animation_check(lua_State *, int);
+static int animation_push_type(lua_State *L, mrp_wayland_animation_t *,
+ mrp_wayland_animation_type_t);
+
+static animation_def_t *animation_def_check(lua_State *, int);
+static void animation_def_free(animation_def_t *);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ animation, /* class name */
+ scripting_animation_t, /* userdata type */
+ animation_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (animation_create)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (animation_create)
+ MRP_LUA_OVERRIDE_GETFIELD (animation_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (animation_setfield)
+ )
+);
+
+
+void mrp_wayland_scripting_animation_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, ANIMATION_CLASS);
+}
+
+mrp_wayland_animation_t *mrp_wayland_scripting_animation_check(lua_State *L,
+ int idx)
+{
+ scripting_animation_t *an;
+
+ MRP_ASSERT(L, "invalid argument");
+
+ if ((an = animation_check(L, idx)))
+ return an->anims;
+
+ return NULL;
+}
+
+
+mrp_wayland_animation_t *mrp_wayland_scripting_animation_unwrap(void *void_an)
+{
+ scripting_animation_t *an = (scripting_animation_t *)void_an;
+
+ if (an && mrp_lua_get_object_classdef(an) == ANIMATION_CLASS)
+ return an->anims;
+
+ return NULL;
+}
+
+
+static int animation_create(lua_State *L)
+{
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_animation_t *an;
+ mrp_wayland_animation_t *anims;
+ animation_def_t *hide = NULL;
+ animation_def_t *show = NULL;
+ animation_def_t *move = NULL;
+ animation_def_t *resize = NULL;
+
+ MRP_LUA_ENTER;
+
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ switch (mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen)) {
+ case HIDE: hide = animation_def_check(L, -1); break;
+ case SHOW: show = animation_def_check(L, -1); break;
+ case MOVE: move = animation_def_check(L, -1); break;
+ case RESIZE: resize = animation_def_check(L, -1); break;
+ default: luaL_error(L, "bad field '%s'", fldnam); break;
+ }
+ }
+
+ anims = mrp_wayland_animation_create();
+
+ if (hide) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_HIDE,
+ hide->name, hide->time);
+ mrp_free(hide);
+ }
+ if (show) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_SHOW,
+ show->name, show->time);
+ animation_def_free(show);
+ }
+ if (move) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_MOVE,
+ move->name, move->time);
+ animation_def_free(move);
+ }
+ if (resize) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_RESIZE,
+ resize->name, resize->time);
+ animation_def_free(resize);
+ }
+
+ an = (scripting_animation_t *)mrp_lua_create_object(L, ANIMATION_CLASS,
+ NULL, 0);
+ if (!an)
+ luaL_error(L, "can't create animation");
+
+ an->anims = anims;
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int animation_getfield(lua_State *L)
+{
+ scripting_animation_t *an;
+ mrp_wayland_animation_t *anims;
+ mrp_wayland_animation_type_t type;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ an = animation_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 1);
+
+ if (!an || !(anims = an->anims))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case HIDE: type = MRP_WAYLAND_ANIMATION_HIDE; goto push;
+ case SHOW: type = MRP_WAYLAND_ANIMATION_SHOW; goto push;
+ case MOVE: type = MRP_WAYLAND_ANIMATION_MOVE; goto push;
+ case RESIZE: type = MRP_WAYLAND_ANIMATION_RESIZE; goto push;
+ push: animation_push_type(L, anims, type); break;
+ default: lua_pushnil(L); break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int animation_setfield(lua_State *L)
+{
+ scripting_animation_t *an;
+ mrp_wayland_animation_t *anims;
+ mrp_wayland_scripting_field_t fld;
+ animation_def_t *def;
+ mrp_wayland_animation_type_t type;
+
+ MRP_LUA_ENTER;
+
+ an = animation_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+ def = animation_def_check(L, 3);
+
+ lua_pop(L, 2);
+
+ if (an && (anims = an->anims) && def) {
+ switch (fld) {
+ case HIDE: type = MRP_WAYLAND_ANIMATION_HIDE; goto setfield;
+ case SHOW: type = MRP_WAYLAND_ANIMATION_SHOW; goto setfield;
+ case MOVE: type = MRP_WAYLAND_ANIMATION_MOVE; goto setfield;
+ case RESIZE: type = MRP_WAYLAND_ANIMATION_RESIZE; goto setfield;
+ default: break;
+ setfield:
+ mrp_wayland_animation_set(anims, type, def->name, def->time);
+ break;
+ }
+ mrp_free(def);
+ }
+
+ MRP_LUA_LEAVE(0);
+}
+
+static void animation_destroy(void *data)
+{
+ scripting_animation_t *an = (scripting_animation_t *)data;
+
+ if (an) {
+ mrp_wayland_animation_destroy(an->anims);
+ }
+}
+
+
+static scripting_animation_t *animation_check(lua_State *L, int idx)
+{
+ return (scripting_animation_t*)mrp_lua_check_object(L,ANIMATION_CLASS,idx);
+}
+
+static int animation_push_type(lua_State *L, mrp_wayland_animation_t *anims,
+ mrp_wayland_animation_type_t type)
+{
+ mrp_wayland_animation_t *a;
+
+ MRP_LUA_ENTER;
+
+ if (!anims || type < 0 || type >= MRP_WAYLAND_ANIMATION_MAX)
+ lua_pushnil(L);
+ else {
+ a = anims + type;
+
+ if (type != a->type || !a->name || a->time < 1)
+ lua_pushnil(L);
+ else {
+ lua_createtable(L, 2, 0);
+
+ lua_pushinteger(L, 1);
+ lua_pushstring(L, a->name);
+ lua_settable(L, -3);
+
+ lua_pushinteger(L, 2);
+ lua_pushinteger(L, a->time);
+ lua_settable(L, -3);
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static animation_def_t *animation_def_check(lua_State *L, int t)
+{
+ animation_def_t *def;
+ size_t i, tlen;
+ const char *name = NULL;
+ int16_t time = -1;
+
+ t = (t < 0) ? lua_gettop(L) + t + 1 : t;
+
+ luaL_checktype(L, t, LUA_TTABLE);
+
+ if ((tlen = lua_objlen(L, t)) != 2) {
+ luaL_error(L,"invalid animation definition: "
+ "expected 2 fields, got %u", tlen);
+ }
+
+ for (i = 0; i < tlen; i++) {
+ lua_pushinteger(L, (int)(i+1));
+ lua_gettable(L, t);
+
+ if (i == 0)
+ name = lua_isstring(L,-1) ? mrp_strdup(lua_tostring(L,-1)) : NULL;
+ else
+ time = lua_tointeger(L,-1);
+
+ lua_pop(L, 1);
+ }
+
+ if (!name || time < 1)
+ return NULL;
+
+ if (!(def = mrp_allocz(sizeof(animation_def_t))))
+ mrp_free((void *)name);
+ else {
+ def->name = name;
+ def->time = time;
+ }
+
+ return def;
+}
+
+
+static void animation_def_free(animation_def_t *def)
+{
+ if (def) {
+ mrp_free((void *)def->name);
+ mrp_free(def);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "area.h"
+#include "output.h"
+
+#define AREA_CLASS MRP_LUA_CLASS_SIMPLE(area)
+#define ALIGN_MASK_CLASS MRP_LUA_CLASS_SIMPLE(align_mask)
+
+#define ALIGN_MASK_INVALID (~(uint32_t)0)
+
+
+typedef struct scripting_area_s scripting_area_t;
+typedef struct scripting_align_mask_s scripting_align_mask_t;
+
+
+struct scripting_area_s {
+ mrp_wayland_area_t *area;
+ const char *id;
+};
+
+struct scripting_align_mask_s {
+ uint32_t mask;
+};
+
+static int area_create_from_lua(lua_State *);
+static int area_getfield(lua_State *);
+static int area_setfield(lua_State *);
+static int area_stringify(lua_State *);
+static void area_destroy_from_lua(void *);
+
+static scripting_area_t *area_check(lua_State *, int);
+
+static int align_mask_create_from_lua(lua_State *);
+static int align_mask_getfield(lua_State *);
+static int align_mask_setfield(lua_State *);
+static int align_mask_stringify(lua_State *);
+static void align_mask_destroy(void *);
+
+static scripting_align_mask_t *align_mask_check(lua_State *, int);
+
+static uint32_t get_align_mask(mrp_wayland_scripting_field_t);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ area, /* class name */
+ scripting_area_t, /* userdata type */
+ area_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (area_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (area_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (area_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (area_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (area_stringify)
+ )
+);
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ align_mask, /* class name */
+ scripting_align_mask_t , /* userdata type */
+ align_mask_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (align_mask_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (align_mask_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (align_mask_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (align_mask_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (align_mask_stringify)
+ )
+);
+
+void mrp_wayland_scripting_area_init(lua_State *L)
+{
+ mrp_lua_create_object_class(L, AREA_CLASS);
+ mrp_lua_create_object_class(L, ALIGN_MASK_CLASS);
+}
+
+
+mrp_wayland_area_t *mrp_wayland_scripting_area_check(lua_State *L, int idx)
+{
+ scripting_area_t *a;
+ mrp_wayland_area_t *area;
+
+ if ((a = area_check(L, idx)) && (area = a->area)) {
+ MRP_ASSERT(area->scripting_data == (void *)a,
+ "confused with data structures");
+ return area;
+ }
+
+ return NULL;
+}
+
+mrp_wayland_area_t *mrp_wayland_scripting_area_unwrap(void *void_a)
+{
+ scripting_area_t *a = (scripting_area_t *)void_a;
+
+ if (a && mrp_lua_get_object_classdef(a) == AREA_CLASS)
+ return a->area;
+
+ return NULL;
+}
+
+int mrp_wayland_scripting_area_push(lua_State *L, mrp_wayland_area_t *area)
+{
+ MRP_LUA_ENTER;
+
+ if (!area || !area->scripting_data)
+ lua_pushnil(L);
+ else
+ mrp_lua_push_object(L, area->scripting_data);
+
+ MRP_LUA_LEAVE(1);
+}
+
+void *mrp_wayland_scripting_area_create_from_c(lua_State *L,
+ mrp_wayland_area_t *area)
+{
+ scripting_area_t *a;
+ char *id;
+ char buf[2048];
+
+ MRP_ASSERT(area && area->fullname, "invald argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting area %d: LUA is "
+ "not initialized", area->areaid);
+ return NULL;
+ }
+
+ id = mrp_wayland_scripting_canonical_name(area->fullname, buf,sizeof(buf));
+ a = (scripting_area_t*)mrp_lua_create_object(L, AREA_CLASS, id, 0);
+
+ if (!a) {
+ mrp_log_error("can't create scripting area %d: LUA object "
+ "creation failed", area->areaid);
+ return NULL;
+ }
+
+ a->area = area;
+ a->id = mrp_strdup(id);
+
+ return a;
+}
+
+void mrp_wayland_scripting_area_destroy_from_c(lua_State *L,
+ mrp_wayland_area_t *area)
+{
+ scripting_area_t *a;
+
+ MRP_ASSERT(area, "invalid argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't destroy scripting area %d: LUA is "
+ "not initialized", area->areaid);
+ area->scripting_data = NULL;
+ return;
+ }
+
+ if ((a = area->scripting_data)) {
+ mrp_debug("destroy scripting area %d", area->areaid);
+
+ a->area = NULL;
+
+ mrp_lua_destroy_object(L, a->id,0, area->scripting_data);
+
+ area->scripting_data = NULL;
+ }
+}
+
+
+static int area_create_from_lua(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ luaL_error(L, "area from lua can only be created via the 'areas' field "
+ "of 'outputs' window_manager property");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int area_getfield(lua_State *L)
+{
+ scripting_area_t *a;
+ mrp_wayland_area_t *area;
+ const char *fldnam;
+ mrp_wayland_scripting_field_t fld;
+ char buf[32];
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ a = area_check(L, 1);
+
+ if (!a || !(area = a->area))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case ID:
+ lua_pushinteger(L, area->areaid);
+ break;
+
+ case OUTPUT:
+ if (!area->output)
+ lua_pushnil(L);
+ else if (area->output->outputname)
+ lua_pushstring(L, area->output->outputname);
+ else {
+ snprintf(buf, sizeof(buf), "%d", area->output->outputid);
+ lua_pushstring(L, buf);
+ }
+ break;
+
+ case POS_X:
+ lua_pushinteger(L, area->x);
+ break;
+ case POS_Y:
+ lua_pushinteger(L, area->y);
+ break;
+
+ case WIDTH:
+ lua_pushinteger(L, area->width);
+ break;
+ case HEIGHT:
+ lua_pushinteger(L, area->height);
+ break;
+
+ case KEEPRATIO:
+ lua_pushboolean(L, area->keepratio);
+ break;
+
+ case ALIGN:
+ mrp_wayland_scripting_align_mask_create_from_c(L, area->align);
+ break;
+
+ default:
+ lua_pushnil(L);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int area_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ area_check(L, 1);
+ luaL_error(L, "area objects are read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int area_stringify(lua_State *L)
+{
+#define ALL_FIELDS (MRP_WAYLAND_AREA_END_MASK - 1)
+
+ scripting_area_t *a;
+ mrp_wayland_area_t *area;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ a = area_check(L, 1);
+
+ if (!a || !(area = a->area))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "area %d", area->areaid);
+ p += mrp_wayland_area_print(area, ALL_FIELDS, p, e-p);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+
+#undef ALL_FIELDS
+}
+
+static void area_destroy_from_lua(void *data)
+{
+ scripting_area_t *a = (scripting_area_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (a && a->area) {
+ mrp_wayland_area_set_scripting_data(a->area, NULL);
+ mrp_free((void *)a->id);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_area_t *area_check(lua_State *L, int idx)
+{
+ return (scripting_area_t *)mrp_lua_check_object(L, AREA_CLASS, idx);
+}
+
+
+void *mrp_wayland_scripting_align_mask_create_from_c(lua_State *L,
+ uint32_t mask)
+{
+ scripting_align_mask_t *um;
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting window mask: "
+ "LUA is not initialized");
+ return NULL;
+ }
+
+ um = (scripting_align_mask_t *)mrp_lua_create_object(L, ALIGN_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ mrp_log_error("can't create align_mask");
+ else
+ um->mask = mask;
+
+ return um;
+}
+
+
+static int align_mask_create_from_lua(lua_State *L)
+{
+ size_t fldnamlen;
+ const char *fldnam, *valstr;
+ scripting_align_mask_t *um;
+ mrp_wayland_scripting_field_t fld, val;
+ uint32_t m;
+ uint32_t mask = 0;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ fld = mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ switch (fld) {
+
+ case MASK:
+ mask = lua_tointeger(L, -1);
+ break;
+
+ case HORIZONTAL:
+ val = mrp_wayland_scripting_field_check(L, -1, &valstr);
+ if ((m = get_align_mask(val)) == ALIGN_MASK_INVALID ||
+ (m & ~MRP_WAYLAND_AREA_ALIGN_HMASK))
+ luaL_error(L, "invalid horizontal alingment '%s'", valstr);
+ else {
+ mask &= ~MRP_WAYLAND_AREA_ALIGN_HMASK;
+ mask |= m;
+ }
+ break;
+
+ case VERTICAL:
+ val = mrp_wayland_scripting_field_check(L, -1, &valstr);
+ if ((m = get_align_mask(val)) == ALIGN_MASK_INVALID ||
+ (m & ~MRP_WAYLAND_AREA_ALIGN_VMASK))
+ luaL_error(L, "invalid vertical alingment '%s'", valstr);
+ else {
+ mask &= ~MRP_WAYLAND_AREA_ALIGN_VMASK;
+ mask |= m;
+ }
+ break;
+
+ default:
+ if ((m = get_align_mask(fld)) == ALIGN_MASK_INVALID)
+ luaL_error(L, "bad field '%s'", fldnam);
+ else {
+ mask &= ~((m & MRP_WAYLAND_AREA_ALIGN_HMASK) ?
+ MRP_WAYLAND_AREA_ALIGN_HMASK :
+ MRP_WAYLAND_AREA_ALIGN_VMASK);
+ if (lua_toboolean(L, -1))
+ mask |= m;
+ }
+ break;
+ }
+ }
+
+ um = (scripting_align_mask_t *)mrp_lua_create_object(L, ALIGN_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ luaL_error(L, "can't create window_mask");
+
+ um->mask = mask;
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int align_mask_getfield(lua_State *L)
+{
+ scripting_align_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+
+ MRP_LUA_ENTER;
+
+ um = align_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 1);
+
+ if (!um)
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case MASK:
+ lua_pushinteger(L, um->mask);
+ break;
+ case HORIZONTAL:
+ m = um->mask & MRP_WAYLAND_AREA_ALIGN_HMASK;
+ lua_pushstring(L, mrp_wayland_area_align_str(m));
+ break;
+ case VERTICAL:
+ m = um->mask & MRP_WAYLAND_AREA_ALIGN_VMASK;
+ lua_pushstring(L, mrp_wayland_area_align_str(m));
+ break;
+ default:
+ if ((m = get_align_mask(fld)) != ALIGN_MASK_INVALID)
+ lua_pushboolean(L, (um->mask & m) ? 1 : 0);
+ else
+ lua_pushnil(L);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int align_mask_setfield(lua_State *L)
+{
+ scripting_align_mask_t *um;
+ const char *fldstr, *valstr;
+ uint32_t m;
+ mrp_wayland_scripting_field_t fld, val;
+
+ MRP_LUA_ENTER;
+
+ um = align_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldstr);
+
+ lua_pop(L, 2);
+
+ if (um) {
+ switch (fld) {
+ case MASK:
+ um->mask = lua_tointeger(L, 3);
+ break;
+ case HORIZONTAL:
+ val = mrp_wayland_scripting_field_check(L, 3, &valstr);
+ if ((m = get_align_mask(val)) == ALIGN_MASK_INVALID ||
+ (m & ~MRP_WAYLAND_AREA_ALIGN_HMASK))
+ luaL_error(L, "invalid horizontal alingment '%s'", valstr);
+ else {
+ um->mask &= ~MRP_WAYLAND_AREA_ALIGN_HMASK;
+ um->mask |= m;
+ }
+ break;
+ case VERTICAL:
+ val = mrp_wayland_scripting_field_check(L, 3, &valstr);
+ if ((m = get_align_mask(val)) == ALIGN_MASK_INVALID ||
+ (m & ~MRP_WAYLAND_AREA_ALIGN_VMASK))
+ luaL_error(L, "invalid vertical alingment '%s'", valstr);
+ else {
+ um->mask &= ~MRP_WAYLAND_AREA_ALIGN_VMASK;
+ um->mask |= m;
+ }
+ break;
+ default:
+ if ((m = get_align_mask(fld)) == ALIGN_MASK_INVALID)
+ luaL_error(L, "invalid alignement field '%s'", fldstr);
+ else {
+ um->mask &= ~((m & MRP_WAYLAND_AREA_ALIGN_HMASK) ?
+ MRP_WAYLAND_AREA_ALIGN_HMASK :
+ MRP_WAYLAND_AREA_ALIGN_VMASK);
+ if (lua_toboolean(L, 3))
+ um->mask |= m;
+ }
+ }
+ }
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int align_mask_stringify(lua_State *L)
+{
+ scripting_align_mask_t *um;
+ uint32_t m, mask;
+ char buf[4096];
+ char *p, *e;
+ const char *name;
+
+
+ MRP_LUA_ENTER;
+
+ um = align_mask_check(L, 1);
+
+ e = (p = buf) + sizeof(buf);
+ *p = 0;
+
+ mask = um->mask;
+
+ for (m=1; mask && m < MRP_WAYLAND_AREA_ALIGN_END_MASK && p < e; m <<= 1) {
+ if ((mask & m)) {
+ mask &= ~m;
+
+ if ((name = mrp_wayland_area_align_str(m)))
+ p += snprintf(p, e-p, "%s%s", p > buf ? " | " : "", name);
+ }
+ }
+
+ lua_pushstring(L, (p > buf) ? buf : "<empty>");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static void align_mask_destroy(void *data)
+{
+ scripting_align_mask_t *um = (scripting_align_mask_t *)data;
+
+ MRP_UNUSED(um);
+}
+
+static scripting_align_mask_t *align_mask_check(lua_State *L, int idx)
+{
+ return (scripting_align_mask_t *)mrp_lua_check_object(L, ALIGN_MASK_CLASS,
+ idx);
+}
+
+
+static uint32_t get_align_mask(mrp_wayland_scripting_field_t fld)
+{
+ switch (fld) {
+ case MIDDLE: return MRP_WAYLAND_AREA_ALIGN_MIDDLE;
+ case LEFT: return MRP_WAYLAND_AREA_ALIGN_LEFT;
+ case RIGHT: return MRP_WAYLAND_AREA_ALIGN_RIGHT;
+ case TOP: return MRP_WAYLAND_AREA_ALIGN_TOP;
+ case BOTTOM: return MRP_WAYLAND_AREA_ALIGN_BOTTOM;
+ default: return ALIGN_MASK_INVALID;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "layer.h"
+
+#define LAYER_CLASS MRP_LUA_CLASS_SIMPLE(layer)
+#define LAYER_MASK_CLASS MRP_LUA_CLASS_SIMPLE(layer_mask)
+
+typedef struct scripting_layer_s scripting_layer_t;
+typedef struct scripting_layer_mask_s scripting_layer_mask_t;
+
+
+struct scripting_layer_s {
+ mrp_wayland_layer_t *layer;
+};
+
+struct scripting_layer_mask_s {
+ uint32_t mask;
+};
+
+
+static int layer_create_from_lua(lua_State *);
+static int layer_getfield(lua_State *);
+static int layer_setfield(lua_State *);
+static int layer_stringify(lua_State *);
+static void layer_destroy_from_lua(void *);
+
+static scripting_layer_t *layer_check(lua_State *, int);
+
+static int layer_mask_create_from_lua(lua_State *);
+static int layer_mask_getfield(lua_State *);
+static int layer_mask_setfield(lua_State *);
+static int layer_mask_stringify(lua_State *);
+static void layer_mask_destroy(void *);
+
+static scripting_layer_mask_t *layer_mask_check(lua_State *, int);
+
+static uint32_t get_layer_mask(mrp_wayland_scripting_field_t);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ layer, /* class name */
+ scripting_layer_t, /* userdata type */
+ layer_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (layer_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (layer_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (layer_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (layer_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (layer_stringify)
+ )
+);
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ layer_mask, /* class name */
+ scripting_layer_mask_t, /* userdata type */
+ layer_mask_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (layer_mask_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (layer_mask_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (layer_mask_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (layer_mask_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (layer_mask_stringify)
+ )
+);
+
+
+
+void mrp_wayland_scripting_layer_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, LAYER_CLASS);
+ mrp_lua_create_object_class(L, LAYER_MASK_CLASS);
+}
+
+
+mrp_wayland_layer_t *mrp_wayland_scripting_layer_check(lua_State *L, int idx)
+{
+ scripting_layer_t *l;
+ mrp_wayland_layer_t *layer;
+
+ if ((l = layer_check(L, idx)) && (layer = l->layer)) {
+ MRP_ASSERT(layer->scripting_data == (void *)l,
+ "confused with data structures");
+ return layer;
+ }
+
+ return NULL;
+}
+
+mrp_wayland_layer_t *mrp_wayland_scripting_layer_unwrap(void *void_l)
+{
+ scripting_layer_t *l = (scripting_layer_t *)void_l;
+
+ if (l && mrp_lua_get_object_classdef(l) == LAYER_CLASS)
+ return l->layer;
+
+ return NULL;
+}
+
+void *mrp_wayland_scripting_layer_create_from_c(lua_State *L,
+ mrp_wayland_layer_t *layer)
+{
+ scripting_layer_t *l;
+ mrp_wayland_t *wl;
+
+ MRP_ASSERT(layer && layer->wl, "invald argument");
+
+ wl = layer->wl;
+
+ if (!wl->create_scripting_layers)
+ l = NULL;
+ else if (layer->scripting_data)
+ l = layer->scripting_data;
+ else {
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting layer %d: LUA is "
+ "not initialized", layer->layerid);
+ return NULL;
+ }
+
+ l = (scripting_layer_t *)mrp_lua_create_object(L, LAYER_CLASS, NULL,
+ layer->layerid + 1);
+ if (!l) {
+ mrp_log_error("can't create scripting layer %d: LUA object "
+ "creation failed", layer->layerid);
+ }
+ else {
+ l->layer = layer;
+ mrp_wayland_layer_set_scripting_data(layer, l);
+ lua_pop(L, 1);
+ }
+ }
+
+ return l;
+}
+
+void mrp_wayland_scripting_layer_destroy_from_c(lua_State *L,
+ mrp_wayland_layer_t *layer)
+{
+ scripting_layer_t *l;
+
+ MRP_ASSERT(layer, "invalid argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't destroy scripting layer %d: LUA is "
+ "not initialized", layer->layerid);
+ layer->scripting_data = NULL;
+ return;
+ }
+
+ if ((l = layer->scripting_data)) {
+ mrp_debug("destroy scripting layer %d", layer->layerid);
+
+ l->layer = NULL;
+
+ mrp_lua_destroy_object(L,NULL,layer->layerid+1,layer->scripting_data);
+
+ layer->scripting_data = NULL;
+ }
+}
+
+
+static int layer_create_from_lua(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ luaL_error(L, "layer from lua can only be created via the 'layers' "
+ "window_manager property");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int layer_getfield(lua_State *L)
+{
+ scripting_layer_t *l;
+ mrp_wayland_layer_t *layer;
+ const char *fldnam;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ l = layer_check(L, 1);
+
+ if (!l || !(layer = l->layer))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case ID:
+ lua_pushinteger(L, layer->layerid);
+ break;
+
+ case NAME:
+ lua_pushstring(L, layer->name ? layer->name : "");
+ break;
+
+ case LAYERTYPE:
+ lua_pushstring(L, mrp_wayland_layer_type_str(layer->type));
+ break;
+
+ case VISIBLE:
+ lua_pushboolean(L, layer->visible);
+ break;
+
+ default:
+ lua_pushnil(L);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int layer_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ layer_check(L, 1);
+ luaL_error(L, "layer objects are read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int layer_stringify(lua_State *L)
+{
+#define ALL_FIELDS (MRP_WAYLAND_LAYER_END_MASK - 1)
+
+ scripting_layer_t *l;
+ mrp_wayland_layer_t *layer;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ l = layer_check(L, 1);
+
+ if (!l || !(layer = l->layer))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "layer %d", layer->layerid);
+ p += mrp_wayland_layer_print(layer, ALL_FIELDS, p, e-p);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+
+#undef ALL_FIELDS
+}
+
+static void layer_destroy_from_lua(void *data)
+{
+ scripting_layer_t *l = (scripting_layer_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (l && l->layer) {
+ mrp_wayland_layer_set_scripting_data(l->layer, NULL);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_layer_t *layer_check(lua_State *L, int idx)
+{
+ return (scripting_layer_t *)mrp_lua_check_object(L, LAYER_CLASS, idx);
+}
+
+void *mrp_wayland_scripting_layer_mask_create_from_c(lua_State *L,
+ uint32_t mask)
+{
+ scripting_layer_mask_t *um;
+
+ um = (scripting_layer_mask_t *)mrp_lua_create_object(L, LAYER_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ mrp_log_error("can't create layer_mask");
+ else
+ um->mask = mask;
+
+ return (void *)um;
+}
+
+static int layer_mask_create_from_lua(lua_State *L)
+{
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_layer_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+ uint32_t mask = 0;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ fld = mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (fld == MASK)
+ mask = lua_tointeger(L, -1);
+ else if ((m = get_layer_mask(fld)))
+ mask |= m;
+ else
+ luaL_error(L, "bad field '%s'", fldnam);
+ }
+
+ um = (scripting_layer_mask_t *)mrp_lua_create_object(L, LAYER_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ luaL_error(L, "can't create layer_mask");
+
+ um->mask = mask;
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int layer_mask_getfield(lua_State *L)
+{
+ scripting_layer_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+
+ MRP_LUA_ENTER;
+
+ um = layer_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 1);
+
+ if (!um)
+ lua_pushnil(L);
+ else {
+ if (fld == MASK)
+ lua_pushinteger(L, um->mask);
+ else if ((m = get_layer_mask(fld)))
+ lua_pushboolean(L, (um->mask & m) ? 1 : 0);
+ else
+ lua_pushnil(L);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int layer_mask_setfield(lua_State *L)
+{
+ scripting_layer_mask_t *um;
+ uint32_t m;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ um = layer_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 2);
+
+ if (um) {
+ if (fld == MASK)
+ um->mask = lua_tointeger(L, 3);
+ else if ((m = get_layer_mask(fld))) {
+ um->mask &= ~m;
+
+ if (lua_toboolean(L, 3))
+ um->mask |= m;
+ }
+ }
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int layer_mask_stringify(lua_State *L)
+{
+ scripting_layer_mask_t *um;
+ uint32_t m, mask;
+ char buf[4096];
+ char *p, *e;
+ const char *name;
+
+
+ MRP_LUA_ENTER;
+
+ um = layer_mask_check(L, 1);
+ e = (p = buf) + sizeof(buf);
+ *p = 0;
+
+ mask = um->mask;
+
+ for (m = 1; mask && m < MRP_WAYLAND_LAYER_END_MASK && p < e; m <<= 1) {
+ if ((mask & m)) {
+ mask &= ~m;
+
+ if ((name = mrp_wayland_layer_update_mask_str(m)))
+ p += snprintf(p, e-p, "%s%s", p > buf ? " | " : "", name);
+ }
+ }
+
+ lua_pushstring(L, (p > buf) ? buf : "<empty>");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static void layer_mask_destroy(void *data)
+{
+ scripting_layer_mask_t *um = (scripting_layer_mask_t *)data;
+
+ MRP_UNUSED(um);
+}
+
+
+static scripting_layer_mask_t *layer_mask_check(lua_State *L, int idx)
+{
+ return (scripting_layer_mask_t *)mrp_lua_check_object(L, LAYER_MASK_CLASS,
+ idx);
+}
+
+static uint32_t get_layer_mask(mrp_wayland_scripting_field_t fld)
+{
+ switch (fld) {
+ case LAYER: return MRP_WAYLAND_LAYER_LAYERID_MASK;
+ case VISIBLE: return MRP_WAYLAND_LAYER_VISIBLE_MASK;
+ default: return 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "output.h"
+
+#define OUTPUT_CLASS MRP_LUA_CLASS_SIMPLE(output)
+#define OUTPUT_MASK_CLASS MRP_LUA_CLASS_SIMPLE(output_mask)
+
+
+typedef struct scripting_output_s scripting_output_t;
+typedef struct scripting_output_mask_s scripting_output_mask_t;
+
+
+
+struct scripting_output_s {
+ mrp_wayland_output_t *out;
+};
+
+struct scripting_output_mask_s {
+ uint32_t mask;
+};
+
+
+
+static int output_create_from_lua(lua_State *);
+static int output_getfield(lua_State *);
+static int output_setfield(lua_State *);
+static int output_stringify(lua_State *);
+static void output_destroy_from_lua(void *);
+
+static scripting_output_t *output_check(lua_State *L, int idx);
+
+static int output_mask_create_from_lua(lua_State *);
+static int output_mask_getfield(lua_State *);
+static int output_mask_setfield(lua_State *);
+static int output_mask_stringify(lua_State *);
+static void output_mask_destroy(void *);
+
+static scripting_output_mask_t *output_mask_check(lua_State *, int);
+
+static uint32_t get_output_mask(mrp_wayland_scripting_field_t);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ output, /* class name */
+ scripting_output_t, /* userdata type */
+ output_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (output_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (output_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (output_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (output_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (output_stringify)
+ )
+);
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ output_mask, /* class name */
+ scripting_output_mask_t, /* userdata type */
+ output_mask_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (output_mask_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (output_mask_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (output_mask_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (output_mask_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (output_mask_stringify)
+ )
+);
+
+
+
+
+void mrp_wayland_scripting_output_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, OUTPUT_CLASS);
+ mrp_lua_create_object_class(L, OUTPUT_MASK_CLASS);
+}
+
+
+mrp_wayland_output_t *mrp_wayland_scripting_output_check(lua_State *L, int idx)
+{
+ scripting_output_t *o;
+ mrp_wayland_output_t *out;
+
+ if ((o = output_check(L, idx)) && (out = o->out)) {
+ MRP_ASSERT(out->scripting_data == (void *)o,
+ "confused with data structures");
+ return out;
+ }
+
+ return NULL;
+}
+
+mrp_wayland_output_t *mrp_wayland_scripting_output_unwrap(void *void_o)
+{
+ scripting_output_t *o = (scripting_output_t *)void_o;
+
+ if (o && mrp_lua_get_object_classdef(o) == OUTPUT_CLASS)
+ return o->out;
+
+ return NULL;
+}
+
+void *mrp_wayland_scripting_output_create_from_c(lua_State *L,
+ mrp_wayland_output_t *out)
+{
+ scripting_output_t *o;
+ mrp_wayland_t *wl;
+
+ MRP_ASSERT(out && out->interface && out->interface->wl, "invald argument");
+
+ wl = out->interface->wl;
+
+ if (!wl->create_scripting_outputs)
+ o = NULL;
+ else if (out->scripting_data)
+ o = out->scripting_data;
+ else {
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting output %d: LUA is "
+ "not initialized", out->outputid);
+ return NULL;
+ }
+
+ o = (scripting_output_t *)mrp_lua_create_object(L, OUTPUT_CLASS, NULL,
+ out->outputid + 1);
+ if (!o) {
+ mrp_log_error("can't create scripting output %d: LUA object "
+ "creation failed", out->outputid);
+ }
+ else {
+ o->out = out;
+ mrp_wayland_output_set_scripting_data(out, o);
+ lua_pop(L, 1);
+ }
+ }
+
+ return o;
+}
+
+void mrp_wayland_scripting_output_destroy_from_c(lua_State *L,
+ mrp_wayland_output_t *out)
+{
+ scripting_output_t *o;
+
+ MRP_ASSERT(out, "invalid argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't destroy scripting output %d: LUA is "
+ "not initialized", out->outputid);
+ out->scripting_data = NULL;
+ return;
+ }
+
+ if ((o = out->scripting_data)) {
+ mrp_debug("destroy scripting output %d", out->outputid);
+
+ o->out = NULL;
+
+ mrp_lua_destroy_object(L, NULL,out->outputid+1, out->scripting_data);
+
+ out->scripting_data = NULL;
+ }
+}
+
+
+static int output_create_from_lua(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ luaL_error(L, "can't create output from lua");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int output_getfield(lua_State *L)
+{
+ scripting_output_t *o;
+ mrp_wayland_output_t *out;
+ const char *fldnam;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ o = output_check(L, 1);
+
+ if (!o || !(out = o->out))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case INDEX: lua_pushinteger(L, out->index); break;
+ case ID: lua_pushinteger(L, out->outputid); break;
+ case NAME: lua_pushstring(L, out->outputname ?
+ out->outputname : ""); break;
+ case PIXEL_X: lua_pushinteger(L, out->pixel_x); break;
+ case PIXEL_Y: lua_pushinteger(L, out->pixel_y); break;
+ case PIXEL_WIDTH: lua_pushinteger(L, out->pixel_width); break;
+ case PIXEL_HEIGHT: lua_pushinteger(L, out->pixel_height); break;
+ case WIDTH: lua_pushinteger(L, out->width); break;
+ case HEIGHT: lua_pushinteger(L, out->height); break;
+ case MAKE: lua_pushstring(L, out->make ? out->make:""); break;
+ case MODEL: lua_pushstring(L, out->model?out->model:""); break;
+ case ROTATE: lua_pushinteger(L, out->rotate); break;
+ case FLIP: lua_pushboolean(L, out->flip); break;
+ default: lua_pushnil(L); break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int output_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ output_check(L, 1);
+ luaL_error(L, "output objects are read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int output_stringify(lua_State *L)
+{
+#define ALL_FIELDS (MRP_WAYLAND_OUTPUT_END_MASK - 1)
+
+ scripting_output_t *o;
+ mrp_wayland_output_t *out;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ o = output_check(L, 1);
+
+ if (!o || !(out = o->out))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "output %d", out->index);
+ p += mrp_wayland_output_print(out, ALL_FIELDS, p, e-p);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+
+#undef ALL_FIELDS
+}
+
+static void output_destroy_from_lua(void *data)
+{
+ scripting_output_t *o = (scripting_output_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (o && o->out) {
+ mrp_wayland_output_set_scripting_data(o->out, NULL);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_output_t *output_check(lua_State *L, int idx)
+{
+ return (scripting_output_t *)mrp_lua_check_object(L, OUTPUT_CLASS, idx);
+}
+
+
+
+void *mrp_wayland_scripting_output_mask_create_from_c(lua_State *L,
+ uint32_t mask)
+{
+ scripting_output_mask_t *um;
+
+ um = (scripting_output_mask_t *)mrp_lua_create_object(L, OUTPUT_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ mrp_log_error("can't create output_mask");
+ else
+ um->mask = mask;
+
+ return um;
+}
+
+static int output_mask_create_from_lua(lua_State *L)
+{
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_output_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+ uint32_t mask = 0;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ fld = mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (fld == MASK)
+ mask = lua_tointeger(L, -1);
+ else if ((m = get_output_mask(fld)))
+ mask |= m;
+ else
+ luaL_error(L, "bad field '%s'", fldnam);
+ }
+
+ um = (scripting_output_mask_t *)mrp_lua_create_object(L, OUTPUT_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ luaL_error(L, "can't create output_mask");
+
+ um->mask = mask;
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int output_mask_getfield(lua_State *L)
+{
+ scripting_output_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+
+ MRP_LUA_ENTER;
+
+ um = output_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 1);
+
+ if (!um)
+ lua_pushnil(L);
+ else {
+ if (fld == MASK)
+ lua_pushinteger(L, um->mask);
+ else if ((m = get_output_mask(fld)))
+ lua_pushboolean(L, (um->mask & m) ? 1 : 0);
+ else
+ lua_pushnil(L);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int output_mask_setfield(lua_State *L)
+{
+ scripting_output_mask_t *um;
+ uint32_t m;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ um = output_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 2);
+
+ if (um) {
+ if (fld == MASK)
+ um->mask = lua_tointeger(L, 3);
+ else if ((m = get_output_mask(fld))) {
+ um->mask &= ~m;
+
+ if (lua_toboolean(L, 3))
+ um->mask |= m;
+ }
+ }
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int output_mask_stringify(lua_State *L)
+{
+ scripting_output_mask_t *um;
+ uint32_t m, mask;
+ char buf[4096];
+ char *p, *e;
+ const char *name;
+
+
+ MRP_LUA_ENTER;
+
+ um = output_mask_check(L, 1);
+ e = (p = buf) + sizeof(buf);
+ *p = 0;
+
+ mask = um->mask;
+
+ for (m = 1; mask && m < MRP_WAYLAND_OUTPUT_END_MASK && p < e; m <<= 1) {
+ if ((mask & m)) {
+ mask &= ~m;
+
+ if ((name = mrp_wayland_output_update_mask_str(m)))
+ p += snprintf(p, e-p, "%s%s", p > buf ? " | " : "", name);
+ }
+ }
+
+ lua_pushstring(L, (p > buf) ? buf : "<empty>");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static void output_mask_destroy(void *data)
+{
+ scripting_output_mask_t *um = (scripting_output_mask_t *)data;
+
+ MRP_UNUSED(um);
+}
+
+static scripting_output_mask_t *output_mask_check(lua_State *L, int idx)
+{
+ return (scripting_output_mask_t *)mrp_lua_check_object(L,OUTPUT_MASK_CLASS,
+ idx);
+}
+
+static uint32_t get_output_mask(mrp_wayland_scripting_field_t fld)
+{
+ switch (fld) {
+ case ID: return MRP_WAYLAND_OUTPUT_OUTPUTID_MASK;
+ case PIXEL_X: return MRP_WAYLAND_OUTPUT_PIXEL_X_MASK;
+ case PIXEL_Y: return MRP_WAYLAND_OUTPUT_PIXEL_Y_MASK;
+ case PIXEL_WIDTH: return MRP_WAYLAND_OUTPUT_PIXEL_WIDTH_MASK;
+ case PIXEL_HEIGHT: return MRP_WAYLAND_OUTPUT_PIXEL_HEIGHT_MASK;
+ case WIDTH: return MRP_WAYLAND_OUTPUT_WIDTH_MASK;
+ case HEIGHT: return MRP_WAYLAND_OUTPUT_HEIGHT_MASK;
+ case SUBPIXEL: return MRP_WAYLAND_OUTPUT_SUBPIXEL_MASK;
+ case MAKE: return MRP_WAYLAND_OUTPUT_MAKE_MASK;
+ case MODEL: return MRP_WAYLAND_OUTPUT_MODEL_MASK;
+ case ROTATE: return MRP_WAYLAND_OUTPUT_ROTATE_MASK;
+ case FLIP: return MRP_WAYLAND_OUTPUT_FLIP_MASK;
+ default: return 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "output.h"
+#include "area.h"
+#include "window.h"
+#include "layer.h"
+#include "animation.h"
+
+
+
+void mrp_wayland_scripting_init(lua_State *L)
+{
+ mrp_wayland_scripting_window_manager_init(L);
+ mrp_wayland_scripting_animation_init(L);
+ mrp_wayland_scripting_window_init(L);
+ mrp_wayland_scripting_output_init(L);
+ mrp_wayland_scripting_area_init(L);
+ mrp_wayland_scripting_layer_init(L);
+}
+
+
+char *mrp_wayland_scripting_canonical_name(const char *name,
+ char *buf,
+ size_t len)
+{
+ const char *q;
+ char *p, *e, c;
+
+ if (len < 2)
+ return "";
+
+ e = (p = buf) + (len - 1);
+ q = name;
+
+ if (isdigit(*q))
+ *p++ = '_';
+
+ while ((c = *q++) && p < e)
+ *p++ = isalnum(c) ? c : '_';
+
+ *p = 0;
+
+ return buf;
+}
+
+
+int mrp_wayland_json_integer_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ const char *str;
+ int32_t val;
+ char *e;
+
+ MRP_UNUSED(wl);
+
+ if (mrp_json_is_type(jval, MRP_JSON_INTEGER)) {
+ *(int32_t *)uval = mrp_json_integer_value(jval);
+ return mask;
+ }
+
+ if (mrp_json_is_type(jval, MRP_JSON_STRING)) {
+ str = mrp_json_string_value(jval);
+ val = strtol(str, &e, 10);
+
+ if (e > str && !*e) {
+ *(int32_t *)uval = val;
+ return mask;
+ }
+ }
+
+ return 0;
+}
+
+int mrp_wayland_json_string_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ MRP_UNUSED(wl);
+
+ if (mrp_json_is_type(jval, MRP_JSON_STRING)) {
+ *(const char **)uval = mrp_json_string_value(jval);
+ return mask;
+ }
+
+ return 0;
+}
+
+int mrp_wayland_json_boolean_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ const char *str;
+
+ MRP_UNUSED(wl);
+
+ if (mrp_json_is_type(jval, MRP_JSON_BOOLEAN)) {
+ *(bool *)uval = mrp_json_boolean_value(jval) ? true : false;
+ return mask;
+ }
+
+ if (mrp_json_is_type(jval, MRP_JSON_INTEGER)) {
+ *(bool *)uval = mrp_json_integer_value(jval) ? true : false;
+ return mask;
+ }
+
+ if (mrp_json_is_type(jval, MRP_JSON_STRING)) {
+ str = mrp_json_string_value(jval);
+
+ if (!strcmp(str,"yes") || !strcmp(str,"on") || !strcmp(str,"true")) {
+ *(bool *)uval = true;
+ return mask;
+ }
+
+ if (!strcmp(str,"no") || !strcmp(str,"off") || !strcmp(str,"false")) {
+ *(bool *)uval = false;
+ return mask;
+ }
+ }
+
+ return 0;
+}
+
+int mrp_wayland_json_layer_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ int32_t layerid;
+ mrp_wayland_layer_t *layer;
+
+ if (!mrp_json_is_type(jval, MRP_JSON_INTEGER))
+ return 0;
+
+ layerid = mrp_json_integer_value(jval);
+
+ if (!(layer = mrp_wayland_layer_find(wl, layerid)))
+ return 0;
+
+ *(mrp_wayland_layer_t **)uval = layer;
+
+ return mask;
+}
+
+int mrp_wayland_json_output_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ uint32_t index;
+ mrp_wayland_output_t *out;
+
+ if (!mrp_json_is_type(jval, MRP_JSON_INTEGER))
+ return 0;
+
+ index = mrp_json_integer_value(jval);
+
+ if (!(out = mrp_wayland_output_find(wl, index)))
+ return 0;
+
+ *(mrp_wayland_output_t **)uval = out;
+
+ return mask;
+}
+
+int mrp_wayland_json_area_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ const char *fullname;
+ mrp_wayland_area_t *area;
+
+ if (!mrp_json_is_type(jval, MRP_JSON_STRING))
+ return 0;
+
+ fullname = mrp_json_string_value(jval);
+
+ if (!(area = mrp_wayland_area_find(wl, fullname)))
+ return 0;
+
+ *(mrp_wayland_area_t **)uval = area;
+
+ return mask;
+}
+
+int mrp_wayland_json_align_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask)
+{
+ const char *key;
+ mrp_json_t *val;
+ mrp_json_iter_t it;
+ mrp_wayland_scripting_field_t fldid, valid;
+ const char *valstr;
+ mrp_wayland_area_align_t align;
+
+ MRP_UNUSED(wl);
+
+ if (!mrp_json_is_type(jval, MRP_JSON_ARRAY) &&
+ !mrp_json_is_type(jval, MRP_JSON_INTEGER))
+ return 0;
+
+ if (mrp_json_is_type(jval, MRP_JSON_INTEGER))
+ align = mrp_json_integer_value(jval);
+ else {
+ align = 0;
+ mrp_json_foreach_member(jval, key,val, it) {
+ if (!mrp_json_is_type(val, MRP_JSON_STRING))
+ return 0;
+ valstr = mrp_json_string_value(val);
+ fldid = mrp_wayland_scripting_field_name_to_type(key, -1);
+ valid = mrp_wayland_scripting_field_name_to_type(valstr, -1);
+ switch (fldid) {
+ case HORIZONTAL:
+ switch (valid) {
+ case LEFT: align |= MRP_WAYLAND_AREA_ALIGN_LEFT; break;
+ case RIGHT: align |= MRP_WAYLAND_AREA_ALIGN_RIGHT; break;
+ case MIDDLE: align |= MRP_WAYLAND_AREA_ALIGN_MIDDLE; break;
+ default: /* invalid alignement */ return 0;
+ }
+ break;
+ case VERTICAL:
+ switch (valid) {
+ case TOP: align |= MRP_WAYLAND_AREA_ALIGN_TOP; break;
+ case BOTTOM: align |= MRP_WAYLAND_AREA_ALIGN_BOTTOM; break;
+ case MIDDLE: align |= MRP_WAYLAND_AREA_ALIGN_MIDDLE; break;
+ default: /* invalid alignement */ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+ }
+ }
+
+ *(mrp_wayland_area_align_t *)uval = align;
+
+ return mask;
+}
+
+
+
+mrp_wayland_scripting_field_t
+mrp_wayland_scripting_field_check(lua_State *L,int idx,const char **ret_fldnam)
+{
+ const char *fldnam;
+ size_t fldnamlen;
+ mrp_wayland_scripting_field_t fldtyp;
+
+ if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
+ fldtyp = 0;
+ else
+ fldtyp = mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (ret_fldnam)
+ *ret_fldnam = fldnam;
+
+ return fldtyp;
+}
+
+mrp_wayland_scripting_field_t
+mrp_wayland_scripting_field_name_to_type(const char *name, ssize_t len)
+{
+ if (len < 0)
+ len = strlen(name);
+
+ switch (len) {
+
+ case 2:
+ if (!strcmp(name, "id"))
+ return ID;
+ break;
+
+ case 3:
+ switch (name[0]) {
+ case 'p':
+ if (!strcmp(name, "pid"))
+ return PID;
+ break;
+ case 't':
+ if (!strcmp(name, "top"))
+ return TOP;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 4:
+ switch (name[0]) {
+ case 'a':
+ if (!strcmp(name, "area"))
+ return AREA;
+ break;
+ case 'f':
+ if (!strcmp(name, "flip"))
+ return FLIP;
+ break;
+ case 'h':
+ if (!strcmp(name, "hide"))
+ return HIDE;
+ break;
+ case 'l':
+ if (!strcmp(name, "left"))
+ return LEFT;
+ break;
+ case 'm':
+ if (!strcmp(name, "make"))
+ return MAKE;
+ if (!strcmp(name, "mask"))
+ return MASK;
+ if (!strcmp(name, "move"))
+ return MOVE;
+ break;
+ case 'n':
+ if (!strcmp(name, "name"))
+ return NAME;
+ if (!strcmp(name, "node"))
+ return NODE;
+ break;
+ case 's':
+ if (!strcmp(name, "show"))
+ return SHOW;
+ if (!strcmp(name, "size"))
+ return SIZE;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 5:
+ switch(name[0]) {
+ case 'a':
+ if (!strcmp(name, "align"))
+ return ALIGN;
+ if (!strcmp(name, "appid"))
+ return APPID;
+ break;
+ case 'i':
+ if (!strcmp(name, "index"))
+ return INDEX;
+ break;
+ case 'l':
+ if (!strcmp(name, "layer"))
+ return LAYER;
+ break;
+ case 'm':
+ if (!strcmp(name, "model"))
+ return MODEL;
+ break;
+ case 'p':
+ if (!strcmp(name, "pos_x"))
+ return POS_X;
+ if (!strcmp(name, "pos_y"))
+ return POS_Y;
+ break;
+ case 'r':
+ if (!strcmp(name, "raise"))
+ return RAISE;
+ if (!strcmp(name, "right"))
+ return RIGHT;
+ break;
+ case 'w':
+ if (!strcmp(name, "width"))
+ return WIDTH;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 6:
+ switch (name[0]) {
+ case 'a':
+ if (!strcmp(name, "active"))
+ return ACTIVE;
+ break;
+ case 'b':
+ if (!strcmp(name, "bottom"))
+ return BOTTOM;
+ break;
+ case 'h':
+ if (!strcmp(name, "height"))
+ return HEIGHT;
+ break;
+ case 'l':
+ if (!strcmp(name, "layers"))
+ return LAYERS;
+ break;
+ case 'm':
+ if (!strcmp(name, "mapped"))
+ return MAPPED;
+ if (!strcmp(name, "middle"))
+ return MIDDLE;
+ break;
+ case 'o':
+ if (!strcmp(name, "output"))
+ return OUTPUT;
+ break;
+ case 'r':
+ if (!strcmp(name, "resize"))
+ return RESIZE;
+ if (!strcmp(name, "rotate"))
+ return ROTATE;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 7:
+ switch (name[0]) {
+ case 'd':
+ if (!strcmp(name, "display"))
+ return DISPLAY;
+ break;
+ case 'p':
+ if (!strcmp(name, "pixel_x"))
+ return PIXEL_X;
+ if (!strcmp(name, "pixel_y"))
+ return PIXEL_Y;
+ break;
+ case 's':
+ if (!strcmp(name, "surface"))
+ return SURFACE;
+ break;
+ case 'v':
+ if (!strcmp(name, "visible"))
+ return VISIBLE;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 8:
+ switch (name[0]) {
+ case 'p':
+ if (!strcmp(name, "position"))
+ return POSITION;
+ break;
+ case 's':
+ if (!strcmp(name, "subpixel"))
+ return SUBPIXEL;
+ break;
+ case 'v':
+ if (!strcmp(name, "vertical"))
+ return VERTICAL;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 9:
+ if (!strcmp(name, "layertype"))
+ return LAYERTYPE;
+ break;
+
+ case 10:
+ switch (name[0]) {
+ case 'h':
+ if (!strcmp(name, "horizontal"))
+ return HORIZONTAL;
+ break;
+ case 'k':
+ if (!strcmp(name, "keep_ratio"))
+ return KEEPRATIO;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 11:
+ switch (name[0]) {
+ case 'a':
+ if (!strcmp(name, "area_create"))
+ return AREA_CREATE;
+ break;
+ case 'p':
+ if (!strcmp(name, "pixel_width"))
+ return PIXEL_WIDTH;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 12:
+ switch (name[0]) {
+ case 'l':
+ if (!strcmp(name, "layer_update"))
+ return LAYER_UPDATE;
+ break;
+ case 'p':
+ if (!strcmp(name, "pixel_height"))
+ return PIXEL_HEIGHT;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 13:
+ switch (name[0]) {
+ case 'l':
+ if (!strcmp(name, "layer_request"))
+ return LAYER_REQUEST;
+ break;
+ case 'o':
+ if (!strcmp(name, "output_update"))
+ return OUTPUT_UPDATE;
+ break;
+ case 'w':
+ if (!strcmp(name, "window_update"))
+ return WINDOW_UPDATE;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 14:
+ switch (name[0]) {
+ case 'o':
+ if (!strcmp(name, "output_request"))
+ return OUTPUT_REQUEST;
+ break;
+ case 'w':
+ if (!strcmp(name, "window_manager"))
+ return WINDOW_MANAGER;
+ if (!strcmp(name, "window_request"))
+ return WINDOW_REQUEST;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_SCRIPTING_H__
+#define __MURPHY_WAYLAND_SCRIPTING_H__
+
+#include <lua.h>
+
+#include <murphy/core/lua-bindings/lua-json.h>
+
+#include "wayland/wayland.h"
+
+typedef int (*mrp_wayland_json_copy_func_t)(mrp_wayland_t *, void *,
+ mrp_json_t *, int);
+
+void mrp_wayland_scripting_init(lua_State *L);
+char *mrp_wayland_scripting_canonical_name(const char *name, char *buf,
+ size_t len);
+
+/* scripting-window-manager.c */
+void mrp_wayland_scripting_window_manager_init(lua_State *L);
+
+mrp_wayland_t *mrp_wayland_scripting_window_manager_check(lua_State *L,
+ int idx);
+mrp_wayland_t *mrp_wayland_scripting_window_manager_unwrap(void *wmgr);
+
+/* scripting-animation.c */
+void mrp_wayland_scripting_animation_init(lua_State *L);
+mrp_wayland_animation_t *mrp_wayland_scripting_animation_check(lua_State *L,
+ int idx);
+mrp_wayland_animation_t *mrp_wayland_scripting_animation_unwrap(void *void_an);
+
+/* scripting-window.c */
+void mrp_wayland_scripting_window_init(lua_State *);
+
+mrp_wayland_window_t *mrp_wayland_scripting_window_check(lua_State *L,int idx);
+mrp_wayland_window_t *mrp_wayland_scripting_window_unwrap(void *void_w);
+void *mrp_wayland_scripting_window_create_from_c(lua_State *L,
+ mrp_wayland_window_t *win);
+void mrp_wayland_scripting_window_destroy_from_c(lua_State *L,
+ mrp_wayland_window_t *win);
+
+uint32_t mrp_wayland_scripting_window_mask_check(lua_State *L, int idx);
+uint32_t mrp_wayland_scripting_window_mask_unwrap(void *void_um);
+void *mrp_wayland_scripting_window_mask_create_from_c(lua_State *L,
+ uint32_t mask);
+
+/* scripting-output.c */
+void mrp_wayland_scripting_output_init(lua_State *L);
+
+mrp_wayland_output_t *mrp_wayland_scripting_output_check(lua_State *L,int idx);
+mrp_wayland_output_t *mrp_wayland_scripting_output_unwrap(void *void_o);
+void *mrp_wayland_scripting_output_create_from_c(lua_State *L,
+ mrp_wayland_output_t *out);
+void mrp_wayland_scripting_output_destroy_from_c(lua_State *L,
+ mrp_wayland_output_t *out);
+
+void *mrp_wayland_scripting_output_mask_create_from_c(lua_State *L,
+ uint32_t mask);
+
+/* scripting-area.c */
+void mrp_wayland_scripting_area_init(lua_State *L);
+
+mrp_wayland_area_t *mrp_wayland_scripting_area_check(lua_State *L, int idx);
+mrp_wayland_area_t *mrp_wayland_scripting_area_unwrap(void *void_a);
+int mrp_wayland_scripting_area_push(lua_State *L, mrp_wayland_area_t *area);
+void *mrp_wayland_scripting_area_create_from_c(lua_State *L,
+ mrp_wayland_area_t *area);
+void mrp_wayland_scripting_area_destroy_from_c(lua_State *L,
+ mrp_wayland_area_t *area);
+
+void *mrp_wayland_scripting_align_mask_create_from_c(lua_State *L,
+ uint32_t mask);
+
+
+/* scripting-layer.c */
+void mrp_wayland_scripting_layer_init(lua_State *L);
+
+mrp_wayland_layer_t *mrp_wayland_scripting_layer_check(lua_State *L, int idx);
+mrp_wayland_layer_t *mrp_wayland_scripting_layer_unwrap(void *void_l);
+void *mrp_wayland_scripting_layer_create_from_c(lua_State *L,
+ mrp_wayland_layer_t *layer);
+void mrp_wayland_scripting_layer_destroy_from_c(lua_State *L,
+ mrp_wayland_layer_t *layer);
+
+void *mrp_wayland_scripting_layer_mask_create_from_c(lua_State *L,
+ uint32_t mask);
+
+/* internal for scripting-window-manager.c files */
+int mrp_wayland_json_integer_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_string_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_boolean_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_layer_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_output_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_area_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+int mrp_wayland_json_align_copy(mrp_wayland_t *wl, void *uval,
+ mrp_json_t *jval, int mask);
+
+mrp_wayland_scripting_field_t
+mrp_wayland_scripting_field_check(lua_State *, int, const char **);
+
+mrp_wayland_scripting_field_t
+mrp_wayland_scripting_field_name_to_type(const char *, ssize_t);
+
+
+#endif /* __MURPHY_WAYLAND_SCRIPTING_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "animation.h"
+#include "window.h"
+#include "layer.h"
+#include "output.h"
+#include "area.h"
+#include "ico-window-manager.h"
+
+#define WINDOW_MANAGER_CLASS MRP_LUA_CLASS_SIMPLE(window_manager)
+
+typedef struct scripting_winmgr_s scripting_winmgr_t;
+typedef struct funcbridge_def_s funcbridge_def_t;
+typedef struct layer_def_s layer_def_t;
+typedef struct request_def_s request_def_t;
+
+struct scripting_winmgr_s {
+ mrp_wayland_t *wl;
+ const char *name;
+ const char *display;
+ mrp_funcbridge_t *output_update;
+ mrp_funcbridge_t *layer_update;
+ mrp_funcbridge_t *window_update;
+};
+
+struct funcbridge_def_s {
+ const char *name;
+ const char *sign;
+ mrp_funcbridge_cfunc_t func;
+ void *data;
+ mrp_funcbridge_t **ptr;
+};
+
+
+struct layer_def_s {
+ int32_t id;
+ const char *name;
+ int32_t type;
+};
+
+struct request_def_s {
+ const char *name;
+ int offset;
+ int mask;
+ mrp_wayland_json_copy_func_t copy;
+};
+
+
+static int window_manager_create(lua_State *);
+static int window_manager_connect(lua_State *);
+static int window_manager_canonical_name(lua_State *);
+static int window_manager_getfield(lua_State *);
+static int window_manager_setfield(lua_State *);
+static void window_manager_destroy(void *);
+
+static scripting_winmgr_t *window_manager_check(lua_State *, int);
+
+static layer_def_t *layer_def_check(lua_State *, int);
+static void layer_def_free(layer_def_t *);
+
+
+static bool window_request_bridge(lua_State *, void *,
+ const char *, mrp_funcbridge_value_t *,
+ char *, mrp_funcbridge_value_t *);
+static void window_update_callback(mrp_wayland_t *,
+ mrp_wayland_window_operation_t,
+ mrp_wayland_window_update_mask_t,
+ mrp_wayland_window_t *);
+
+static bool output_request_bridge(lua_State *, void *,
+ const char *, mrp_funcbridge_value_t *,
+ char *, mrp_funcbridge_value_t *);
+static void output_update_callback(mrp_wayland_t *,
+ mrp_wayland_output_operation_t,
+ mrp_wayland_output_update_mask_t,
+ mrp_wayland_output_t *);
+
+static bool area_create_bridge(lua_State *, void *,
+ const char *, mrp_funcbridge_value_t *,
+ char *, mrp_funcbridge_value_t *);
+
+static bool layer_request_bridge(lua_State *, void *,
+ const char *, mrp_funcbridge_value_t *,
+ char *, mrp_funcbridge_value_t *);
+static void layer_update_callback(mrp_wayland_t *,
+ mrp_wayland_layer_operation_t,
+ mrp_wayland_layer_update_mask_t,
+ mrp_wayland_layer_t *);
+
+static uint32_t copy_json_fields(mrp_wayland_t *, mrp_json_t *,
+ request_def_t *, void *);
+static bool register_methods(lua_State *);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ window_manager, /* class name */
+ scripting_winmgr_t, /* userdata type */
+ window_manager_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (window_manager_create)
+ MRP_LUA_METHOD(connect, window_manager_connect)
+ MRP_LUA_METHOD(canonical_name, window_manager_canonical_name)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (window_manager_create)
+ MRP_LUA_OVERRIDE_GETFIELD (window_manager_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (window_manager_setfield)
+ )
+);
+
+static mrp_funcbridge_t *output_request;
+static mrp_funcbridge_t *area_create;
+static mrp_funcbridge_t *layer_request;
+static mrp_funcbridge_t *window_request;
+
+
+void mrp_wayland_scripting_window_manager_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, WINDOW_MANAGER_CLASS);
+ register_methods(L);
+}
+
+mrp_wayland_t *mrp_wayland_scripting_window_manager_check(lua_State *L,int idx)
+{
+ scripting_winmgr_t *wmgr;
+ mrp_wayland_t *wl;
+
+ if ((wmgr = window_manager_check(L, idx)) && (wl = wmgr->wl)) {
+ MRP_ASSERT(wl->scripting_data == (void *)wmgr,
+ "confused with data structures");
+ return wl;
+ }
+
+ return NULL;
+}
+
+mrp_wayland_t *mrp_wayland_scripting_window_manager_unwrap(void *void_wmgr)
+{
+ scripting_winmgr_t *wmgr = (scripting_winmgr_t *)void_wmgr;
+
+ if (wmgr && mrp_lua_get_object_classdef(wmgr) == WINDOW_MANAGER_CLASS)
+ return wmgr->wl;
+
+ return NULL;
+}
+
+static int window_manager_create(lua_State *L)
+{
+ mrp_context_t *ctx;
+ mrp_wayland_t *wl;
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_winmgr_t *winmgr;
+ mrp_wayland_layer_update_t lu;
+ char *name;
+ const char *display = NULL;
+ layer_def_t *layers = NULL;
+ mrp_funcbridge_t *output_update = NULL;
+ mrp_funcbridge_t *layer_update = NULL;
+ mrp_funcbridge_t *window_update = NULL;
+ char buf[256];
+ layer_def_t *l;
+ int table;
+
+ MRP_LUA_ENTER;
+
+ ctx = mrp_lua_get_murphy_context();
+
+ MRP_ASSERT(ctx && ctx->ml, "invalid app.context or missing mainloop");
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ winmgr = (scripting_winmgr_t*)mrp_lua_create_object(L,WINDOW_MANAGER_CLASS,
+ NULL, 0);
+ if (!winmgr)
+ luaL_error(L, "can't create window manager on display '%s'", display);
+
+ table = lua_gettop(L);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ switch (mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen)) {
+
+ case DISPLAY:
+ display = luaL_checkstring(L, -1);
+ break;
+
+ case LAYERS:
+ layers = layer_def_check(L, -1);
+ break;
+
+ case OUTPUT_UPDATE:
+ output_update = mrp_funcbridge_create_luafunc(L, -1);
+ break;
+
+ case LAYER_UPDATE:
+ layer_update = mrp_funcbridge_create_luafunc(L, -1);
+ break;
+
+ case WINDOW_UPDATE:
+ window_update = mrp_funcbridge_create_luafunc(L, -1);
+ break;
+
+ default:
+ lua_pushvalue(L, -2);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, table);
+ break;
+ }
+ }
+
+ if (!display)
+ display = getenv("WAYLAND_DISPLAY");
+
+ if (!display)
+ display = "wayland-0";
+
+ name = mrp_wayland_scripting_canonical_name(display, buf, sizeof(buf));
+
+ if (!(wl = mrp_wayland_create(display, ctx->ml)))
+ luaL_error(L, "can't create wayland object");
+
+ mrp_lua_set_object_name(L, WINDOW_MANAGER_CLASS, name);
+
+ winmgr->wl = wl;
+ winmgr->name = mrp_strdup(name);
+ winmgr->display = mrp_strdup(display);
+ winmgr->output_update = output_update;
+ winmgr->layer_update = layer_update;
+ winmgr->window_update = window_update;
+
+ mrp_wayland_output_register(wl);
+ mrp_ico_window_manager_register(wl);
+
+ mrp_wayland_register_output_update_callback(wl, output_update_callback);
+ mrp_wayland_register_layer_update_callback(wl, layer_update_callback);
+ mrp_wayland_register_window_update_callback(wl, window_update_callback);
+
+ mrp_wayland_set_scripting_data(wl, winmgr);
+
+ mrp_wayland_create_scripting_windows(wl, true);
+ mrp_wayland_create_scripting_outputs(wl, true);
+ mrp_wayland_create_scripting_areas(wl, true);
+ mrp_wayland_create_scripting_layers(wl, true);
+
+ if (layers) {
+ memset(&lu, 0, sizeof(lu));
+ lu.mask = MRP_WAYLAND_LAYER_LAYERID_MASK |
+ MRP_WAYLAND_LAYER_NAME_MASK |
+ MRP_WAYLAND_LAYER_TYPE_MASK ;
+
+ for (l = layers; l->name; l++) {
+ lu.layerid = l->id;
+ lu.name = l->name;
+ lu.type = l->type;
+ mrp_wayland_layer_create(wl, &lu);
+ }
+
+ layer_def_free(layers);
+ }
+
+ lua_settop(L, table);
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_manager_connect(lua_State *L)
+{
+ scripting_winmgr_t *wmgr;
+ bool success;
+
+ MRP_LUA_ENTER;
+
+ wmgr = window_manager_check(L, 1);
+
+ if (wmgr->wl != NULL)
+ success = mrp_wayland_connect(wmgr->wl);
+ else
+ success = false;
+
+ lua_pushboolean(L, success);
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_manager_canonical_name(lua_State *L)
+{
+ const char *name;
+ char *canonical;
+ char buf[2048];
+
+ MRP_LUA_ENTER;
+
+ *(canonical = buf) = 0;
+
+ if ((name = luaL_checkstring(L, 2)))
+ canonical = mrp_wayland_scripting_canonical_name(name,buf,sizeof(buf));
+
+ lua_pushstring(L, canonical);
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_manager_getfield(lua_State *L)
+{
+ scripting_winmgr_t *wmgr;
+ const char *fldnam;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ wmgr = window_manager_check(L, 1);
+
+ if (!wmgr)
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+
+ case DISPLAY:
+ lua_pushstring(L, wmgr->display);
+ break;
+
+ case OUTPUT_REQUEST:
+ mrp_funcbridge_push(L, output_request);
+ break;
+
+ case OUTPUT_UPDATE:
+ mrp_funcbridge_push(L, wmgr->output_update);
+ break;
+
+ case AREA_CREATE:
+ mrp_funcbridge_push(L, area_create);
+ break;
+
+ case LAYER_REQUEST:
+ mrp_funcbridge_push(L, layer_request);
+ break;
+
+ case LAYER_UPDATE:
+ mrp_funcbridge_push(L, wmgr->layer_update);
+ break;
+
+ case WINDOW_REQUEST:
+ mrp_funcbridge_push(L, window_request);
+ break;
+
+ case WINDOW_UPDATE:
+ mrp_funcbridge_push(L, wmgr->window_update);
+ break;
+
+ default:
+ lua_pushstring(L, fldnam);
+ lua_rawget(L, 1);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_manager_setfield(lua_State *L)
+{
+ scripting_winmgr_t *wmgr;
+
+ MRP_LUA_ENTER;
+
+ wmgr = window_manager_check(L, 1);
+ luaL_error(L, "window manager '%s' is read-only", wmgr->display);
+
+ MRP_LUA_LEAVE(0);
+}
+
+static void window_manager_destroy(void *data)
+{
+ scripting_winmgr_t *winmgr = (scripting_winmgr_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (winmgr) {
+ mrp_free((void *)winmgr->name);
+ mrp_free((void *)winmgr->display);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+static scripting_winmgr_t *window_manager_check(lua_State *L, int idx)
+{
+
+ return (scripting_winmgr_t *)mrp_lua_check_object(L, WINDOW_MANAGER_CLASS,
+ idx);
+}
+
+static layer_def_t *layer_def_check(lua_State *L, int t)
+{
+ size_t tlen, dlen;
+ size_t size;
+ layer_def_t *layers, *l;
+ size_t i, j;
+
+ t = (t < 0) ? lua_gettop(L) + t + 1 : t;
+
+ luaL_checktype(L, t, LUA_TTABLE);
+ tlen = lua_objlen(L, t);
+ size = sizeof(layer_def_t) * (tlen + 1);
+
+ if (!(layers = mrp_allocz(size)))
+ luaL_error(L, "can't allocate %d byte long memory", size);
+ else {
+ for (i = 0; i < tlen; i++) {
+ l = layers + i;
+
+ lua_pushinteger(L, (int)(i+1));
+ lua_gettable(L, t);
+
+ if (!lua_istable(L, -1))
+ goto error;
+
+ dlen = lua_objlen(L, -1);
+
+ for (j = 0; j < dlen; j++) {
+ lua_pushnumber(L, (int)(j+1));
+ lua_gettable(L, -2);
+
+ switch (j) {
+ case 0: l->id = lua_tointeger(L, -1); break;
+ case 1: l->name = mrp_strdup(lua_tostring(L, -1)); break;
+ case 2: l->type = lua_tointeger(L, -1); break;
+ default: goto error;
+ }
+
+ lua_pop(L, 1);
+ }
+
+ lua_pop(L, 1);
+
+ if (!l->name || l->id < 0 || l->id > 0x10000)
+ goto error;
+ }
+ }
+
+ return layers;
+
+ error:
+ layer_def_free(layers);
+ luaL_argerror(L, i+1, "malformed layer definition");
+ return NULL;
+}
+
+static void layer_def_free(layer_def_t *layers)
+{
+ layer_def_t *l;
+
+ if (layers) {
+ for (l = layers; l->name; l++)
+ mrp_free((void *)l->name);
+ mrp_free((void *)layers);
+ }
+}
+
+static bool window_request_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+#define FIELD(f) MRP_OFFSET(mrp_wayland_window_update_t, f)
+#define MASK(m) MRP_WAYLAND_WINDOW_ ## m ## _MASK
+#define TYPE(t) mrp_wayland_json_ ## t ## _copy
+
+ static request_def_t fields[] = {
+ { "surface", FIELD(surfaceid), MASK(SURFACEID), TYPE(integer) },
+ { "layer" , FIELD(layer) , MASK(LAYER) , TYPE(layer) },
+ { "node" , FIELD(nodeid) , MASK(NODEID) , TYPE(integer) },
+ { "pos_x" , FIELD(x) , MASK(X) , TYPE(integer) },
+ { "pos_y" , FIELD(y) , MASK(Y) , TYPE(integer) },
+ { "width" , FIELD(width) , MASK(WIDTH) , TYPE(integer) },
+ { "height" , FIELD(height) , MASK(HEIGHT) , TYPE(integer) },
+ { "raise" , FIELD(raise) , MASK(RAISE) , TYPE(integer) },
+ { "visible", FIELD(visible) , MASK(VISIBLE) , TYPE(integer) },
+ { "active" , FIELD(active) , MASK(ACTIVE) , TYPE(integer) },
+ { "area" , FIELD(area) , MASK(AREA) , TYPE(area) },
+ { NULL , 0 , 0 , NULL }
+ };
+
+#undef FIELD
+#undef MASK
+#undef TYPE
+
+ mrp_wayland_t *wl;
+ mrp_wayland_animation_t *anims;
+ mrp_wayland_window_update_t u;
+ uint32_t framerate;
+ mrp_json_t *json;
+
+ MRP_UNUSED(L);
+ MRP_UNUSED(data);
+ MRP_UNUSED(ret_val);
+ MRP_ASSERT(signature && args && ret_type, "invalid argument");
+
+ *ret_type = MRP_FUNCBRIDGE_NO_DATA;
+
+ if (strcmp(signature, "oood")) {
+ mrp_log_error("bad signature: expected 'oood' got '%s'",signature);
+ return false;
+ }
+
+ if (!(wl = mrp_wayland_scripting_window_manager_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'window_manager' class object");
+ return false;
+ }
+
+ if (!(json = mrp_json_lua_unwrap(args[1].pointer))) {
+ mrp_log_error("argument 2 is not a 'JSON' class object");
+ return false;
+ }
+
+ if (!(anims = mrp_wayland_scripting_animation_unwrap(args[2].pointer))) {
+ mrp_log_error("argument 3 is not an 'animation' class object");
+ return false;
+ }
+
+ if ((framerate = args[3].integer) > MRP_WAYLAND_FRAMERATE_MAX) {
+ mrp_log_error("argument 3 is not valid framerate (out of range 0-%d)",
+ MRP_WAYLAND_FRAMERATE_MAX);
+ return false;
+ }
+
+
+ memset(&u, 0, sizeof(u));
+ u.mask = copy_json_fields(wl, json, fields, &u);
+
+ mrp_wayland_window_request(wl, &u, anims, framerate);
+
+ return true;
+}
+
+
+static void window_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_operation_t oper,
+ mrp_wayland_window_update_mask_t mask,
+ mrp_wayland_window_t *win)
+{
+ lua_State *L;
+ scripting_winmgr_t *winmgr;
+ mrp_funcbridge_value_t args[4], ret;
+ char t;
+ bool success;
+
+ MRP_ASSERT(wl && win, "invalid argument");
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't update window %u: LUA is not initialesed",
+ win->surfaceid);
+ return;
+ }
+
+ if (!(winmgr = (scripting_winmgr_t *)wl->scripting_data)) {
+ mrp_log_error("window manager scripting is not initialized");
+ return;
+ }
+
+ MRP_ASSERT(wl == winmgr->wl, "confused with data structures");
+
+ if (!win->scripting_data) {
+ mrp_log_error("no scripting data for window %d", win->surfaceid);
+ return;
+ }
+
+ args[0].pointer = winmgr;
+ args[1].integer = oper;
+ args[2].pointer = win->scripting_data;
+ args[3].pointer = mrp_wayland_scripting_window_mask_create_from_c(L, mask);
+
+ memset(&ret, 0, sizeof(ret));
+
+ success = mrp_funcbridge_call_from_c(L, winmgr->window_update, "odoo",
+ args, &t, &ret);
+ if (!success) {
+ mrp_log_error("failed to call window_manager.%s.window_update method "
+ "(%s)", winmgr->name, ret.string ? ret.string : "NULL");
+ mrp_free((void *)ret.string);
+ }
+}
+
+static bool output_request_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+#define FIELD(f) MRP_OFFSET(mrp_wayland_output_update_t, f)
+#define MASK(m) MRP_WAYLAND_OUTPUT_ ## m ## _MASK
+#define TYPE(t) mrp_wayland_json_ ## t ## _copy
+
+ static request_def_t fields[] = {
+ { "index" , FIELD(index) , MASK(INDEX) , TYPE(integer) },
+ { "id" , FIELD(outputid) , MASK(OUTPUTID), TYPE(integer) },
+ { "name" , FIELD(outputname), MASK(NAME) , TYPE(string) },
+ { NULL , 0 , 0 , NULL }
+ };
+
+#undef FIELD
+#undef MASK
+#undef TYPE
+
+ mrp_wayland_t *wl;
+ mrp_wayland_output_update_t u;
+ mrp_json_t *json;
+
+ MRP_UNUSED(L);
+ MRP_UNUSED(data);
+ MRP_UNUSED(ret_val);
+ MRP_ASSERT(signature && args && ret_type, "invalid argument");
+
+ *ret_type = MRP_FUNCBRIDGE_NO_DATA;
+
+ if (strcmp(signature, "oo")) {
+ mrp_log_error("bad signature: expected 'oo' got '%s'",signature);
+ return false;
+ }
+
+ if (!(wl = mrp_wayland_scripting_window_manager_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'window_manager' class object");
+ return false;
+ }
+
+ if (!(json = mrp_json_lua_unwrap(args[1].pointer))) {
+ mrp_log_error("argument 2 is not a 'JSON' class object");
+ return false;
+ }
+
+
+ memset(&u, 0, sizeof(u));
+ u.mask = copy_json_fields(wl, json, fields, &u);
+
+ mrp_wayland_output_request(wl, &u);
+
+ return true;
+}
+
+static void output_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_output_operation_t oper,
+ mrp_wayland_output_update_mask_t mask,
+ mrp_wayland_output_t *out)
+{
+ lua_State *L;
+ scripting_winmgr_t *winmgr;
+ mrp_funcbridge_value_t args[4], ret;
+ char t;
+ bool success;
+
+ MRP_ASSERT(wl && out, "invalid argument");
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't update output %d '%s': LUA is not initialesed",
+ out->outputid, out->outputname);
+ return;
+ }
+
+ if (!(winmgr = (scripting_winmgr_t *)wl->scripting_data)) {
+ mrp_log_error("window manager scripting is not initialized");
+ return;
+ }
+
+ MRP_ASSERT(wl == winmgr->wl, "confused with data structures");
+
+ if (!out->scripting_data) {
+ mrp_log_error("no scripting data for output %d '%s'",
+ out->outputid, out->outputname);
+ return;
+ }
+
+ args[0].pointer = winmgr;
+ args[1].integer = oper;
+ args[2].pointer = out->scripting_data;
+ args[3].pointer = mrp_wayland_scripting_output_mask_create_from_c(L, mask);
+
+ memset(&ret, 0, sizeof(ret));
+
+ success = mrp_funcbridge_call_from_c(L, winmgr->output_update, "odoo",
+ args, &t, &ret);
+ if (!success) {
+ mrp_log_error("failed to call window_manager.%s.output_update method "
+ "(%s)", winmgr->name, ret.string ? ret.string : "NULL");
+ mrp_free((void *)ret.string);
+ }
+}
+
+static bool area_create_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+#define FIELD(f) MRP_OFFSET(mrp_wayland_area_update_t, f)
+#define MASK(m) MRP_WAYLAND_AREA_ ## m ## _MASK
+#define TYPE(t) mrp_wayland_json_ ## t ## _copy
+
+ static request_def_t fields[] = {
+ { "id" , FIELD(areaid) , MASK(AREAID) , TYPE(integer) },
+ { "name" , FIELD(name) , MASK(NAME) , TYPE(string) },
+ { "output" , FIELD(output) , MASK(OUTPUT) , TYPE(output) },
+ { "pos_x" , FIELD(x) , MASK(X) , TYPE(integer) },
+ { "pos_y" , FIELD(y) , MASK(Y) , TYPE(integer) },
+ { "width" , FIELD(width) , MASK(WIDTH) , TYPE(integer) },
+ { "height" , FIELD(height) , MASK(HEIGHT) , TYPE(integer) },
+ { "keep_ratio", FIELD(keepratio), MASK(KEEPRATIO), TYPE(boolean) },
+ { "align" , FIELD(align) , MASK(ALIGN) , TYPE(align) },
+ { NULL , 0 , 0 , NULL }
+ };
+
+#undef FIELD
+#undef MASK
+#undef TYPE
+
+ mrp_wayland_t *wl;
+ mrp_wayland_area_update_t u;
+ mrp_json_t *json;
+
+ MRP_UNUSED(L);
+ MRP_UNUSED(data);
+ MRP_UNUSED(ret_val);
+ MRP_ASSERT(signature && args && ret_type, "invalid argument");
+
+ *ret_type = MRP_FUNCBRIDGE_NO_DATA;
+
+
+ if (strcmp(signature, "oo")) {
+ mrp_log_error("bad signature: expected 'oo' got '%s'",signature);
+ return false;
+ }
+
+ if (!(wl = mrp_wayland_scripting_window_manager_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'window_manager' class object");
+ return false;
+ }
+
+ if (!(json = mrp_json_lua_unwrap(args[1].pointer))) {
+ mrp_log_error("argument 2 is not a 'JSON' class object");
+ return false;
+ }
+
+ memset(&u, 0, sizeof(u));
+ u.mask = copy_json_fields(wl, json, fields, &u);
+
+ mrp_wayland_area_create(wl, &u);
+
+ return true;
+}
+
+static bool layer_request_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+#define FIELD(f) MRP_OFFSET(mrp_wayland_layer_update_t, f)
+#define MASK(m) MRP_WAYLAND_LAYER_ ## m ## _MASK
+#define TYPE(t) mrp_wayland_json_ ## t ## _copy
+
+ static request_def_t fields[] = {
+ { "layer" , FIELD(layerid) , MASK(LAYERID), TYPE(integer) },
+ { "visible", FIELD(visible) , MASK(VISIBLE), TYPE(integer) },
+ { NULL , 0 , 0 , NULL }
+ };
+
+#undef FIELD
+#undef MASK
+#undef TYPE
+
+ mrp_wayland_t *wl;
+ mrp_wayland_layer_update_t u;
+ mrp_json_t *json;
+
+ MRP_UNUSED(L);
+ MRP_UNUSED(data);
+ MRP_UNUSED(ret_val);
+ MRP_ASSERT(signature && args && ret_type, "invalid argument");
+
+ *ret_type = MRP_FUNCBRIDGE_NO_DATA;
+
+ if (strcmp(signature, "oo")) {
+ mrp_log_error("bad signature: expected 'oo' got '%s'",signature);
+ return false;
+ }
+
+ if (!(wl = mrp_wayland_scripting_window_manager_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'window_manager' class object");
+ return false;
+ }
+
+ if (!(json = mrp_json_lua_unwrap(args[1].pointer))) {
+ mrp_log_error("argument 2 is not a 'JSON' class object");
+ return false;
+ }
+
+ memset(&u, 0, sizeof(u));
+ u.mask = copy_json_fields(wl, json, fields, &u);
+
+ return true;
+}
+
+static void layer_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_layer_operation_t oper,
+ mrp_wayland_layer_update_mask_t mask,
+ mrp_wayland_layer_t *layer)
+{
+ lua_State *L;
+ scripting_winmgr_t *winmgr;
+ mrp_funcbridge_value_t args[4], ret;
+ char t;
+ bool success;
+
+ MRP_ASSERT(wl && layer, "invalid argument");
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't update layer %u: LUA is not initialesed",
+ layer->layerid);
+ return;
+ }
+
+ if (!(winmgr = (scripting_winmgr_t *)wl->scripting_data)) {
+ mrp_log_error("window manager scripting is not initialized");
+ return;
+ }
+
+ MRP_ASSERT(wl == winmgr->wl, "confused with data structures");
+
+ if (!layer->scripting_data) {
+ mrp_log_error("no scripting data for layer %d", layer->layerid);
+ return;
+ }
+
+ args[0].pointer = winmgr;
+ args[1].integer = oper;
+ args[2].pointer = layer->scripting_data;
+ args[3].pointer = mrp_wayland_scripting_layer_mask_create_from_c(L, mask);
+
+ memset(&ret, 0, sizeof(ret));
+
+ success = mrp_funcbridge_call_from_c(L, winmgr->layer_update, "odoo",
+ args, &t, &ret);
+ if (!success) {
+ mrp_log_error("failed to call window_manager.%s.output_update method "
+ "(%s)", winmgr->name, ret.string ? ret.string : "NULL");
+ mrp_free((void *)ret.string);
+ }
+}
+
+
+static uint32_t copy_json_fields(mrp_wayland_t *wl,
+ mrp_json_t *json,
+ request_def_t *fields,
+ void *copy)
+{
+ const char *key;
+ mrp_json_t *val;
+ mrp_json_iter_t it;
+ request_def_t *f;
+ uint32_t m, mask;
+
+ mask = 0;
+
+ mrp_json_foreach_member(json, key,val, it) {
+ for (f = fields; f->name; f++) {
+ if (!strcmp(key, f->name)) {
+ if ((m = f->copy(wl, copy + f->offset, val, f->mask)))
+ mask |= m;
+ else
+ mrp_debug("'%s' field has invalid value", key);
+ break;
+ }
+ }
+ }
+
+ return mask;
+}
+
+
+static bool register_methods(lua_State *L)
+{
+#define FUNCBRIDGE(n,s,d) { #n, s, n##_bridge, d, &n }
+#define FUNCBRIDGE_END { NULL, NULL, NULL, NULL, NULL }
+
+ static funcbridge_def_t funcbridge_defs[] = {
+ FUNCBRIDGE(output_request, "oo" , NULL),
+ FUNCBRIDGE(area_create , "oo" , NULL),
+ FUNCBRIDGE(layer_request , "oo" , NULL),
+ FUNCBRIDGE(window_request, "oood", NULL),
+ FUNCBRIDGE_END
+ };
+
+ mrp_funcbridge_t *f;
+ funcbridge_def_t *d;
+ bool success = true;
+
+ for (d = funcbridge_defs; d->name; d++) {
+ *(d->ptr) = f = mrp_funcbridge_create_cfunc(L, d->name, d->sign,
+ d->func, d->data);
+ if (!f) {
+ mrp_log_error("failed to register builtin function '%s'", d->name);
+ success = false;
+ }
+ }
+
+ return success;
+
+#undef FUNCBRIDGE_END
+#undef FUNCBRIDGE
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+#include <murphy/core/lua-bindings/murphy.h>
+#include <murphy/core/lua-utils/error.h>
+#include <murphy/core/lua-utils/object.h>
+#include <murphy/core/lua-utils/funcbridge.h>
+
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "scripting-wayland.h"
+#include "window.h"
+#include "area.h"
+
+#define WINDOW_CLASS MRP_LUA_CLASS_SIMPLE(window)
+#define WINDOW_MASK_CLASS MRP_LUA_CLASS_SIMPLE(window_mask)
+
+typedef struct scripting_window_s scripting_window_t;
+typedef struct scripting_window_mask_s scripting_window_mask_t;
+
+struct scripting_window_s {
+ mrp_wayland_window_t *win;
+};
+
+struct scripting_window_mask_s {
+ uint32_t mask;
+};
+
+static int window_create_from_lua(lua_State *);
+static int window_getfield(lua_State *);
+static int window_setfield(lua_State *);
+static int window_stringify(lua_State *);
+static void window_destroy_from_lua(void *);
+
+static scripting_window_t *window_check(lua_State *L, int idx);
+
+static int window_mask_create_from_lua(lua_State *);
+static int window_mask_getfield(lua_State *);
+static int window_mask_setfield(lua_State *);
+static int window_mask_stringify(lua_State *);
+static void window_mask_destroy(void *);
+
+static scripting_window_mask_t *window_mask_check(lua_State *, int);
+
+static uint32_t get_window_mask(mrp_wayland_scripting_field_t);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ window, /* class name */
+ scripting_window_t, /* userdata type */
+ window_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (window_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (window_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (window_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (window_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (window_stringify)
+ )
+);
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ window_mask, /* class name */
+ scripting_window_mask_t, /* userdata type */
+ window_mask_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (window_mask_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (window_mask_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (window_mask_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (window_mask_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (window_mask_stringify)
+ )
+);
+
+
+
+void mrp_wayland_scripting_window_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, WINDOW_CLASS);
+ mrp_lua_create_object_class(L, WINDOW_MASK_CLASS);
+}
+
+mrp_wayland_window_t *mrp_wayland_scripting_window_check(lua_State *L, int idx)
+{
+ scripting_window_t *w;
+ mrp_wayland_window_t *win;
+
+ if ((w = window_check(L, idx)) && (win = w->win)) {
+ MRP_ASSERT(win->scripting_data == (void *)w,
+ "confused with data structures");
+ return win;
+ }
+
+ return NULL;
+}
+
+mrp_wayland_window_t *mrp_wayland_scripting_window_unwrap(void *void_w)
+{
+ scripting_window_t *w = (scripting_window_t *)void_w;
+
+ if (w && mrp_lua_get_object_classdef(w) == WINDOW_CLASS)
+ return w->win;
+
+ return NULL;
+}
+
+
+void *mrp_wayland_scripting_window_create_from_c(lua_State *L,
+ mrp_wayland_window_t *win)
+{
+ scripting_window_t *w;
+
+ MRP_ASSERT(win, "invald argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting window %d: LUA is "
+ "not initialized", win->surfaceid);
+ return NULL;
+ }
+
+ w = (scripting_window_t *)mrp_lua_create_object(L, WINDOW_CLASS, NULL,
+ win->surfaceid + 1);
+ if (!w) {
+ mrp_log_error("can't create scripting window %d: LUA object "
+ "creation failed", win->surfaceid);
+ return NULL;
+ }
+
+ w->win = win;
+
+ return w;
+}
+
+void mrp_wayland_scripting_window_destroy_from_c(lua_State *L,
+ mrp_wayland_window_t *win)
+{
+ scripting_window_t *w;
+
+ MRP_ASSERT(win, "invalid argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't destroy scripting window %d: LUA is "
+ "not initialized", win->surfaceid);
+ win->scripting_data = NULL;
+ return;
+ }
+
+ if ((w = win->scripting_data)) {
+ mrp_debug("destroy scripting window %d", win->surfaceid);
+
+ w->win = NULL;
+
+ mrp_lua_destroy_object(L, NULL,win->surfaceid+1, win->scripting_data);
+
+ win->scripting_data = NULL;
+ }
+}
+
+
+static int window_create_from_lua(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ luaL_error(L, "can't create window from lua");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_getfield(lua_State *L)
+{
+ scripting_window_t *w;
+ mrp_wayland_window_t *win;
+ const char *fldnam;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_wayland_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ w = window_check(L, 1);
+
+ if (!w || !(win = w->win))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case SURFACE: lua_pushinteger(L, win->surfaceid); break;
+ case NAME: lua_pushstring(L, win->name ? win->name : ""); break;
+ case APPID: lua_pushstring(L, win->appid ? win->appid : ""); break;
+ case PID: lua_pushinteger(L, win->pid); break;
+ case NODE: lua_pushinteger(L, win->nodeid); break;
+ case LAYER: lua_pushinteger(L, win->layer ?
+ win->layer->layerid : -1); break;
+ case POS_X: lua_pushinteger(L, win->x); break;
+ case POS_Y: lua_pushinteger(L, win->y); break;
+ case WIDTH: lua_pushinteger(L, win->width); break;
+ case HEIGHT: lua_pushinteger(L, win->height); break;
+ case VISIBLE: lua_pushinteger(L, win->visible ? 1 : 0); break;
+ case RAISE: lua_pushinteger(L, win->raise ? 1 : 0); break;
+ case MAPPED: lua_pushinteger(L, win->mapped ? 1 : 0); break;
+ case ACTIVE: lua_pushinteger(L, win->active); break;
+ case LAYERTYPE: lua_pushinteger(L, win->layertype); break;
+ case AREA: lua_pushstring(L, win->area && win->area->fullname ?
+ win->area->fullname : ""); break;
+ default: lua_pushnil(L); break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ window_check(L, 1);
+ luaL_error(L, "window objects are read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int window_stringify(lua_State *L)
+{
+#define ALL_FIELDS (MRP_WAYLAND_WINDOW_END_MASK - 1)
+
+ scripting_window_t *w;
+ mrp_wayland_window_t *win;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ w = window_check(L, 1);
+
+ if (!(win = w->win))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "window %d", win->surfaceid);
+ p += mrp_wayland_window_print(win, ALL_FIELDS, p, e-p);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+
+#undef ALL_FIELDS
+}
+
+static void window_destroy_from_lua(void *data)
+{
+ scripting_window_t *w = (scripting_window_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (w && w->win) {
+ mrp_wayland_window_set_scripting_data(w->win, NULL);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_window_t *window_check(lua_State *L, int idx)
+{
+ return (scripting_window_t *)mrp_lua_check_object(L, WINDOW_CLASS, idx);
+}
+
+
+uint32_t mrp_wayland_scripting_window_mask_check(lua_State *L, int idx)
+{
+ scripting_window_mask_t *um = window_mask_check(L, idx);
+
+ return um ? um->mask : 0;
+}
+
+uint32_t mrp_wayland_scripting_window_mask_unwrap(void *void_um)
+{
+ scripting_window_mask_t *um = (scripting_window_mask_t *)void_um;
+
+ return um ? um->mask : 0;
+}
+
+
+void *mrp_wayland_scripting_window_mask_create_from_c(lua_State *L,
+ uint32_t mask)
+{
+ scripting_window_mask_t *um;
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't create scripting window mask: "
+ "LUA is not initialized");
+ return NULL;
+ }
+
+ um = (scripting_window_mask_t *)mrp_lua_create_object(L, WINDOW_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ mrp_log_error("can't create window_mask");
+ else
+ um->mask = mask;
+
+ return um;
+}
+
+static int window_mask_create_from_lua(lua_State *L)
+{
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_window_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+ uint32_t mask = 0;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ fld = mrp_wayland_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (fld == MASK)
+ mask = lua_tointeger(L, -1);
+ else if ((m = get_window_mask(fld)))
+ mask |= m;
+ else
+ luaL_error(L, "bad field '%s'", fldnam);
+ }
+
+ um = (scripting_window_mask_t *)mrp_lua_create_object(L, WINDOW_MASK_CLASS,
+ NULL, 0);
+ if (!um)
+ luaL_error(L, "can't create window_mask");
+
+ um->mask = mask;
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_mask_getfield(lua_State *L)
+{
+ scripting_window_mask_t *um;
+ mrp_wayland_scripting_field_t fld;
+ uint32_t m;
+
+ MRP_LUA_ENTER;
+
+ um = window_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 1);
+
+ if (!um)
+ lua_pushnil(L);
+ else {
+ if (fld == MASK)
+ lua_pushinteger(L, um->mask);
+ else if ((m = get_window_mask(fld)))
+ lua_pushboolean(L, (um->mask & m) ? 1 : 0);
+ else
+ lua_pushnil(L);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int window_mask_setfield(lua_State *L)
+{
+ scripting_window_mask_t *um;
+ uint32_t m;
+ mrp_wayland_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ um = window_mask_check(L, 1);
+ fld = mrp_wayland_scripting_field_check(L, 2, NULL);
+
+ lua_pop(L, 2);
+
+ if (um) {
+ if (fld == MASK)
+ um->mask = lua_tointeger(L, 3);
+ else if ((m = get_window_mask(fld))) {
+ um->mask &= ~m;
+
+ if (lua_toboolean(L, 3))
+ um->mask |= m;
+ }
+ }
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int window_mask_stringify(lua_State *L)
+{
+ scripting_window_mask_t *um;
+ uint32_t m, mask;
+ char buf[4096];
+ char *p, *e;
+ const char *name;
+
+
+ MRP_LUA_ENTER;
+
+ um = window_mask_check(L, 1);
+ e = (p = buf) + sizeof(buf);
+ *p = 0;
+
+ mask = um->mask;
+
+ for (m = 1; mask && m < MRP_WAYLAND_WINDOW_END_MASK && p < e; m <<= 1) {
+ if ((mask & m)) {
+ mask &= ~m;
+
+ if ((name = mrp_wayland_window_update_mask_str(m)))
+ p += snprintf(p, e-p, "%s%s", p > buf ? " | " : "", name);
+ }
+ }
+
+ lua_pushstring(L, (p > buf) ? buf : "<empty>");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static void window_mask_destroy(void *data)
+{
+ scripting_window_mask_t *um = (scripting_window_mask_t *)data;
+
+ MRP_UNUSED(um);
+}
+
+
+static scripting_window_mask_t *window_mask_check(lua_State *L, int idx)
+{
+ return (scripting_window_mask_t*)mrp_lua_check_object(L, WINDOW_MASK_CLASS,
+ idx);
+}
+
+
+static uint32_t get_window_mask(mrp_wayland_scripting_field_t fld)
+{
+ switch (fld) {
+ case SURFACE: return MRP_WAYLAND_WINDOW_SURFACEID_MASK;
+ case APPID: return MRP_WAYLAND_WINDOW_APPID_MASK;
+ case PID: return MRP_WAYLAND_WINDOW_PID_MASK;
+ case NODE: return MRP_WAYLAND_WINDOW_NODEID_MASK;
+ case LAYER: return MRP_WAYLAND_WINDOW_LAYER_MASK;
+ case POS_X: return MRP_WAYLAND_WINDOW_X_MASK;
+ case POS_Y: return MRP_WAYLAND_WINDOW_Y_MASK;
+ case POSITION: return MRP_WAYLAND_WINDOW_POSITION_MASK;
+ case WIDTH: return MRP_WAYLAND_WINDOW_WIDTH_MASK;
+ case HEIGHT: return MRP_WAYLAND_WINDOW_HEIGHT_MASK;
+ case SIZE: return MRP_WAYLAND_WINDOW_SIZE_MASK;
+ case VISIBLE: return MRP_WAYLAND_WINDOW_VISIBLE_MASK;
+ case RAISE: return MRP_WAYLAND_WINDOW_RAISE_MASK;
+ case ACTIVE: return MRP_WAYLAND_WINDOW_ACTIVE_MASK;
+ case LAYERTYPE: return MRP_WAYLAND_WINDOW_LAYERTYPE_MASK;
+ case AREA: return MRP_WAYLAND_WINDOW_AREA_MASK;
+ default: return 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "wayland.h"
+#include "output.h"
+#include "layer.h"
+
+
+static uint32_t oid_hash(const void *);
+static uint32_t wid_hash(const void *);
+static uint32_t lid_hash(const void *);
+static int id_compare(const void *, const void *);
+
+static const char *get_display_name(mrp_wayland_t *w);
+static void display_io_watch(mrp_io_watch_t *, int, mrp_io_event_t, void *);
+static void object_create(mrp_wayland_interface_t *, uint32_t, uint32_t);
+static void global_available_callback(void *, struct wl_registry *, uint32_t,
+ const char *, uint32_t);
+static void global_remove_callback(void *, struct wl_registry *, uint32_t);
+
+static mrp_wayland_t **instances;
+static size_t ninstance;
+
+
+mrp_wayland_t *mrp_wayland_create(const char *display_name, mrp_mainloop_t *ml)
+{
+ mrp_wayland_t *wl;
+ mrp_htbl_config_t icfg, ocfg, wcfg, lcfg, acfg;
+
+ MRP_ASSERT(ml, "invalid argument");
+
+ if (!(wl = mrp_allocz(sizeof(mrp_wayland_t))))
+ mrp_log_error("can't allocate memory for wayland");
+ else {
+ memset(&icfg, 0, sizeof(icfg));
+ icfg.nentry = MRP_WAYLAND_INTERFACE_MAX;
+ icfg.comp = mrp_string_comp;
+ icfg.hash = mrp_string_hash;
+ icfg.nbucket = MRP_WAYLAND_INTERFACE_BUCKETS;
+
+ memset(&ocfg, 0, sizeof(ocfg));
+ ocfg.nentry = MRP_WAYLAND_OUTPUT_MAX;
+ ocfg.comp = id_compare;
+ ocfg.hash = oid_hash;
+ ocfg.nbucket = MRP_WAYLAND_OUTPUT_BUCKETS;
+
+ memset(&wcfg, 0, sizeof(wcfg));
+ wcfg.nentry = MRP_WAYLAND_WINDOW_MAX;
+ wcfg.comp = id_compare;
+ wcfg.hash = wid_hash;
+ wcfg.nbucket = MRP_WAYLAND_WINDOW_BUCKETS;
+
+ memset(&lcfg, 0, sizeof(lcfg));
+ lcfg.nentry = MRP_WAYLAND_LAYER_MAX + MRP_WAYLAND_LAYER_BUILTIN;
+ lcfg.comp = id_compare;
+ lcfg.hash = lid_hash;
+ lcfg.nbucket = MRP_WAYLAND_LAYER_BUCKETS;
+
+ memset(&acfg, 0, sizeof(acfg));
+ acfg.nentry = MRP_WAYLAND_AREA_MAX;
+ acfg.comp = mrp_string_comp;
+ acfg.hash = mrp_string_hash;
+ acfg.nbucket = MRP_WAYLAND_AREA_BUCKETS;
+
+ wl->display_name = display_name ? mrp_strdup(display_name) : NULL;
+ wl->ml = ml;
+
+ wl->registry_listener.global = global_available_callback;
+ wl->registry_listener.global_remove = global_remove_callback;
+
+ wl->interfaces = mrp_htbl_create(&icfg);
+ wl->outputs = mrp_htbl_create(&ocfg);
+ wl->windows = mrp_htbl_create(&wcfg);
+ wl->layers = mrp_htbl_create(&lcfg);
+ wl->areas = mrp_htbl_create(&acfg);
+
+ instances = mrp_reallocz(instances, ninstance, ninstance + 2);
+ instances[ninstance++] = wl;
+ }
+
+ return wl;
+}
+
+void mrp_wayland_destroy(mrp_wayland_t *wl)
+{
+ size_t i;
+
+ if (wl) {
+ for (i = 0; i < ninstance; i++) {
+ if (instances[i] == wl) {
+ if (i < ninstance-1) {
+ memmove(instances + i, instances + i + 1,
+ (ninstance - (i + 1)) * sizeof(*instances));
+ }
+ instances[--ninstance] = NULL;
+ break;
+ }
+ }
+ }
+}
+
+mrp_wayland_t *mrp_wayland_iterate(void **cursor)
+{
+ ptrdiff_t i;
+
+ if (cursor) {
+ i = *cursor - NULL;
+
+ if (i >= 0 && i < (ptrdiff_t)ninstance) {
+ *cursor = NULL + (i + 1);
+ return instances[i];
+ }
+ }
+
+ return NULL;
+}
+
+bool mrp_wayland_connect(mrp_wayland_t *wl)
+{
+#define IO_EVENTS MRP_IO_EVENT_IN | MRP_IO_EVENT_ERR | MRP_IO_EVENT_HUP
+
+ struct wl_display *display;
+ struct wl_registry *registry;
+ mrp_io_watch_t *iow;
+ int fd;
+
+ MRP_ASSERT(wl, "invalid argument");
+ MRP_ASSERT(wl->ml, "no mainloop");
+
+ if (wl->iow)
+ return true; /* we are already connected */
+
+ if (!(display = wl_display_connect(wl->display_name))) {
+ mrp_debug("attempt to connect to display '%s' failed",
+ get_display_name(wl));
+ return false;
+ }
+
+ fd = wl_display_get_fd(display);
+
+ MRP_ASSERT(fd >= 0, "fd for wayland display < 0");
+
+ if (!(registry = wl_display_get_registry(display))) {
+ mrp_log_error("can't get registry for display '%s'",
+ get_display_name(wl));
+ wl_display_disconnect(display);
+ return false;
+ }
+
+ if (wl_registry_add_listener(registry, &wl->registry_listener, wl) < 0) {
+ mrp_log_error("can't add listener for registry (display '%s')",
+ get_display_name(wl));
+ wl_registry_destroy(registry);
+ wl_display_disconnect(display);
+ return false;
+ }
+
+ if (!(iow = mrp_add_io_watch(wl->ml,fd,IO_EVENTS,display_io_watch,wl))) {
+ mrp_log_error("can't add io watch for display '%s')",
+ get_display_name(wl));
+ wl_registry_destroy(registry);
+ wl_display_disconnect(display);
+ return false;
+ }
+
+ wl->iow = iow;
+ wl->display = display;
+ wl->registry = registry;
+
+ mrp_log_info("connecting to wayland display '%s'", get_display_name(wl));
+
+ wl_display_roundtrip(display);
+
+ mrp_debug("queried interfaces");
+
+ wl_display_roundtrip(display);
+
+ mrp_log_info("display '%s' is up and running", get_display_name(wl));
+
+ return true;
+
+#undef IO_EVENTS
+}
+
+void mrp_wayland_flush(mrp_wayland_t *wl)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ if (wl->display) {
+ mrp_debug("calling wl_display_flush()");
+ wl_display_flush(wl->display);
+ }
+}
+
+
+static int update_layers(void *key, void *object, void *ud)
+{
+ mrp_wayland_window_manager_t *wm = (mrp_wayland_window_manager_t *)ud;
+ mrp_wayland_layer_t *layer = (mrp_wayland_layer_t *)object;
+
+ MRP_UNUSED(key);
+
+ mrp_debug("register window manager to layer %u/'%s'",
+ layer->layerid, layer->name);
+
+ layer->wm = wm;
+
+ return MRP_HTBL_ITER_MORE;
+}
+
+
+void mrp_wayland_register_window_manager(mrp_wayland_t *wl,
+ mrp_wayland_window_manager_t *wm)
+{
+ wl->wm = wm;
+
+ mrp_htbl_foreach(wl->layers, update_layers, wm);
+}
+
+
+bool mrp_wayland_register_interface(mrp_wayland_t *wl,
+ mrp_wayland_factory_t *factory)
+{
+ mrp_wayland_interface_t *wif;
+ const char *name;
+
+ MRP_ASSERT(wl && factory, "invalid argument");
+ MRP_ASSERT(factory->size >= sizeof(mrp_wayland_object_t),
+ "invalid object size in factory");
+ MRP_ASSERT(factory->interface, "missing factory interface");
+
+ name = factory->interface->name;
+
+ MRP_ASSERT(name, "broken factory interface");
+
+ if (!(wif = mrp_allocz(sizeof(mrp_wayland_interface_t)))) {
+ mrp_log_error("can't allocate memory for wayland interface '%s'",
+ name);
+ return false;
+ }
+
+ wif->wl = wl;
+ wif->name = mrp_strdup(name);
+ wif->object_factory = *factory;
+
+ mrp_list_init(&wif->object_list);
+
+ if (!mrp_htbl_insert(wl->interfaces, (void *)wif->name, wif)) {
+ mrp_log_error("failed to add interface '%s' to hashtable. "
+ "Perhaps already registered ...", wif->name);
+ mrp_free((void *)wif->name);
+ mrp_free(wif);
+ return false;
+ }
+
+ mrp_log_info("registered wayland interface '%s'", wif->name);
+
+ return true;
+}
+
+void mrp_wayland_register_output_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_output_update_callback_t callback)
+{
+ MRP_ASSERT(wl, "invalid aruments");
+
+ mrp_debug("registering output_update_callback");
+
+ wl->output_update_callback = callback;
+}
+
+void mrp_wayland_register_window_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_update_callback_t callback)
+{
+ MRP_ASSERT(wl, "invalid aruments");
+
+ mrp_debug("registering window_update_callback");
+
+ wl->window_update_callback = callback;
+}
+
+void mrp_wayland_register_layer_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_layer_update_callback_t callback)
+{
+ MRP_ASSERT(wl, "invalid aruments");
+
+ mrp_debug("registering layer_update_callback");
+
+ wl->layer_update_callback = callback;
+}
+
+void mrp_wayland_register_area_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_area_update_callback_t callback)
+{
+ MRP_ASSERT(wl, "invalid aruments");
+
+ mrp_debug("registering area_update_callback");
+
+ wl->area_update_callback = callback;
+}
+
+void mrp_wayland_set_scripting_data(mrp_wayland_t *wl, void *data)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ wl->scripting_data = data;
+}
+
+void mrp_wayland_create_scripting_windows(mrp_wayland_t *wl, bool create)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ mrp_debug("%screate scripting windows", create ? "" : "do not ");
+
+ wl->create_scripting_windows = create;
+}
+
+
+void mrp_wayland_create_scripting_outputs(mrp_wayland_t *wl, bool create)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ mrp_debug("%screate scripting outputs", create ? "" : "do not ");
+
+ wl->create_scripting_outputs = create;
+}
+
+
+void mrp_wayland_create_scripting_areas(mrp_wayland_t *wl, bool create)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ mrp_debug("%screate scripting areas", create ? "" : "do not ");
+
+ wl->create_scripting_areas = create;
+}
+
+
+void mrp_wayland_create_scripting_layers(mrp_wayland_t *wl, bool create)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ mrp_debug("%screate scripting layers", create ? "" : "do not ");
+
+ wl->create_scripting_layers = create;
+}
+
+
+static uint32_t oid_hash(const void *pkey)
+{
+ uint32_t key = *(uint32_t *)pkey;
+
+ return key % MRP_WAYLAND_OUTPUT_BUCKETS;
+}
+
+static uint32_t wid_hash(const void *pkey)
+{
+ uint32_t key = *(uint32_t *)pkey;
+
+ return key % MRP_WAYLAND_WINDOW_BUCKETS;
+}
+
+static uint32_t lid_hash(const void *pkey)
+{
+ uint32_t key = *(uint32_t *)pkey;
+
+ return key % MRP_WAYLAND_LAYER_BUCKETS;
+}
+
+static int id_compare(const void *pkey1, const void *pkey2)
+{
+ int32_t key1 = *(int32_t *)pkey1;
+ int32_t key2 = *(int32_t *)pkey2;
+
+ return (key1 == key2) ? 0 : ((key1 < key2) ? -1 : 1);
+}
+
+static const char *get_display_name(mrp_wayland_t *wl)
+{
+ const char *display_name;
+
+ MRP_ASSERT(wl, "invalid argument");
+
+ if (wl->display_name)
+ return wl->display_name;
+
+ if ((display_name = getenv("WAYLAND_DISPLAY")) != NULL)
+ return display_name;
+
+ return "wayland-0";
+}
+
+static void display_io_watch(mrp_io_watch_t *iow,
+ int fd,
+ mrp_io_event_t events,
+ void *ud)
+{
+ mrp_wayland_t *wl = (mrp_wayland_t *)ud;
+ char evnam[32];
+ char evlist[1024];
+ char *p, *e;
+
+ MRP_UNUSED(fd);
+
+ MRP_ASSERT(wl, "invalid user data");
+ MRP_ASSERT(iow == wl->iow, "mismatching io watch");
+
+ if ((events & MRP_IO_EVENT_HUP)) {
+ mrp_log_info("display '%s' is gone", get_display_name(wl));
+
+ wl_registry_destroy(wl->registry);
+ wl_display_disconnect(wl->display);
+
+ return;
+ }
+
+ if ((events & MRP_IO_EVENT_ERR)) {
+ mrp_log_error("I/O error on display '%s'", get_display_name(wl));
+ return;
+ }
+
+ if ((events & MRP_IO_EVENT_IN)) {
+ events &= ~MRP_IO_EVENT_IN;
+
+ mrp_debug("dispatching inputs from display '%s'",get_display_name(wl));
+
+ if (wl_display_dispatch(wl->display) < 0) {
+ mrp_log_error("failed to dispatch events of display '%s'",
+ get_display_name(wl));
+ }
+
+ wl_display_flush(wl->display);
+ }
+
+ if (events) {
+# define PRINT(w) \
+ if (p < e) { \
+ p += snprintf(p, e-p, "%s%s", p > evlist ? " " : "", w); \
+ }
+# define CHECK_EVENT(e) \
+ if ((events & MRP_IO_EVENT_ ## e)) { \
+ char *evnam = #e; \
+ PRINT(evnam); \
+ events &= ~MRP_IO_EVENT_ ## e; \
+ }
+
+ e = (p = evlist) + (sizeof(evlist) - 1);
+
+ CHECK_EVENT(PRI);
+ CHECK_EVENT(OUT);
+
+ if (events) {
+ snprintf(evnam, sizeof(evnam), "<unknown 0x%x>", events);
+ PRINT(evnam);
+ }
+
+ mrp_debug("unhandled io events: %s", evlist);
+
+# undef CHECK_EVENT
+# undef PRINT
+ }
+}
+
+static void object_create(mrp_wayland_interface_t *wif,
+ uint32_t name,
+ uint32_t version)
+{
+ mrp_wayland_t *wl;
+ mrp_wayland_factory_t *factory;
+ mrp_wayland_object_t *obj;
+ struct wl_proxy *proxy;
+
+ MRP_ASSERT(wif, "invalid argument");
+
+ wl = wif->wl;
+ factory = &wif->object_factory;
+
+ if (!(obj = mrp_allocz(factory->size))) {
+ mrp_log_error("can't allocate %zd byte memory for %u/'%s' object",
+ factory->size, (unsigned int)name, wif->name);
+ return;
+ }
+
+ proxy = wl_registry_bind(wl->registry, name, factory->interface, 1);
+
+ if (!proxy) {
+ mrp_log_error("failed to create proxy for object %u/'%s' on "
+ "display '%s'", name, wif->name, get_display_name(wl));
+ mrp_free(obj);
+ return;
+ }
+
+ mrp_list_init(&obj->interface_link);
+ obj->interface = wif;
+ obj->name = name;
+ obj->version = version;
+ obj->proxy = proxy;
+
+ if (factory->constructor) {
+ if (!factory->constructor(wl, obj)) {
+ mrp_log_error("failed to construct object %u/'%s' on "
+ "display '%s'",name,wif->name, get_display_name(wl));
+ wl_proxy_destroy(proxy);
+ mrp_free(obj);
+ }
+ }
+
+ /* TODO: register the object by name */
+
+ mrp_debug("object %u/'%s' on display '%s' created", name, wif->name,
+ get_display_name(wl));
+}
+
+
+static void global_available_callback(void *data,
+ struct wl_registry *registry,
+ uint32_t name,
+ const char *interface,
+ uint32_t version)
+{
+ mrp_wayland_t *wl = (mrp_wayland_t *)data;
+ mrp_wayland_interface_t *wif;
+
+ MRP_ASSERT(wl && registry && interface, "invalid argument");
+ MRP_ASSERT(registry == wl->registry, "confused with data structures");
+
+ wif = mrp_htbl_lookup(wl->interfaces, (void *)interface);
+
+ mrp_debug("object %u/%s is up%s", name, interface,
+ wif ? "" : " (interface unknown)");
+
+ if (wif) {
+ MRP_ASSERT(wif->wl == wl, "confused with data structures");
+ object_create(wif, name, version);
+ }
+}
+
+static void global_remove_callback(void *data,
+ struct wl_registry *wl_registry,
+ uint32_t name)
+{
+ MRP_UNUSED(data);
+ MRP_UNUSED(wl_registry);
+
+ mrp_debug("object %u is down", name);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_H__
+#define __MURPHY_WAYLAND_H__
+
+#include <wayland-client.h>
+
+#include <murphy/common/hashtbl.h>
+
+#include "data-types.h"
+
+#define MRP_WAYLAND_INTERFACE_MAX 64
+#define MRP_WAYLAND_OUTPUT_MAX 16
+#define MRP_WAYLAND_WINDOW_MAX 256
+#define MRP_WAYLAND_LAYER_MAX 32
+#define MRP_WAYLAND_LAYER_BUILTIN 8
+#define MRP_WAYLAND_AREA_MAX 32
+#define MRP_WAYLAND_FRAMERATE_MAX 100
+
+#define MRP_WAYLAND_INTERFACE_BUCKETS (MRP_WAYLAND_INTERFACE_MAX / 2)
+#define MRP_WAYLAND_OUTPUT_BUCKETS (MRP_WAYLAND_OUTPUT_MAX / 4)
+#define MRP_WAYLAND_WINDOW_BUCKETS (MRP_WAYLAND_WINDOW_MAX / 2)
+#define MRP_WAYLAND_LAYER_BUCKETS ((MRP_WAYLAND_LAYER_MAX + \
+ MRP_WAYLAND_LAYER_BUILTIN)/ 4)
+#define MRP_WAYLAND_AREA_BUCKETS (MRP_WAYLAND_AREA_MAX / 4)
+
+#define MRP_WAYLAND_NO_UPDATE INT32_MIN
+
+#define MRP_WAYLAND_OBJECT_COMMON \
+ mrp_list_hook_t interface_link; \
+ mrp_wayland_interface_t *interface; \
+ uint32_t name; \
+ uint32_t version; \
+ struct wl_proxy *proxy
+
+
+typedef enum mrp_sysctl_scripting_field_e mrp_wayland_scripting_field_t;
+typedef enum mrp_wayland_output_operation_e mrp_wayland_output_operation_t;
+typedef enum mrp_wayland_output_update_mask_e mrp_wayland_output_update_mask_t;
+typedef enum mrp_wayland_layer_type_e mrp_wayland_layer_type_t;
+typedef enum mrp_wayland_layer_operation_e mrp_wayland_layer_operation_t;
+typedef enum mrp_wayland_layer_update_mask_e mrp_wayland_layer_update_mask_t;
+typedef enum mrp_wayland_window_update_mask_e mrp_wayland_window_update_mask_t;
+typedef enum mrp_wayland_window_operation_e mrp_wayland_window_operation_t;
+typedef enum mrp_wayland_animation_type_e mrp_wayland_animation_type_t;
+typedef enum mrp_wayland_active_e mrp_wayland_active_t;
+typedef enum mrp_wayland_area_operation_e mrp_wayland_area_operation_t;
+typedef enum mrp_wayland_area_align_e mrp_wayland_area_align_t;
+typedef enum mrp_wayland_area_update_mask_e mrp_wayland_area_update_mask_t;
+
+typedef struct mrp_wayland_s mrp_wayland_t;
+typedef struct mrp_wayland_factory_s mrp_wayland_factory_t;
+typedef struct mrp_wayland_interface_s mrp_wayland_interface_t;
+typedef struct mrp_wayland_object_s mrp_wayland_object_t;
+typedef struct mrp_wayland_animation_s mrp_wayland_animation_t;
+typedef struct mrp_wayland_output_s mrp_wayland_output_t;
+typedef struct mrp_wayland_output_update_s mrp_wayland_output_update_t;
+typedef struct mrp_wayland_layer_s mrp_wayland_layer_t;
+typedef struct mrp_wayland_layer_update_s mrp_wayland_layer_update_t;
+typedef struct mrp_wayland_window_s mrp_wayland_window_t;
+typedef struct mrp_wayland_window_update_s mrp_wayland_window_update_t;
+typedef struct mrp_wayland_area_s mrp_wayland_area_t;
+typedef struct mrp_wayland_area_update_s mrp_wayland_area_update_t;
+typedef struct mrp_wayland_window_manager_s mrp_wayland_window_manager_t;
+typedef struct mrp_wayland_input_manager_s mrp_wayland_input_manager_t;
+
+#include "application/application.h"
+
+typedef bool (*mrp_wayland_constructor_t)(mrp_wayland_t *,
+ mrp_wayland_object_t *);
+typedef void (*mrp_wayland_destructor_t)(mrp_wayland_object_t *);
+
+typedef void (*mrp_wayland_output_update_callback_t)(mrp_wayland_t *,
+ mrp_wayland_output_operation_t,
+ mrp_wayland_output_update_mask_t,
+ mrp_wayland_output_t *);
+typedef void (*mrp_wayland_layer_update_callback_t)(mrp_wayland_t *,
+ mrp_wayland_layer_operation_t,
+ mrp_wayland_layer_update_mask_t,
+ mrp_wayland_layer_t *);
+typedef void (*mrp_wayland_area_update_callback_t)(mrp_wayland_t *,
+ mrp_wayland_area_operation_t,
+ mrp_wayland_area_update_mask_t,
+ mrp_wayland_area_t *);
+typedef void (*mrp_wayland_window_update_callback_t)(mrp_wayland_t *,
+ mrp_wayland_window_operation_t,
+ mrp_wayland_window_update_mask_t,
+ mrp_wayland_window_t *);
+typedef void (*mrp_wayland_app_update_callback_t)(mrp_wayland_t *,
+ mrp_application_operation_t,
+ mrp_application_update_mask_t,
+ mrp_application_t *);
+
+
+struct mrp_wayland_s {
+ const char *display_name;
+
+ mrp_mainloop_t *ml;
+ mrp_io_watch_t *iow;
+
+ struct wl_display *display;
+ struct wl_registry *registry;
+
+ struct wl_registry_listener registry_listener;
+
+ mrp_htbl_t *interfaces;
+ mrp_htbl_t *outputs;
+ mrp_htbl_t *windows;
+ mrp_htbl_t *layers;
+ mrp_htbl_t *areas;
+
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_input_manager_t *im;
+
+ mrp_wayland_output_update_callback_t output_update_callback;
+ mrp_wayland_window_update_callback_t window_update_callback;
+ mrp_wayland_layer_update_callback_t layer_update_callback;
+ mrp_wayland_area_update_callback_t area_update_callback;
+ mrp_wayland_app_update_callback_t application_update_callback;
+ void *scripting_data;
+
+ bool create_scripting_windows;
+ bool create_scripting_outputs;
+ bool create_scripting_areas;
+ bool create_scripting_layers;
+};
+
+struct mrp_wayland_factory_s {
+ size_t size;
+ const struct wl_interface *interface;
+ mrp_wayland_constructor_t constructor;
+ mrp_wayland_destructor_t destructor;
+};
+
+struct mrp_wayland_interface_s {
+ mrp_wayland_t *wl;
+ const char *name;
+ mrp_wayland_factory_t object_factory;
+ mrp_list_hook_t object_list;
+};
+
+struct mrp_wayland_object_s {
+ MRP_WAYLAND_OBJECT_COMMON;
+};
+
+
+mrp_wayland_t *mrp_wayland_create(const char *display_name,mrp_mainloop_t *ml);
+void mrp_wayland_destroy(mrp_wayland_t *wl);
+
+mrp_wayland_t *mrp_wayland_iterate(void **cursor);
+
+bool mrp_wayland_connect(mrp_wayland_t *wl);
+void mrp_wayland_flush(mrp_wayland_t *wl);
+
+void mrp_wayland_register_window_manager(mrp_wayland_t *wl,
+ mrp_wayland_window_manager_t *wm);
+bool mrp_wayland_register_interface(mrp_wayland_t *wl,
+ mrp_wayland_factory_t *factory);
+void mrp_wayland_register_output_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_output_update_callback_t callback);
+void mrp_wayland_register_window_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_update_callback_t callback);
+void mrp_wayland_register_layer_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_layer_update_callback_t callback);
+void mrp_wayland_register_area_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_area_update_callback_t callback);
+void mrp_wayland_set_scripting_data(mrp_wayland_t *, void *);
+
+void mrp_wayland_create_scripting_windows(mrp_wayland_t *wl, bool create);
+void mrp_wayland_create_scripting_outputs(mrp_wayland_t *wl, bool create);
+void mrp_wayland_create_scripting_areas(mrp_wayland_t *wl, bool create);
+void mrp_wayland_create_scripting_layers(mrp_wayland_t *wl, bool create);
+
+#define mrp_wayland_foreach(_wl, _i) \
+ for ((_i) = NULL; (_wl = mrp_wayland_iterate(&(_i)));)
+
+#endif /* __MURPHY_WAYLAND_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_WINDOW_MANAGER_H__
+#define __MURPHY_WAYLAND_WINDOW_MANAGER_H__
+
+#include <sys/types.h>
+
+#include "wayland/wayland.h"
+
+#define MRP_WAYLAND_WINDOW_MANAGER_COMMON \
+ MRP_WAYLAND_OBJECT_COMMON; \
+ void (*layer_request)(mrp_wayland_layer_t *, \
+ mrp_wayland_layer_update_t *); \
+ void (*window_request)(mrp_wayland_window_t *, \
+ mrp_wayland_window_update_t *, \
+ mrp_wayland_animation_t *, \
+ uint32_t)
+
+struct mrp_wayland_window_manager_s {
+ MRP_WAYLAND_WINDOW_MANAGER_COMMON;
+};
+
+#endif /* __MURPHY_WAYLAND_WINDOW_MANAGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "window.h"
+#include "layer.h"
+#include "animation.h"
+#include "window-manager.h"
+#include "area.h"
+#include "scripting-wayland.h"
+
+typedef struct {
+ mrp_wayland_window_t *win;
+ int32_t state;
+} update_active_t;
+
+static mrp_wayland_window_update_mask_t update(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *);
+
+static mrp_wayland_window_update_mask_t set_appid(mrp_wayland_window_t *,
+ mrp_wayland_window_update_t *);
+
+static char *active_str(mrp_wayland_active_t, char *, size_t);
+
+
+mrp_wayland_window_t *
+mrp_wayland_window_create(mrp_wayland_t *wl, mrp_wayland_window_update_t *u)
+{
+ mrp_wayland_window_t *win;
+ mrp_wayland_window_update_mask_t mask;
+ char buf[2048];
+
+ MRP_ASSERT(wl && u && (u->mask & MRP_WAYLAND_WINDOW_SURFACEID_MASK),
+ "invalid argument");
+
+ if (!wl->wm) {
+ mrp_log_error("failed to create window %d: no window manager",
+ u->surfaceid);
+ return NULL;
+ }
+
+ if (!(win = mrp_allocz(sizeof(mrp_wayland_window_t)))) {
+ mrp_log_error("failed to create window %d: out of memory",
+ u->surfaceid);
+ return NULL;
+ }
+
+ win->wm = wl->wm;
+ win->surfaceid = u->surfaceid;
+ win->name = mrp_strdup("");
+ win->appid = mrp_strdup("");
+ win->nodeid = -1;
+ win->x = win->y = -1;
+ win->width = win->height = -1;
+
+ if (!mrp_htbl_insert(wl->windows, &win->surfaceid, win)) {
+ mrp_log_error("failed to create window: already exists");
+ mrp_free(win->name);
+ mrp_free(win->appid);
+ mrp_free(win);
+ return NULL;
+ }
+
+ if (wl->create_scripting_windows) {
+ win->scripting_data = mrp_wayland_scripting_window_create_from_c(NULL,
+ win);
+ }
+
+ mask = update(win, u);
+
+ mrp_wayland_window_print(win, mask, buf,sizeof(buf));
+ mrp_debug("window %d created%s", win->surfaceid, buf);
+
+ if (win->scripting_data && wl->window_update_callback)
+ wl->window_update_callback(wl, MRP_WAYLAND_WINDOW_CREATE, mask, win);
+
+ return win;
+}
+
+void mrp_wayland_window_destroy(mrp_wayland_window_t *win)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_interface_t *interface;
+ mrp_wayland_t *wl;
+ char buf[1024];
+
+ MRP_ASSERT(win && win->wm && win->wm->interface &&
+ win->wm->interface->wl, "invalid argument");
+
+ wm = win->wm;
+ interface = wm->interface;
+ wl = interface->wl;
+
+ mrp_wayland_window_print(win, MRP_WAYLAND_WINDOW_APPID_MASK |
+ MRP_WAYLAND_WINDOW_NAME_MASK,
+ buf, sizeof(buf));
+ mrp_debug("destroying window %d%s", win->surfaceid, buf);
+
+ if (win->scripting_data) {
+ if (wl->window_update_callback)
+ wl->window_update_callback(wl, MRP_WAYLAND_WINDOW_DESTROY, 0, win);
+
+ mrp_wayland_scripting_window_destroy_from_c(NULL, win);
+ }
+
+
+ mrp_free(win->name);
+ mrp_free(win->appid);
+
+ if ((void *)win != mrp_htbl_remove(wl->windows, &win->surfaceid, false)) {
+ mrp_log_error("failed to destroy window %d: confused with "
+ "data structures", win->surfaceid);
+ return;
+ }
+
+ free(win);
+}
+
+mrp_wayland_window_t *mrp_wayland_window_find(mrp_wayland_t *wl,
+ int32_t surfaceid)
+{
+ MRP_ASSERT(wl, "invalid argument");
+
+ return (mrp_wayland_window_t *)mrp_htbl_lookup(wl->windows, &surfaceid);
+}
+
+
+#if 0
+void mrp_wayland_window_visibility_request(mrp_wayland_window_t *win,
+ int32_t visible,
+ int32_t raise,
+ const char *animation,
+ int32_t time)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_window_update_t u;
+ mrp_wayland_animation_t *anims;
+ mrp_wayland_animation_type_t at;
+
+ MRP_ASSERT(win && win->wm, "invalid argument");
+
+ wm = win->wm;
+
+ memset(&u, 0, sizeof(u));
+
+ if (visible >= 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_VISIBLE_MASK;
+ u.visible = visible ? true : false;
+ }
+
+ if (raise >= 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_RAISE_MASK;
+ u.raise = raise ? true : false;
+ }
+
+ if ((anims = mrp_wayland_animation_create())) {
+ at = visible ? MRP_WAYLAND_ANIMATION_SHOW : MRP_WAYLAND_ANIMATION_HIDE;
+ mrp_wayland_animation_set(anims, at, animation, time);
+ }
+
+ wm->window_request(win, &u, anims, 0);
+
+ mrp_wayland_animation_destroy(anims);
+}
+
+void mrp_wayland_window_active_request(mrp_wayland_window_t *win,
+ mrp_wayland_active_t active)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(win && win->wm, "invalid argument");
+
+ wm = win->wm;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_ACTIVE_MASK;
+ u.active = active;
+
+ wm->window_request(win, &u, NULL, 0);
+}
+
+void mrp_wayland_window_map_request(mrp_wayland_window_t *win,
+ bool map,
+ uint32_t framerate)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(win && win->wm && framerate <= MRP_WAYLAND_FRAMERATE_MAX,
+ "invalid argument");
+
+ wm = win->wm;
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_MAPPED_MASK;
+ u.mapped = map;
+
+ wm->window_request(win, &u, NULL, framerate);
+}
+
+void mrp_wayland_window_geometry_request(mrp_wayland_window_t *win,
+ int32_t nodeid,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height,
+ const char *move_animation,
+ int32_t move_time,
+ const char *resize_animation,
+ int32_t resize_time)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_window_update_t u;
+ mrp_wayland_animation_t *anims;
+ bool have_move_animation;
+ bool have_resize_animation;
+
+ MRP_ASSERT(win && win->wm, "invalid argument");
+
+ wm = win->wm;
+
+ memset(&u, 0, sizeof(u));
+
+ if (nodeid >= 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_NODEID_MASK;
+ u.nodeid = nodeid;
+ }
+ else if (win->nodeid >= 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_NODEID_MASK;
+ u.nodeid = win->nodeid;
+ }
+
+ if (x != MRP_WAYLAND_NO_UPDATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_X_MASK;
+ u.x = x;
+ }
+ if (y != MRP_WAYLAND_NO_UPDATE) {
+ u.mask |= MRP_WAYLAND_WINDOW_Y_MASK;
+ u.y = y;
+ }
+
+ if (width > 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_WIDTH_MASK;
+ u.width = width;
+ }
+ if (height > 0) {
+ u.mask |= MRP_WAYLAND_WINDOW_HEIGHT_MASK;
+ u.height = height;
+ }
+
+ have_move_animation = (move_animation && move_animation[0] &&
+ move_time > 0);
+ have_resize_animation = (resize_animation && resize_animation[0] &&
+ resize_time > 0);
+
+ if (!have_move_animation && !have_resize_animation)
+ anims = NULL;
+ else {
+ if ((anims = mrp_wayland_animation_create())) {
+ if (have_move_animation) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_MOVE,
+ move_animation, move_time);
+ }
+ if (have_resize_animation) {
+ mrp_wayland_animation_set(anims, MRP_WAYLAND_ANIMATION_RESIZE,
+ resize_animation, resize_time);
+ }
+ }
+ }
+
+ wm->window_request(win, &u, NULL, 0);
+
+ mrp_wayland_animation_destroy(anims);
+}
+
+
+void mrp_wayland_window_layer_request(mrp_wayland_window_t *win,
+ int32_t layerid)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_t *wl;
+ mrp_wayland_layer_t *layer;
+ mrp_wayland_window_update_t u;
+
+ MRP_ASSERT(win && win->wm && win->wm->interface && win->wm->interface->wl,
+ "invalid argument");
+
+ wm = win->wm;
+ wl = wm->interface->wl;
+
+ if (!(layer = mrp_wayland_layer_find(wl, layerid))) {
+ mrp_log_error("can't find layer %d", layerid);
+ return;
+ }
+
+ memset(&u, 0, sizeof(u));
+ u.mask = MRP_WAYLAND_WINDOW_LAYER_MASK;
+ u.layer = layer;
+
+ wm->window_request(win, &u, NULL, 0);
+}
+#endif
+
+void mrp_wayland_window_request(mrp_wayland_t *wl,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims,
+ uint32_t framerate)
+{
+ mrp_wayland_window_t *win;
+ mrp_wayland_window_manager_t *wm;
+
+ MRP_ASSERT(wl && u, "invalid arguments");
+
+ if (!(u->mask & MRP_WAYLAND_WINDOW_SURFACEID_MASK) ||
+ !(win = mrp_wayland_window_find(wl, u->surfaceid)))
+ {
+ mrp_debug("can't find window %u: request rejected", u->surfaceid);
+ return;
+ }
+
+ MRP_ASSERT(win->wm, "confused with data structures");
+
+ wm = win->wm;
+
+ wm->window_request(win, u, anims, framerate);
+}
+
+static int update_active(void *key, void *object, void *ud)
+{
+ mrp_wayland_window_t *win = (mrp_wayland_window_t *)object;
+ update_active_t *active = (update_active_t *)ud;
+
+ MRP_UNUSED(key);
+
+ if (win != active->win) {
+ if (active->state == 0)
+ win->active = 0;
+ else
+ win->active &= ~active->state;
+
+ mrp_debug("setting window %d 'active' to 0x%x",
+ win->surfaceid, win->active);
+ }
+
+ return MRP_HTBL_ITER_MORE;
+}
+
+void mrp_wayland_window_update(mrp_wayland_window_t *win,
+ mrp_wayland_window_operation_t oper,
+ mrp_wayland_window_update_t *u)
+{
+ mrp_wayland_window_manager_t *wm;
+ mrp_wayland_interface_t *interface;
+ mrp_wayland_t *wl;
+ int32_t surfaceid;
+ mrp_wayland_window_update_mask_t mask;
+ char buf[2048];
+ update_active_t active;
+
+ MRP_ASSERT(win && win->wm && win->wm->interface &&
+ win->wm->interface->wl && u, "invalid argument");
+
+ wm = win->wm;
+ interface = wm->interface;
+ wl = interface->wl;
+
+ surfaceid = win->surfaceid;
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_SURFACEID_MASK)) {
+ if (u->surfaceid != surfaceid) {
+ mrp_log_error("attempt to change surfaceid to %d of "
+ "existing window %d", u->surfaceid, surfaceid);
+ return;
+ }
+ }
+
+ mask = update(win, u);
+
+ if (!mask)
+ mrp_debug("window %d update requested but nothing changed", surfaceid);
+ else {
+ mrp_wayland_window_print(win, mask, buf,sizeof(buf));
+ mrp_debug("window %d updated%s", surfaceid, buf);
+ }
+
+ if (win->scripting_data && wl->window_update_callback)
+ wl->window_update_callback(wl, oper, mask, win);
+
+ if (oper == MRP_WAYLAND_WINDOW_ACTIVE) {
+ active.win = win;
+ active.state = win->active;
+ mrp_htbl_foreach(wl->windows, update_active, &active);
+ }
+}
+
+size_t mrp_wayland_window_print(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_mask_t mask,
+ char *buf,
+ size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ char *p, *e;
+ char as[256];
+
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_WINDOW_NAME_MASK))
+ PRINT("name: '%s'", win->name);
+ if ((mask & MRP_WAYLAND_WINDOW_APPID_MASK))
+ PRINT("appid: '%s'", win->appid);
+ if ((mask & MRP_WAYLAND_WINDOW_PID_MASK))
+ PRINT("pid: %u", win->pid);
+ if ((mask & MRP_WAYLAND_WINDOW_NODEID_MASK))
+ PRINT("nodeid: %d", win->nodeid);
+ if ((mask & MRP_WAYLAND_WINDOW_LAYER_MASK))
+ PRINT("layer: '%s'", win->layer ? win->layer->name : "<not set>");
+ if ((mask & MRP_WAYLAND_WINDOW_POSITION_MASK))
+ PRINT("position: %d,%d", win->x, win->y);
+ if ((mask & MRP_WAYLAND_WINDOW_SIZE_MASK))
+ PRINT("size: %dx%d", win->width, win->height);
+ if ((mask & MRP_WAYLAND_WINDOW_VISIBLE_MASK))
+ PRINT("visible: %s", win->visible ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_RAISE_MASK))
+ PRINT("raise: %s", win->raise ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_MAPPED_MASK))
+ PRINT("mapped: %s", win->mapped ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_ACTIVE_MASK)) {
+ PRINT("active: 0x%x =%s", win->active, active_str(win->active,
+ as, sizeof(as)));
+ }
+ if ((mask & MRP_WAYLAND_WINDOW_LAYERTYPE_MASK)) {
+ PRINT("layertype: %d - %s",win->layertype,
+ mrp_wayland_layer_type_str(win->layertype));
+ }
+ if ((mask & MRP_WAYLAND_WINDOW_APP_MASK)) {
+ PRINT("application: '%s'", win->application ? win->application->appid :
+ "<unknown>");
+ }
+ if ((mask & MRP_WAYLAND_WINDOW_AREA_MASK)) {
+ PRINT("area: '%s'", win->area ? win->area->name : "<unknown>");
+ }
+
+ return p - buf;
+
+#undef PRINT
+}
+
+size_t mrp_wayland_window_request_print(mrp_wayland_window_update_t *u,
+ char *buf, size_t len)
+{
+#define PRINT(fmt, args...) \
+ if (p < e) { p += snprintf(p, e-p, "\n " fmt , ## args); }
+
+ mrp_wayland_window_update_mask_t mask;
+ char *p, *e;
+ char as[256];
+
+ mask = u->mask;
+ e = (p = buf) + len;
+
+ *p = 0;
+
+ if ((mask & MRP_WAYLAND_WINDOW_NAME_MASK))
+ PRINT("name: '%s'", u->name);
+ if ((mask & MRP_WAYLAND_WINDOW_APPID_MASK))
+ PRINT("appid: '%s'", u->appid);
+ if ((mask & MRP_WAYLAND_WINDOW_PID_MASK))
+ PRINT("pid: %u", u->pid);
+ if ((mask & MRP_WAYLAND_WINDOW_NODEID_MASK))
+ PRINT("nodeid: %d", u->nodeid);
+ if ((mask & MRP_WAYLAND_WINDOW_LAYER_MASK))
+ PRINT("layer: '%s'", u->layer ? u->layer->name : "<not set>");
+ if ((mask & MRP_WAYLAND_WINDOW_POSITION_MASK))
+ PRINT("position: %d,%d", u->x, u->y);
+ if ((mask & MRP_WAYLAND_WINDOW_SIZE_MASK))
+ PRINT("size: %dx%d", u->width, u->height);
+ if ((mask & MRP_WAYLAND_WINDOW_VISIBLE_MASK))
+ PRINT("visible: %s", u->visible ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_RAISE_MASK))
+ PRINT("raise: %s", u->raise ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_MAPPED_MASK))
+ PRINT("mapped: %s", u->mapped ? "yes" : "no");
+ if ((mask & MRP_WAYLAND_WINDOW_ACTIVE_MASK)) {
+ PRINT("active: 0x%x =%s", u->active, active_str(u->active,
+ as, sizeof(as)));
+ }
+ if ((mask & MRP_WAYLAND_WINDOW_LAYERTYPE_MASK)) {
+ PRINT("layertype: %d - %s", u->layertype,
+ mrp_wayland_layer_type_str(u->layertype));
+ }
+
+ return p - buf;
+
+#undef PRINT
+}
+
+const char *
+mrp_wayland_window_update_mask_str(mrp_wayland_window_update_mask_t mask)
+{
+ switch (mask) {
+ case MRP_WAYLAND_WINDOW_SURFACEID_MASK: return "surfaceid";
+ case MRP_WAYLAND_WINDOW_NAME_MASK: return "name";
+ case MRP_WAYLAND_WINDOW_APPID_MASK: return "appid";
+ case MRP_WAYLAND_WINDOW_PID_MASK: return "pid";
+ case MRP_WAYLAND_WINDOW_NODEID_MASK: return "nodeid";
+ case MRP_WAYLAND_WINDOW_LAYER_MASK: return "layer";
+ case MRP_WAYLAND_WINDOW_X_MASK: return "x";
+ case MRP_WAYLAND_WINDOW_Y_MASK: return "y";
+ case MRP_WAYLAND_WINDOW_POSITION_MASK: return "position";
+ case MRP_WAYLAND_WINDOW_WIDTH_MASK: return "width";
+ case MRP_WAYLAND_WINDOW_HEIGHT_MASK: return "height";
+ case MRP_WAYLAND_WINDOW_SIZE_MASK: return "size";
+ case MRP_WAYLAND_WINDOW_VISIBLE_MASK: return "visible";
+ case MRP_WAYLAND_WINDOW_RAISE_MASK: return "raise";
+ case MRP_WAYLAND_WINDOW_ACTIVE_MASK: return "active";
+ case MRP_WAYLAND_WINDOW_MAPPED_MASK: return "mapped";
+ case MRP_WAYLAND_WINDOW_LAYERTYPE_MASK: return "layertype";
+ case MRP_WAYLAND_WINDOW_APP_MASK: return "application";
+ case MRP_WAYLAND_WINDOW_AREA_MASK: return "area";
+ default: return "<unknown>";
+ }
+}
+
+void mrp_wayland_window_set_scripting_data(mrp_wayland_window_t *win,
+ void *data)
+{
+ MRP_ASSERT(win, "Invalid Argument");
+
+ mrp_debug("%sset scripting data", data ? "" : "re");
+
+ win->scripting_data = data;
+}
+
+
+static mrp_wayland_window_update_mask_t update(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u)
+{
+ mrp_wayland_window_update_mask_t mask = 0;
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_NAME_MASK)) {
+ if (!win->name || strcmp(u->name, win->name)) {
+ mask |= MRP_WAYLAND_WINDOW_NAME_MASK;
+ mrp_free(win->name);
+ win->name = mrp_strdup(u->name);
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_APPID_MASK)) {
+ if (!win->appid || strcmp(u->appid, win->appid)) {
+ mask |= MRP_WAYLAND_WINDOW_APPID_MASK;
+ mrp_free(win->appid);
+ win->appid = mrp_strdup(u->appid);
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_PID_MASK)) {
+ if (u->pid != win->pid) {
+ mask |= MRP_WAYLAND_WINDOW_PID_MASK;
+ win->pid = u->pid;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_NODEID_MASK)) {
+ if (u->nodeid != win->nodeid) {
+ mask |= MRP_WAYLAND_WINDOW_NODEID_MASK;
+ win->nodeid = u->nodeid;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_LAYER_MASK)) {
+ if (u->layer != win->layer) {
+ mask |= MRP_WAYLAND_WINDOW_LAYER_MASK;
+ win->layer = u->layer;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_X_MASK)) {
+ if (u->x != win->x) {
+ mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
+ win->x = u->x;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_Y_MASK)) {
+ if (u->y != win->y) {
+ mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
+ win->y = u->y;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_WIDTH_MASK)) {
+ if (u->width != win->width) {
+ mask |= MRP_WAYLAND_WINDOW_SIZE_MASK;
+ win->width = u->width;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_HEIGHT_MASK)) {
+ if (u->height != win->height) {
+ mask |= MRP_WAYLAND_WINDOW_SIZE_MASK;
+ win->height = u->height;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_VISIBLE_MASK)) {
+ if ((u->visible && !win->visible) || (!u->visible && win->visible)) {
+ mask |= MRP_WAYLAND_WINDOW_VISIBLE_MASK |
+ MRP_WAYLAND_WINDOW_RAISE_MASK ;
+ win->visible = u->visible;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_RAISE_MASK)) {
+ if ((u->raise && !win->raise) || (!u->raise && win->raise)) {
+ mask |= MRP_WAYLAND_WINDOW_RAISE_MASK |
+ MRP_WAYLAND_WINDOW_VISIBLE_MASK ;
+ win->raise = u->raise;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_MAPPED_MASK)) {
+ if ((u->mapped && !win->mapped) || (!u->mapped && win->mapped)) {
+ mask |= MRP_WAYLAND_WINDOW_MAPPED_MASK;
+ win->mapped = u->mapped;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_ACTIVE_MASK)) {
+ if ((u->active && !win->active) || (!u->active && win->active)) {
+ mask |= MRP_WAYLAND_WINDOW_ACTIVE_MASK;
+ win->active = u->active;
+ }
+ }
+
+ if ((u->mask & MRP_WAYLAND_WINDOW_LAYERTYPE_MASK)) {
+ if ((u->layertype != win->layertype)) {
+ mask |= MRP_WAYLAND_WINDOW_LAYERTYPE_MASK;
+ win->layertype = u->layertype;
+ }
+ }
+
+ if ((mask & MRP_WAYLAND_WINDOW_APPID_MASK)) {
+ mask |= set_appid(win, u);
+ }
+
+ return mask;
+}
+
+static mrp_wayland_window_update_mask_t set_appid(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_t *u)
+{
+ mrp_wayland_window_update_mask_t mask = 0;
+ mrp_wayland_window_manager_t *wm = win->wm;
+ mrp_wayland_window_update_t u2;
+
+ if (win->application || !u->appid)
+ return mask;
+
+ win->application = mrp_application_find(win->appid);
+ win->area = NULL;
+
+ if (!win->application)
+ win->application = mrp_application_find("default");
+
+ if (!win->application) {
+ mrp_log_error("system-controller: can't find application '%s'",
+ win->appid);
+ return mask;
+ }
+
+ mrp_debug("found application '%s'", win->application->appid);
+
+ mask |= MRP_WAYLAND_WINDOW_APP_MASK;
+
+ memset(&u2, 0, sizeof(u2));
+
+ if (!(u2.area = win->application->area)) {
+ mrp_log_error("system-controller: no area for application '%s'",
+ win->application->appid);
+ return mask;
+ }
+
+ mrp_debug("found area '%s'", u2.area->name);
+
+ u2.mask |= MRP_WAYLAND_WINDOW_AREA_MASK;
+
+ if (!(mask & MRP_WAYLAND_WINDOW_POSITION_MASK)) {
+ u2.mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
+ u2.x = u2.area->x;
+ u2.y = u2.area->y;
+ }
+
+ if (!(mask & MRP_WAYLAND_WINDOW_SIZE_MASK)) {
+ u2.mask |= MRP_WAYLAND_WINDOW_SIZE_MASK;
+ u2.width = u2.area->width;
+ u2.height = u2.area->height;
+ }
+
+ wm->window_request(win, &u2, NULL, 0);
+
+ if ((u2.mask & MRP_WAYLAND_WINDOW_POSITION_MASK)) {
+ mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
+ win->x = u2.x;
+ win->y = u2.y;
+ }
+
+ if ((u2.mask & MRP_WAYLAND_WINDOW_SIZE_MASK)) {
+ mask |= MRP_WAYLAND_WINDOW_SIZE_MASK;
+ win->width = u2.width;
+ win->height = u2.height;
+ }
+
+ return mask;
+}
+
+
+static char *active_str(mrp_wayland_active_t active, char *buf, size_t len)
+{
+#define PRINT(fmt, args... ) \
+ if (p < e) { p += snprintf(p, e-p, " " fmt , ## args); }
+
+ typedef struct {
+ mrp_wayland_active_t mask;
+ const char *name;
+ } map_t;
+
+ static map_t map[] = {
+ { MRP_WAYLAND_WINDOW_ACTIVE_POINTER, "pointer" },
+ { MRP_WAYLAND_WINDOW_ACTIVE_KEYBOARD, "keyboard" },
+ { MRP_WAYLAND_WINDOW_ACTIVE_SELECTED, "selected" },
+ { 0, NULL }
+ };
+
+ map_t *m;
+ char *p, *e;
+
+ e = (p = buf) + len;
+
+ if (!active) {
+ PRINT("<none>");
+ }
+ else {
+ for (m = map; active && m->name; m++) {
+ if ((active & m->mask)) {
+ PRINT("%s", m->name);
+ active &= ~m->mask;
+ }
+ }
+
+ if (active)
+ PRINT("<unknown 0x%x>", active);
+ }
+
+ return buf;
+
+#undef PRINT
+}
--- /dev/null
+/*
+ * Copyright (c) 2013, Intel Corporation
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Intel Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MURPHY_WAYLAND_WINDOW_H__
+#define __MURPHY_WAYLAND_WINDOW_H__
+
+#include <sys/types.h>
+
+#include "wayland/layer.h"
+
+enum mrp_wayland_active_e {
+ MRP_WAYLAND_WINDOW_ACTIVE_NONE = 0,
+ MRP_WAYLAND_WINDOW_ACTIVE_POINTER = 1,
+ MRP_WAYLAND_WINDOW_ACTIVE_KEYBOARD = 2,
+ MRP_WAYLAND_WINDOW_ACTIVE_SELECTED = 4,
+};
+
+enum mrp_wayland_window_operation_e {
+ MRP_WAYLAND_WINDOW_OPERATION_NONE = 0,
+ MRP_WAYLAND_WINDOW_CREATE, /* 1 */
+ MRP_WAYLAND_WINDOW_DESTROY, /* 2 */
+ MRP_WAYLAND_WINDOW_NAMECHANGE, /* 3 */
+ MRP_WAYLAND_WINDOW_VISIBLE, /* 4 */
+ MRP_WAYLAND_WINDOW_CONFIGURE, /* 5 */
+ MRP_WAYLAND_WINDOW_ACTIVE /* 6 */
+};
+
+
+struct mrp_wayland_window_s {
+ mrp_wayland_window_manager_t *wm;
+ int32_t surfaceid;
+ char *name;
+
+ char *appid;
+ pid_t pid;
+
+ int32_t nodeid;
+ mrp_wayland_layer_t *layer;
+ int32_t x, y;
+ int32_t width, height;
+ bool visible;
+ bool raise;
+ bool mapped;
+ mrp_wayland_active_t active;
+ mrp_wayland_layer_type_t layertype;
+
+ mrp_application_t *application;
+ mrp_wayland_area_t *area;
+
+ void *scripting_data;
+};
+
+
+enum mrp_wayland_window_update_mask_e {
+ MRP_WAYLAND_WINDOW_SURFACEID_MASK = 0x00001,
+ MRP_WAYLAND_WINDOW_NAME_MASK = 0x00002,
+ MRP_WAYLAND_WINDOW_APPID_MASK = 0x00004,
+ MRP_WAYLAND_WINDOW_PID_MASK = 0x00008,
+ MRP_WAYLAND_WINDOW_NODEID_MASK = 0x00010,
+ MRP_WAYLAND_WINDOW_LAYER_MASK = 0x00020,
+ MRP_WAYLAND_WINDOW_X_MASK = 0x00040,
+ MRP_WAYLAND_WINDOW_Y_MASK = 0x00080,
+ MRP_WAYLAND_WINDOW_POSITION_MASK = 0x000C0,
+ MRP_WAYLAND_WINDOW_WIDTH_MASK = 0x00100,
+ MRP_WAYLAND_WINDOW_HEIGHT_MASK = 0x00200,
+ MRP_WAYLAND_WINDOW_SIZE_MASK = 0x00300,
+ MRP_WAYLAND_WINDOW_VISIBLE_MASK = 0x00400,
+ MRP_WAYLAND_WINDOW_RAISE_MASK = 0x00800,
+ MRP_WAYLAND_WINDOW_MAPPED_MASK = 0x01000,
+ MRP_WAYLAND_WINDOW_ACTIVE_MASK = 0x02000,
+ MRP_WAYLAND_WINDOW_LAYERTYPE_MASK = 0x04000,
+ MRP_WAYLAND_WINDOW_APP_MASK = 0x08000,
+ MRP_WAYLAND_WINDOW_AREA_MASK = 0x10000,
+
+ MRP_WAYLAND_WINDOW_END_MASK = 0x20000
+};
+
+
+struct mrp_wayland_window_update_s {
+ mrp_wayland_window_update_mask_t mask;
+ int32_t surfaceid;
+ const char *name;
+ const char *appid;
+ pid_t pid;
+ int32_t nodeid;
+ mrp_wayland_layer_t *layer;
+ int32_t x, y;
+ int32_t width, height;
+ bool visible;
+ bool raise;
+ bool mapped;
+ mrp_wayland_active_t active;
+ mrp_wayland_layer_type_t layertype;
+ mrp_wayland_area_t *area;
+};
+
+mrp_wayland_window_t *
+mrp_wayland_window_create(mrp_wayland_t *wl, mrp_wayland_window_update_t *u);
+
+void mrp_wayland_window_destroy(mrp_wayland_window_t *win);
+
+mrp_wayland_window_t *mrp_wayland_window_find(mrp_wayland_t *wl,
+ int32_t surfaceid);
+
+#if 0
+void mrp_wayland_window_visibility_request(mrp_wayland_window_t *win,
+ int32_t visible, int32_t raise,
+ const char *animation_name,
+ int32_t animation_time);
+void mrp_wayland_window_active_request(mrp_wayland_window_t *win,
+ mrp_wayland_active_t active);
+void mrp_wayland_window_map_request(mrp_wayland_window_t *win,
+ bool map, uint32_t framerate);
+void mrp_wayland_window_geometry_request(mrp_wayland_window_t *win,
+ int32_t nodeid,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height,
+ const char *move_animation,
+ int32_t move_time,
+ const char *resize_animation,
+ int32_t resize_time);
+void mrp_wayland_window_layer_request(mrp_wayland_window_t *win,
+ int32_t layerid);
+#endif
+
+void mrp_wayland_window_request(mrp_wayland_t *wl,
+ mrp_wayland_window_update_t *u,
+ mrp_wayland_animation_t *anims,
+ uint32_t framerate);
+
+void mrp_wayland_window_update(mrp_wayland_window_t *win,
+ mrp_wayland_window_operation_t oper,
+ mrp_wayland_window_update_t *u);
+
+size_t mrp_wayland_window_print(mrp_wayland_window_t *win,
+ mrp_wayland_window_update_mask_t mask,
+ char *buf,
+ size_t len);
+size_t mrp_wayland_window_request_print(mrp_wayland_window_update_t *u,
+ char *buf, size_t len);
+
+const char *mrp_wayland_window_update_mask_str(
+ mrp_wayland_window_update_mask_t mask);
+
+void mrp_wayland_window_set_scripting_data(mrp_wayland_window_t *win,
+ void *data);
+
+#endif /* __MURPHY_WAYLAND_WINDOW_H__ */
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __MURPHY_DATA_TYPES_H__
-#define __MURPHY_DATA_TYPES_H__
+#ifndef __MURPHY_RESOURCE_DATA_TYPES_H__
+#define __MURPHY_RESOURCE_DATA_TYPES_H__
#include <stdint.h>
#include <stdbool.h>
uint32_t priority;
};
-#endif /* __MURPHY_DATA_TYPES_H__ */
+#endif /* __MURPHY_RESOURCE_DATA_TYPES_H__ */
/*
* Local Variables: