with_system_controller = true
+verbose = 0
m = murphy.get()
-- system controller test setup
-if not with_system_controller or
- not m:plugin_exists('system-controller') then
+if not with_system_controller or not m:plugin_exists('system-controller') then
return
end
m:load_plugin('system-controller')
+window_manager_operation_names = {
+ [1] = "create",
+ [2] = "destroy"
+}
+
+function window_manager_operation_name(oper)
+ local name = window_manager_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
window_operation_names = {
[1] = "create",
[2] = "destroy",
return "<unknown " .. tostring(oper) .. ">"
end
+layer_operation_names = {
+ [1] = "create",
+ [2] = "destroy",
+ [3] = "visible"
+}
+
+function layer_operation_name(oper)
+ local name = layer_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
command_names = {
[0x00001] = "send_appid",
[0x10001] = "create",
[0x10022] = "change_layer_attr",
[0x20001] = "add_input",
[0x20002] = "del_input",
- [0x20003] = "send_input"
+ [0x20003] = "send_input",
+ [0x40001] = "acquire_res",
+ [0x40002] = "release_res",
+ [0x40003] = "deprive_res",
+ [0x40004] = "waiting_res",
+ [0x40005] = "revert_res",
+ [0x40011] = "create_res",
+ [0x40012] = "destroy_res",
+ [0x50001] = "set_region",
+ [0x50002] = "unset_region",
+ [0x60001] = "change_state"
}
function command_name(command)
return "<unknown " .. tostring(command) .. ">"
end
-wmgr = window_manager({
+input_layer = {
+ [3] = true, -- input
+ [4] = true, -- touch
+ [5] = true -- cursor
+}
+
+resmgr = resource_manager {
+ screen_event_handler = function(self, ev)
+ local event = ev.event
+ local surface = ev.surface
+
+ if event == "grant" then
+ if verbose > 0 then
+ print("*** make visible surface "..surface)
+ end
+ local a = animation({})
+ local r = m:JSON({surface = surface,
+ visible = 1,
+ raise = 1})
+ wmgr:window_request(r,a,0)
+ elseif event == "revoke" then
+ if verbose > 0 then
+ print("*** hide surface "..surface)
+ end
+ local a = animation({})
+ local r = m:JSON({surface = ev.surface,
+ visible = 0})
+ wmgr:window_request(r,a,0)
+ else
+ if verbose > 0 then
+ print("*** resource event: "..tostring(ev))
+ end
+ end
+ end
+}
+
+resclnt = resource_client {}
+
+wmgr = window_manager {
geometry = function(self, w,h, v)
if type(v) == "function" then
return v(w,h)
return v
end,
+ application = function(self, appid)
+ if appid then
+ local app = application_lookup(appid)
+ if not app then
+ app = application_lookup("default")
+ end
+ return app
+ end
+ return { privileges = {screen="none", audio="none"} }
+ end,
+
outputs = { { name = "Center",
id = 0,
+ zone = "driver",
areas = { Status = {
- id = 100,
+ id = 0,
pos_x = 0,
pos_y = 0,
width = function(w,h) return w end,
}
},
{ name = "Mid",
+ zone = "driver",
id = 1
}
{ 5, "InterruptApp" , 2 },
{ 6, "OnScreen" , 2 },
{ 101, "Input" , 3 },
- { 102, "Touch" , 4 },
- { 103, "Cursor" , 5 },
+ { 102, "Cursor" , 5 },
+ { 103, "Startup" , 6 },
{ 0x1000, "Background" , 1 },
{ 0x2000, "Normal" , 2 },
{ 0x3000, "Fullscreen" , 2 },
},
+ manager_update = function(self, oper)
+ if verbose > 0 then
+ print("### <== WINDOW MANAGER UPDATE:" ..
+ window_manager_operation_name(oper))
+ end
+ if oper == 1 then
+ local umask = window_mask { raise = true,
+ visible = true,
+ active = true }
+ local rmask = window_mask { active = true }
+ local req = m:JSON({
+ passthrough_update = umask:tointeger(),
+ passthrough_request = rmask:tointeger()
+ })
+ self:manager_request(req)
+ end
+ end,
+
window_update = function(self, oper, win, mask)
- if (verbose) then
- print("*** WINDOW UPDATE oper:"..window_operation_name(oper).." mask: "..tostring(mask))
- print(win)
+ if verbose > 0 then
+ print("### <== WINDOW UPDATE oper:" ..
+ window_operation_name(oper) ..
+ " mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(win)
+ end
end
local arg = m:JSON({ surface = win.surface,
local command = 0
if oper == 1 then -- create
- if win.layertype and win.layertype == 3 then
- print("ignoring input panel window creation")
+ local layertype = win.layertype
+ if layertype and input_layer[layertype] then
+ if verbose > 0 then
+ print("ignoring input panel creation")
+ end
return
end
command = 0x10001
arg.visible = win.visible
arg.active = win.active
elseif oper == 6 then -- active
- if false and win.active ~= 0 then
- print("### already active")
- return
- end
- command = 0x10006
+ command = 0x10006
+ arg.active = win.active
else
- print("### nothing to do")
+ if verbose > 0 then
+ print("### nothing to do")
+ end
return
end
pid = win.pid,
arg = arg
})
- print("### sending window message: " .. command_name(msg.command))
- print(msg)
- sc:send_message(msg.appid, msg)
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(msg.command) ..
+ " window message to '" .. win.name .. "'")
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ sc:send_message(sysctlid, msg)
- if (oper == 1) then -- create
- local a = animation({})
- local r = m:JSON({surface = win.surface,
- visible = 1,
- raise = 1})
- self:window_request(r,a,0)
+ if oper == 1 then -- create
+ local i = input_layer[win.layertype]
+ local p = self:application(win.appid)
+ local s = p.privileges.screen
+
+ if s == "system" then
+ local a = animation({})
+ local r = m:JSON({surface = win.surface,
+ visible = 1,
+ raise = 1})
+ self:window_request(r,a,0)
+ else
+ if i then
+ if verbose > 0 then
+ print("do not make resource for " ..
+ "input window")
+ end
+ else
+ resclnt:resource_set_create("screen",
+ "driver",
+ win.appid,
+ win.surface)
+ end
+ end
+ elseif oper == 2 then -- destroy
+ resclnt:resource_set_destroy("screen", win.surface)
+ elseif oper == 6 then -- active
+ if win.active then
+ local i = input_layer[win.layertype]
+ local p = self:application(win.appid)
+ local s = p.privileges.screen
+ local surface = win.surface
+ if not i and s ~= "system" then
+ resclnt:resource_set_acquire("screen",surface)
+ resmgr:window_raise(win.appid, surface, 1)
+ end
+ end
end
end,
- layer_update = function(self, oper, j, mask)
- if verbose then
- print("*** LAYER UPDATE oper:"..oper.." mask: "..tostring(mask))
- print(j)
+ layer_update = function(self, oper, layer, mask)
+ if verbose > 0 then
+ print("### LAYER UPDATE:" ..
+ layer_operation_name(oper) ..
+ " mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(layer)
+ end
+ end
+ if oper == 3 then -- visible
+ local command = 0x10022
+ local msg = m:JSON({
+ command = command,
+ appid = "",
+ arg = m:JSON({layer = layer.id,
+ visible = layer.visible
+ })
+ })
+ if verbose > 0 then
+ print("### <== sending "..command_name(command)..
+ " layer message")
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ sc:send_message(sysctlid, msg)
+ else
+ if verbose > 0 then
+ print("### nothing to do")
+ end
end
end,
+
output_update = function(self, oper, out, mask)
local idx = out.index
- if verbose then
- print("*** OUTPUT UPDATE oper:"..oper.." mask: "..tostring(mask))
+ if verbose > 0 then
+ print("### OUTPUT UPDATE:" .. oper ..
+ " mask: "..tostring(mask))
end
print(out)
+ local outdef = self.outputs[idx+1]
if (oper == 1) then -- create
- local outdef = self.outputs[idx+1]
if outdef then
self:output_request(m:JSON({index = idx,
id = outdef.id,
}))
end
elseif (oper == 5) then -- done
- local ads = self.outputs[idx+1].areas
+ local ads = outdef.areas
+ local on = outdef.name
if ads then
- for name,area in pairs(ads) do
- local a = m:JSON({name=name,output=out.index})
- for fld,val in pairs(area) do
- a[fld] = self:geometry(out.width,out.height,val)
+ for name,ad in pairs(ads) do
+ local can = wmgr:canonical_name(on.."."..name)
+ local a = m:JSON({name = name,
+ output = out.index})
+ for fld,val in pairs(ad) do
+ a[fld] = self:geometry(out.width,
+ out.height,
+ val)
end
self:area_create(a)
+ resmgr:area_create(area[can], outdef.zone)
end
end
end
end
-})
+}
sc = m:get_system_controller()
sets = {}
connected = false
+sysctlid = ""
-- these shoud be before wmgr:connect() is called
-print("====== creating applications")
+if verbose > 0 then
+ print("====== creating applications ======")
+end
application {
- appid = "default",
- area = "Center.Full",
- privileges = { screen = "none", audio = "none" }
+ appid = "default",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
}
application {
- appid = "org.tizen.ico.homescreen",
- area = "Center.Full",
- privileges = { screen = "system", audio = "system" }
+ appid = "weston",
+ area = "Center.Full",
+ privileges = { screen = "system", audio = "none" },
+ resource_class = "implicit",
+ screen_priority = 30
}
application {
- appid = "org.tizen.ico.statusbar",
- area = "Center.Status",
- privileges = { screen = "system", audio = "none" }
+ appid = "org.tizen.ico.homescreen",
+ area = "Center.Full",
+ privileges = { screen = "system", audio = "system" },
+ resource_class = "player",
+ screen_priority = 20
+}
+
+application {
+ appid = "org.tizen.ico.statusbar",
+ area = "Center.Status",
+ privileges = { screen = "system", audio = "none" },
+ resource_class = "player",
+ screen_priority = 20
}
if sc then
sc.client_handler = function (self, cid, msg)
- print('*** client handler: ' .. tostring(msg))
+ local command = msg.command
+ if verbose > 0 then
+ print('### ==> client handler:')
+ if verbose > 1 then
+ print(msg)
+ end
+ end
if not connected then
+ print('Setting sysctlid='..msg.appid)
+ sysctlid = msg.appid
print('Trying to connect to wayland...')
connected = wmgr:connect()
- else
- print('Window manager already connected...')
+ end
+ if connected and command then
+ if command == 1 then -- send_appid
+ local reply = m:JSON({ command = 0x60001,
+ arg = m:JSON({ stateid = 1,
+ state = 0})
+ })
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(command) .. " message")
+ if verbose > 1 then
+ print(reply)
+ end
+ end
+ sc:send_message(sysctlid, reply)
+
+ reply = m:JSON({ command = 0x60001,
+ arg = m:JSON({ stateid = 2,
+ state = 0})
+ })
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(command) .. " message")
+ if verbose > 1 then
+ print(reply)
+ end
+ end
+ sc:send_message(sysctlid, reply)
+ end
end
end
sc.generic_handler = function (self, cid, msg)
- print('*** generic handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> generic handler:')
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
sc.window_handler = function (self, cid, msg)
- print('*** window handler: ' .. command_name(msg.command) .. ' ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> received ' ..
+ command_name(msg.command) .. ' message')
+ if verbose > 1 then
+ print(tostring(msg))
+ end
+ end
local a = animation({})
+ local nores = false
if msg.command == 0x10003 then -- ico SHOW command
local raise_mask = 0x01000000
local lower_mask = 0x02000000
+ local nores_mask = 0x40000000
+ local time_mask = 0x00ffffff
msg.arg.visible = 1
- if msg.arg and msg.arg.anim_name then
- local time = msg.arg.time
- time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
- time = 200
- if m:AND(msg.arg.anim_time, raise_mask) then
- msg.arg.raise = 1
- elseif m:AND(msg.arg.anim_time, lower_mask) then
- msg.arg.raise = 0
+ if msg.arg then
+ local time = 200
+ if msg.arg.anim_time then
+ local t = msg.arg.anim_time
+ time = m:AND(t, time_mask)
+ nores = m:AND(t, nores_mask)
+ if m:AND(t, raise_mask) then
+ msg.arg.raise = 1
+ elseif m:AND(t, lower_mask) then
+ msg.arg.raise = 0
+ end
+ end
+ if msg.arg.anim_name then
+ a.show = { msg.arg.anim_name, time }
+ print('time: ' .. tostring(a.show[2]))
end
- a.show = { msg.arg.anim_name, time }
- print('time: ' .. tostring(a.show[2]))
end
- print('##### SHOW')
- print(tostring(msg.arg))
- wmgr:window_request(msg.arg, a, 0)
+ if not nores then
+ local p = wmgr:application(msg.appid)
+ local s = p.privileges.screen
+ if s == "system" then
+ nores = true
+ end
+ end
+ if verbose > 2 then
+ print('### ==> SHOW')
+ print(tostring(msg.arg))
+ end
+ if nores then
+ wmgr:window_request(msg.arg, a, 0)
+ else
+ local surface = msg.arg.surface
+ resclnt:resource_set_acquire("screen", surface)
+ resmgr:window_raise(msg.appid, surface, 1)
+ end
elseif msg.command == 0x10004 then -- ico HIDE command
local raise_mask = 0x01000000
local lower_mask = 0x02000000
+ local nores_mask = 0x40000000
+ local time_mask = 0x00ffffff
msg.arg.visible = 0
- if msg.arg and msg.arg.anim_name then
- local time = msg.arg.time
- time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
- time = 200
- if m:AND(msg.arg.anim_time, raise_mask) then
- msg.arg.raise = 1
+ if msg.arg then
+ local time = 200
+ if msg.arg.anim_time then
+ local t = msg.arg.anim_time
+ time = m:AND(t, time_mask)
+ nores = m:AND(t, nores_mask)
end
- if m:AND(msg.arg.anim_time, lower_mask) then
- msg.arg.raise = 0
+ if msg.arg.anim_name then
+ a.hide = { msg.arg.anim_name, time }
+ print('hide animation time: ' .. tostring(a.hide[2]))
end
- a.hide = { msg.arg.anim_name, time }
- print('hide animation time: ' .. tostring(a.hide[2]))
end
- print('##### HIDE')
- print(tostring(msg.arg))
- wmgr:window_request(msg.arg, a, 0)
+ if not nores then
+ local p = wmgr:application(msg.appid)
+ local s = p.privileges.screen
+ if s == "system" then
+ nores = true
+ end
+ end
+ if verbose > 2 then
+ print('### ==> HIDE REQUEST')
+ print(tostring(msg.arg))
+ end
+ if nores then
+ wmgr:window_request(msg.arg, a, 0)
+ else
+ resmgr:window_raise(msg.appid, msg.arg.surface, -1)
+ end
elseif msg.command == 0x10005 then -- ico MOVE
- print('##### MOVE')
- print(tostring(msg.arg))
+ if verbose > 2 then
+ print('### ==> MOVE REQUEST')
+ print(tostring(msg.arg))
+ end
wmgr:window_request(msg.arg, a, 0)
+ -- TODO: handle if area changed
elseif msg.command == 0x10006 then -- ico ACTIVE
- print('##### ACTIVE')
if not msg.arg.active then
- msg.arg.active = 0
+ msg.arg.active = 3 -- pointer + keyboard
+ end
+ if verbose > 2 then
+ print('### ==> ACTIVE REQUEST')
+ print(tostring(msg.arg))
end
- print(tostring(msg.arg))
wmgr:window_request(msg.arg, a, 0)
elseif msg.command == 0x10007 then -- ico CHANGE_LAYER
- print('##### CHANGE_LAYER')
- print(tostring(msg.arg))
+ if verbose > 2 then
+ print('### ==> CHANGE_LAYER REQUEST')
+ print(tostring(msg.arg))
+ end
--[[
if msg.arg.layer ~= 4 or msg.arg.layer ~= 5 then
print("do not change layer for other than cursor or touch")
wmgr:window_request(msg.arg, a, 0)
elseif msg.command == 0x10011 then -- ico MAP_THUMB
local framerate = msg.arg.framerate
- print('##### MAP_THUMB')
- msg.arg.map = 1
if not framerate or framerate < 0 then
framerate = 0
end
+ msg.arg.map = 1
+ if verbose > 2 then
+ print('### ==> MAP_THUMB REQUEST')
+ print(msg.arg)
+ print('framerate: '..framerate)
+ end
wmgr:window_request(msg.arg, a, framerate)
elseif msg.command == 0x10012 then -- ico UNMAP_THUMB
- print('##### UNMAP_THUMB')
msg.arg.map = 0
+ if verbose > 2 then
+ print('### ==> UNMAP_THUMB REQUEST')
+ print(msg.arg)
+ end
wmgr:window_request(msg.arg, a, 0)
elseif msg.command == 0x10020 then -- ico SHOW_LAYER command
msg.arg.visible = 1
- print('##### SHOW_LAYER')
+ if verbose > 2 then
+ print('### ==> SHOW_LAYER REQUEST')
+ print(msg.arg)
+ end
+ wmgr:layer_request(msg.arg)
+ elseif msg.command == 0x10021 then -- ico HIDE_LAYER command
+ msg.arg.visible = 0
+ if verbose > 2 then
+ print('### ==> HIDE_LAYER REQUEST')
+ print(msg.arg)
+ end
wmgr:layer_request(msg.arg)
end
end
+
sc.input_handler = function (self, cid, msg)
- print('*** input handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> input handler: ' .. command_name(msg.comand))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
+
sc.user_handler = function (self, cid, msg)
- print('*** user handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> user handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
+
sc.resource_handler = function (self, cid, msg)
- print('*** resource handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> resource handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
createResourceSet = function (ctl, client, msg)
cb = function(rset, data)
print("command REVERT")
end
end
+
sc.inputdev_handler = function (self, cid, msg)
- print('*** inputdev handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('*** inputdev handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
end
$(SYSTEMCTL_DIR)/plugin-system-controller.c \
$(SYSTEMCTL_DIR)/resource-manager/resource-manager.c \
$(SYSTEMCTL_DIR)/resource-manager/scripting-resource-manager.c \
+ $(SYSTEMCTL_DIR)/resource-manager/screen.c \
+ $(SYSTEMCTL_DIR)/resource-manager/notifier.c \
+ $(SYSTEMCTL_DIR)/resource-manager/scripting-notifier.c \
+ $(SYSTEMCTL_DIR)/resource-client/resource-client.c \
+ $(SYSTEMCTL_DIR)/resource-client/scripting-resource-client.c \
$(SYSTEMCTL_DIR)/application/application.c \
$(SYSTEMCTL_DIR)/application/scripting-application.c \
$(SYSTEMCTL_DIR)/wayland/wayland.c \
static void object_delete_exttbl(userdata_t *u, lua_State *L);
static int override_setfield(lua_State *L);
static int override_getfield(lua_State *L);
-static int override_tostring(lua_State *L);
+static int override_tostring(lua_State *L);
static int object_setup_bridges(userdata_t *u, lua_State *L);
static void invalid_destructor(void *data);
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)
+#define IF_PRESENT(u,n) if ((u->mask & MRP_APPLICATION_ ## n ## _MASK))
mrp_application_update_mask_t mask;
mrp_application_t *app;
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");
+ MRP_ASSERT(u, "invalid argument");
mask = u->mask;
+ if (!(mask & MRP_APPLICATION_APPID_MASK) || !u->appid) {
+ mrp_log_error("system-controller: failed to create application: "
+ "no appid");
+ return NULL;
+ }
+
+ if (!(mask & MRP_APPLICATION_AREA_NAME_MASK) || !u->area_name) {
+ mrp_log_error("system-controller: failed to create application '%s': "
+ "no area name", u->appid);
+ return NULL;
+ }
+
if (!(app = mrp_allocz(sizeof(mrp_application_t)))) {
- mrp_log_error("failed to create application '%s': out of memory",
- u->appid);
+ mrp_log_error("system-controller: failed to create application '%s': "
+ "out of memory", u->appid);
return NULL;
}
app->area = area;
}
- if ((mask & MRP_APPLICATION_SCREEN_PRIVILEGE_MASK))
+ IF_PRESENT(u, SCREEN_PRIVILEGE)
app->privileges.screen = u->privileges.screen;
- if ((mask & MRP_APPLICATION_AUDIO_PRIVILEGE_MASK))
+ IF_PRESENT(u, AUDIO_PRIVILEGE)
app->privileges.audio = u->privileges.audio;
+ IF_PRESENT(u, RESOURCE_CLASS)
+ app->resource_class = mrp_strdup(u->resource_class);
+ IF_PRESENT(u, SCREEN_PRIORITY)
+ app->screen_priority = u->screen_priority;
if (!scripting_data)
scripting_data = mrp_application_scripting_app_create_from_c(app);
mrp_application_privilege_str(app->privileges.screen),
mrp_application_privilege_str(app->privileges.audio));
}
+ if ((mask & MRP_APPLICATION_RESOURCE_CLASS_MASK)) {
+ PRINT("resource_class: '%s'",app->resource_class ? app->resource_class:
+ "<unknown>" );
+ }
+ if ((mask & MRP_APPLICATION_SCREEN_PRIORITY_MASK)) {
+ PRINT("screen_priority: %d", app->screen_priority);
+ }
return p - buf;
mrp_wayland_area_t *area;
void *it;
- mrp_wayland_foreach(wl, it) {
- if ((area = mrp_wayland_area_find(wl, fullname)))
- return area;
+ if (fullname) {
+ mrp_wayland_foreach(wl, it) {
+ if ((area = mrp_wayland_area_find(wl, fullname)))
+ return area;
+ }
}
return NULL;
mrp_wayland_area_t *area;
mrp_application_privileges_t privileges;
+ const char *resource_class;
+ int32_t screen_priority;
void *scripting_data;
};
MRP_APPLICATION_AREA_MASK = 0x04,
MRP_APPLICATION_SCREEN_PRIVILEGE_MASK = 0x08,
MRP_APPLICATION_AUDIO_PRIVILEGE_MASK = 0x10,
- MRP_APPLICATION_PRIVILEGES_MASK = 0x18,
+ MRP_APPLICATION_PRIVILEGES_MASK = 0x18,
+ MRP_APPLICATION_RESOURCE_CLASS_MASK = 0x20,
+ MRP_APPLICATION_SCREEN_PRIORITY_MASK = 0x40,
- MRP_APPLICATION_END_MASK = 0x20
+ MRP_APPLICATION_END_MASK = 0x80
};
struct mrp_application_update_s {
mrp_application_update_mask_t mask;
const char *appid;
const char *area_name;
+ const char *resource_class;
mrp_application_privileges_t privileges;
+ int32_t screen_priority;
};
mrp_application_t *mrp_application_create(mrp_application_update_t *u,
static void app_destroy_from_lua(void *);
static scripting_app_t *app_check(lua_State *, int);
+static int app_lookup(lua_State *L);
static mrp_application_privileges_t *priv_check(lua_State *, int);
static void priv_free(mrp_application_privileges_t *);
void mrp_application_scripting_init(lua_State *L)
{
mrp_lua_create_object_class(L, APPLICATION_CLASS);
+
+ lua_pushcfunction(L, app_lookup);
+ lua_setglobal(L, "application_lookup");
}
mrp_application_t *mrp_application_scripting_app_check(lua_State *L, int idx)
const char *fldnam;
const char *appid = NULL;
const char *arnam = "default";
+ const char *class = NULL;
+ int32_t spri = 0;
mrp_application_privileges_t *privs = NULL;
char *id;
char buf[4096];
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;
+ case APPID: appid = luaL_checkstring(L, -1); break;
+ case AREA: arnam = luaL_checkstring(L, -1); break;
+ case PRIVILEGES: privs = priv_check(L, -1); break;
+ case RESOURCE_CLASS: class = luaL_checkstring(L, -1); break;
+ case SCREEN_PRIORITY: spri = luaL_checkinteger(L, -1); break;
+ default: luaL_error(L, "bad field '%s'", fldnam); break;
}
}
if (!appid)
luaL_error(L, "'appid' field is missing");
-
+ if (!class)
+ luaL_error(L, "'resource_class' field is missing");
+ if (spri < 0 || spri > 255)
+ luaL_error(L, "'screen_priority' is out of range (0 - 255)");
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.mask = MRP_APPLICATION_APPID_MASK |
+ MRP_APPLICATION_AREA_NAME_MASK |
+ MRP_APPLICATION_RESOURCE_CLASS_MASK |
+ MRP_APPLICATION_SCREEN_PRIORITY_MASK ;
u.appid = appid;
u.area_name = arnam;
+ u.resource_class = class;
+ u.screen_priority = spri;
if (privs) {
u.mask |= MRP_APPLICATION_PRIVILEGES_MASK;
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;
+ 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;
+ case RESOURCE_CLASS:
+ lua_pushstring(L, app->resource_class ? app->resource_class : "");
+ break;
+ case SCREEN_PRIORITY:
+ lua_pushinteger(L, app->screen_priority);
+ break;
+ default:
+ lua_pushnil(L);
+ break;
}
}
return (scripting_app_t *)mrp_lua_check_object(L, APPLICATION_CLASS, idx);
}
+static int app_lookup(lua_State *L)
+{
+ mrp_application_t *app;
+ const char *appid;
+ void *sa;
+
+ MRP_LUA_ENTER;
+
+ if (!lua_isstring(L, 1))
+ lua_pushnil(L);
+ else {
+ appid = lua_tostring(L, 1);
+
+ if ((app = mrp_application_find(appid)) && (sa = app->scripting_data))
+ mrp_lua_push_object(L, sa);
+ else
+ lua_pushnil(L);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
static mrp_application_privileges_t *priv_check(lua_State *L, int idx)
{
return PRIVILEGES;
break;
+ case 14:
+ if (!strcmp(name, "resource_class"))
+ return RESOURCE_CLASS;
+ break;
+
+ case 15:
+ if (!strcmp(name, "screen_priority"))
+ return SCREEN_PRIORITY;
+ break;
+
default:
break;
}
#ifndef __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__
#define __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__
+#define MRP_SYSCTL_APPID_DEFAULT "default"
+
+#define MRP_SYSCTL_SCREEN_RESOURCE "screen"
+#define MRP_SYSCTL_AUDIO_RESOURCE "audio_playback"
+#define MRP_SYSCTL_INPUT_RESOURCE "input"
+
+
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,
+ /* 5 */ ALIGN, APPID, AUDIO, EVENT, INDEX, INPUT, LAYER, MODEL, POS_X,
+ POS_Y, RAISE, RIGHT, TYPE, WIDTH,
/* 6 */ ACTIVE, BOTTOM, HEIGHT, LAYERS, MAPPED, MIDDLE, OUTPUT, RESIZE,
ROTATE, SCREEN,
/* 7 */ CLASSES, DISPLAY, PIXEL_X, PIXEL_Y, SURFACE, VISIBLE,
/* 9 */ LAYERTYPE, SHAREABLE,
/* 10 */ ATTRIBUTES, HORIZONTAL, KEEPRATIO, PRIVILEGES,
/* 11 */ AREA_CREATE, PIXEL_WIDTH,
- /* 12 */ PIXEL_HEIGHT, LAYER_UPDATE,
+ /* 12 */ PIXEL_HEIGHT, LAYER_UPDATE, WINDOW_RAISE,
/* 13 */ LAYER_REQUEST, OUTPUT_UPDATE, WINDOW_UPDATE,
- /* 14 */ OUTPUT_REQUEST, WINDOW_MANAGER, WINDOW_REQUEST,
+ /* 14 */ MANAGER_UPDATE, OUTPUT_REQUEST, RESOURCE_CLASS, WINDOW_MANAGER,
+ WINDOW_REQUEST,
+ /* 15 */ MANAGER_REQUEST, SCREEN_PRIORITY,
+ /* 18 */ PASSTHROUGH_UPDATE,
+ /* 19 */ PASSTHROUGH_REQUEST, RESOURCE_SET_CREATE,
+ /* 20 */ RESOURCE_SET_ACQUIRE, RESOURCE_SET_DESTROY, RESOURCE_SET_RELEASE,
+ SCREEN_EVENT_HANDLER,
};
#endif /* __MURPHY_SYSTEM_CONTROLLER_DATA_TYPES_H__ */
#include "system-controller.h"
#include "resource-manager/scripting-resource-manager.h"
+#include "resource-client/scripting-resource-client.h"
#include "application/scripting-application.h"
#include "wayland/scripting-wayland.h"
return FALSE;
mrp_resmgr_scripting_init(sc->L);
+ mrp_resclnt_scripting_init(sc->L);
mrp_application_scripting_init(sc->L);
mrp_wayland_scripting_init(sc->L);
--- /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-client.h"
+#include "wayland/wayland.h"
+
+static int hash_compare(const void *, const void *);
+static uint32_t hash_function(const void *);
+
+static void event_cb(uint32_t, mrp_resource_set_t *, void *);
+
+static const char *type_str(mrp_resclnt_resource_set_type_t);
+
+mrp_resclnt_t *mrp_resclnt_create(void)
+{
+ mrp_resclnt_t *resclnt;
+ mrp_htbl_config_t cfg;
+
+ if (!(resclnt = mrp_allocz(sizeof(mrp_resclnt_t)))) {
+ mrp_log_error("system-controller: failed to allocate private data "
+ "resource manager");
+ return NULL;
+ }
+
+ cfg.nentry = MRP_RESCLNT_RESOURCE_SET_MAX;
+ cfg.comp = hash_compare;
+ cfg.hash = hash_function;
+ cfg.free = NULL;
+ cfg.nbucket = MRP_RESCLNT_RESOURCE_SET_BUCKETS;
+
+ resclnt->client = mrp_resource_client_create("system-controller", resclnt);
+ resclnt->rsets.screen = mrp_htbl_create(&cfg);
+ resclnt->rsets.audio = mrp_htbl_create(&cfg);
+ resclnt->rsets.input = mrp_htbl_create(&cfg);
+
+ if (!resclnt->client) {
+ mrp_log_error("system-controller: failed to create resource client");
+ mrp_resclnt_destroy(resclnt);
+ return NULL;
+ }
+
+ return resclnt;
+}
+
+void mrp_resclnt_destroy(mrp_resclnt_t *resclnt)
+{
+ if (resclnt) {
+ mrp_resource_client_destroy(resclnt->client);
+
+ mrp_htbl_destroy(resclnt->rsets.screen, false);
+ mrp_htbl_destroy(resclnt->rsets.audio, false);
+ mrp_htbl_destroy(resclnt->rsets.input, false);
+
+ mrp_free(resclnt);
+ }
+}
+
+bool mrp_resclnt_add_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ const char *zone_name,
+ const char *appid,
+ void *key)
+{
+ mrp_application_t *app;
+ mrp_resource_set_t *rset;
+ const char *name;
+ bool shared;
+ mrp_htbl_t *htbl;
+ mrp_attr_t attr[16];
+ int sts;
+
+ MRP_ASSERT(resclnt && resclnt->client && zone_name && key,
+ "invalid argument");
+ MRP_ASSERT(resclnt->rsets.screen && resclnt->rsets.audio &&
+ resclnt->rsets.input, "uninitialised data structure");
+
+ if (!(app = mrp_application_find(appid)) &&
+ !(app = mrp_application_find(MRP_SYSCTL_APPID_DEFAULT)))
+ {
+ mrp_debug("failed to add %s resource set: can't find "
+ "application '%s'", type_str(type), appid);
+ return false;
+ }
+
+ memset(attr, 0, sizeof(attr));
+
+ switch (type) {
+
+ case MRP_RESCLIENT_RESOURCE_SET_SCREEN:
+ name = MRP_SYSCTL_SCREEN_RESOURCE;
+ htbl = resclnt->rsets.screen;
+ shared = true;
+
+ attr[0].name = "classpri";
+ attr[0].type = mqi_integer;
+ attr[0].value.integer = app->screen_priority;
+
+ attr[1].name = "area";
+ attr[1].type = mqi_string;
+ attr[1].value.string = app->area_name;
+
+ attr[2].name = "appid";
+ attr[2].type = mqi_string;
+ attr[2].value.string = appid;
+
+ attr[3].name = "surface";
+ attr[3].type = mqi_integer;
+ attr[3].value.integer = (int32_t)(key - NULL);
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_AUDIO:
+ name = MRP_SYSCTL_AUDIO_RESOURCE;
+ htbl = resclnt->rsets.audio;
+ shared = false;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_INPUT:
+ name = MRP_SYSCTL_INPUT_RESOURCE;
+ htbl = resclnt->rsets.input;
+ shared = true;
+ break;
+
+ default:
+ mrp_log_error("system-controller: failed to add resource: "
+ "invalid resource type %d", type);
+ return false;
+ }
+
+ rset = mrp_resource_set_create(resclnt->client, false, false, 0,
+ event_cb, resclnt);
+ if (!rset) {
+ mrp_debug("system-controller: failed to add %s resource set: "
+ "can't create resource set", type_str(type));
+ return false;
+ }
+
+ sts = mrp_resource_set_add_resource(rset, name, shared, attr, true);
+
+ if (sts < 0) {
+ mrp_log_error("system-controller: failed to add %s resource set: "
+ "can't create resource '%s'", type_str(type), name);
+ mrp_resource_set_destroy(rset);
+ return false;
+ }
+
+ sts = mrp_application_class_add_resource_set(app->resource_class,
+ zone_name, rset,
+ ++(resclnt->reqno));
+ if (sts < 0) {
+ mrp_log_error("system-controller: failed to add %s resource set: "
+ "can't add resource to application class",
+ type_str(type));
+ mrp_resource_set_destroy(rset);
+ return false;
+ }
+
+ mrp_htbl_insert(htbl, key, rset);
+
+ return true;
+}
+
+void mrp_resclnt_remove_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key)
+{
+ mrp_htbl_t *htbl;
+ mrp_resource_set_t *rset;
+
+ MRP_ASSERT(resclnt && key, "invalid argument");
+ MRP_ASSERT(resclnt->rsets.screen && resclnt->rsets.audio &&
+ resclnt->rsets.input, "uninitialised data structure");
+
+
+ switch (type) {
+
+ case MRP_RESCLIENT_RESOURCE_SET_SCREEN:
+ htbl = resclnt->rsets.screen;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_AUDIO:
+ htbl = resclnt->rsets.audio;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_INPUT:
+ htbl = resclnt->rsets.input;
+ break;
+
+ default:
+ mrp_log_error("system-controller: failed to remove resource: "
+ "invalid resource type %d", type);
+ return;
+ }
+
+ if (!(rset = mrp_htbl_remove(htbl, key, false))) {
+ mrp_log_error("system-controller: failed to remove %s resource set: "
+ "can't find it", type_str(type));
+ return;
+ }
+
+ mrp_resource_set_release(rset, ++(resclnt->reqno));
+ mrp_resource_set_destroy(rset);
+}
+
+bool mrp_resclnt_acquire_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key)
+{
+ mrp_resource_set_t *rset;
+ mrp_htbl_t *htbl;
+
+ MRP_ASSERT(resclnt && resclnt->client, "invalid argument");
+ MRP_ASSERT(resclnt->rsets.screen && resclnt->rsets.audio &&
+ resclnt->rsets.input, "uninitialised data structure");
+
+ switch (type) {
+
+ case MRP_RESCLIENT_RESOURCE_SET_SCREEN:
+ htbl = resclnt->rsets.screen;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_AUDIO:
+ htbl = resclnt->rsets.audio;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_INPUT:
+ htbl = resclnt->rsets.input;
+ break;
+
+ default:
+ mrp_log_error("system-controller: failed to acquire resource: "
+ "invalid resource type %d", type);
+ return false;
+ }
+
+ if (!(rset = mrp_htbl_lookup(htbl, key))) {
+ mrp_log_error("system-controller: failed to acquire resource set: "
+ "can't find it (key=%p)", key);
+ return false;
+ }
+
+ mrp_resource_set_acquire(rset, ++(resclnt->reqno));
+
+ return true;
+}
+
+
+bool mrp_resclnt_release_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key)
+{
+ mrp_resource_set_t *rset;
+ mrp_htbl_t *htbl;
+
+ MRP_ASSERT(resclnt && resclnt->client, "invalid argument");
+ MRP_ASSERT(resclnt->rsets.screen && resclnt->rsets.audio &&
+ resclnt->rsets.input, "uninitialised data structure");
+
+ switch (type) {
+
+ case MRP_RESCLIENT_RESOURCE_SET_SCREEN:
+ htbl = resclnt->rsets.screen;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_AUDIO:
+ htbl = resclnt->rsets.audio;
+ break;
+
+ case MRP_RESCLIENT_RESOURCE_SET_INPUT:
+ htbl = resclnt->rsets.input;
+ break;
+
+ default:
+ mrp_log_error("system-controller: failed to acquire resource: "
+ "invalid resource type %d", type);
+ return false;
+ }
+
+ if (!(rset = mrp_htbl_lookup(htbl, key))) {
+ mrp_log_error("system-controller: failed to release resource set: "
+ "can't find it (key=%p)", key);
+ return false;
+ }
+
+ mrp_resource_set_release(rset, ++(resclnt->reqno));
+
+ return true;
+}
+
+
+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 >> 3) & (ptrdiff_t)0xffffffff);
+}
+
+
+static void event_cb(uint32_t reqid, mrp_resource_set_t *rset, void *u)
+{
+ mrp_resource_client_t *resclnt = (mrp_resource_client_t *)u;
+
+ MRP_UNUSED(reqid);
+ MRP_UNUSED(rset);
+ MRP_UNUSED(resclnt);
+}
+
+static const char *type_str(mrp_resclnt_resource_set_type_t type)
+{
+ switch (type) {
+ case MRP_RESCLIENT_RESOURCE_SET_SCREEN: return "screen";
+ case MRP_RESCLIENT_RESOURCE_SET_AUDIO: return "audio";
+ case MRP_RESCLIENT_RESOURCE_SET_INPUT: return "input";
+ default: return "<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_SYSTEM_CONTROLLER_RESOURCE_CLIENT_H__
+#define __MURPHY_SYSTEM_CONTROLLER_RESOURCE_CLIENT_H__
+
+#include <sys/types.h>
+
+#include <murphy/common/hashtbl.h>
+
+#include <murphy/resource/data-types.h>
+
+#include "data-types.h"
+
+#define MRP_RESCLNT_RESOURCE_SET_MAX 256
+
+#define MRP_RESCLNT_RESOURCE_SET_BUCKETS (MRP_RESCLNT_RESOURCE_SET_MAX / 8)
+
+typedef enum mrp_sysctl_scripting_field_e mrp_resclnt_scripting_field_t;
+typedef enum mrp_resclnt_resource_set_type_e mrp_resclnt_resource_set_type_t;
+
+typedef struct mrp_resclnt_s mrp_resclnt_t;
+
+
+enum mrp_resclnt_resource_set_type_e {
+ MRP_RESCLIENT_RESOURCE_SET_UNKNOWN = 0,
+ MRP_RESCLIENT_RESOURCE_SET_SCREEN,
+ MRP_RESCLIENT_RESOURCE_SET_AUDIO,
+ MRP_RESCLIENT_RESOURCE_SET_INPUT,
+
+ MRP_RESCLIENT_RESOURCE_SET_MAX
+};
+
+
+struct mrp_resclnt_s {
+ mrp_resource_client_t *client;
+ uint32_t reqno;
+
+ struct {
+ mrp_htbl_t *screen;
+ mrp_htbl_t *audio;
+ mrp_htbl_t *input;
+ } rsets;
+
+ void *scripting_data;
+};
+
+
+mrp_resclnt_t *mrp_resclnt_create(void);
+void mrp_resclnt_destroy(mrp_resclnt_t *resclnt);
+
+bool mrp_resclnt_add_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ const char *zone_name,
+ const char *appid,
+ void *key);
+void mrp_resclnt_remove_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key);
+
+bool mrp_resclnt_acquire_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key);
+bool mrp_resclnt_release_resource_set(mrp_resclnt_t *resclnt,
+ mrp_resclnt_resource_set_type_t type,
+ void *key);
+
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_RESOURCE_CLIENT_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-client.h"
+#include "wayland/scripting-wayland.h"
+
+#define RESOURCE_CLIENT_CLASS MRP_LUA_CLASS_SIMPLE(resource_client)
+
+typedef struct scripting_resclnt_s scripting_resclnt_t;
+typedef struct funcbridge_def_s funcbridge_def_t;
+
+struct scripting_resclnt_s {
+ mrp_resclnt_t *resclnt;
+};
+
+struct funcbridge_def_s {
+ const char *name;
+ const char *sign;
+ mrp_funcbridge_cfunc_t func;
+ void *data;
+ mrp_funcbridge_t **ptr;
+};
+
+static int resclnt_create(lua_State *);
+static int resclnt_getfield(lua_State *);
+static int resclnt_setfield(lua_State *);
+static void resclnt_destroy(void *);
+
+static scripting_resclnt_t *resclnt_check(lua_State *, int);
+
+static mrp_resclnt_resource_set_type_t str_to_type(const char *);
+
+static bool register_methods(lua_State *);
+
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ resource_client, /* class name */
+ scripting_resclnt_t, /* userdata type */
+ resclnt_destroy, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (resclnt_create)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (resclnt_create)
+ MRP_LUA_OVERRIDE_GETFIELD (resclnt_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (resclnt_setfield)
+ )
+);
+
+
+static mrp_funcbridge_t *resource_set_create;
+static mrp_funcbridge_t *resource_set_destroy;
+static mrp_funcbridge_t *resource_set_acquire;
+static mrp_funcbridge_t *resource_set_release;
+
+
+void mrp_resclnt_scripting_init(lua_State *L)
+{
+ MRP_ASSERT(L, "invalid argument");
+
+ mrp_lua_create_object_class(L, RESOURCE_CLIENT_CLASS);
+ register_methods(L);
+}
+
+
+mrp_resclnt_t *mrp_resclnt_scripting_check(lua_State *L, int idx)
+{
+ scripting_resclnt_t *rc;
+ mrp_resclnt_t *resclnt;
+
+ if ((rc = resclnt_check(L, idx)) && (resclnt = rc->resclnt)) {
+ MRP_ASSERT(resclnt->scripting_data == (void *)rc,
+ "confused with data structures");
+ return resclnt;
+ }
+
+ return NULL;
+}
+
+mrp_resclnt_t *mrp_resclnt_scripting_unwrap(void *void_rc)
+{
+ scripting_resclnt_t *rc = (scripting_resclnt_t *)void_rc;
+
+ if (rc && mrp_lua_get_object_classdef(rc) == RESOURCE_CLIENT_CLASS)
+ return rc->resclnt;
+
+ return NULL;
+}
+
+static int resclnt_create(lua_State *L)
+{
+ mrp_resclnt_t *resclnt;
+ size_t fldnamlen;
+ const char *fldnam;
+ scripting_resclnt_t *rc;
+ int table;
+
+ MRP_LUA_ENTER;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ rc = (scripting_resclnt_t *)mrp_lua_create_object(L, RESOURCE_CLIENT_CLASS,
+ NULL, 1);
+
+ if (!rc)
+ luaL_error(L, "failed to create resource client");
+
+ table = lua_gettop(L);
+
+ MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
+ switch (mrp_resclnt_scripting_field_name_to_type(fldnam, fldnamlen)) {
+
+ default:
+ lua_pushvalue(L, -2);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, table);
+ break;
+ }
+ }
+
+ if (!(resclnt = mrp_resclnt_create()))
+ luaL_error(L, "can't create resclnt object");
+
+ rc->resclnt = resclnt;
+
+ resclnt->scripting_data = rc;
+
+ lua_settop(L, table);
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int resclnt_getfield(lua_State *L)
+{
+ scripting_resclnt_t *rc;
+ const char *fldnam;
+ mrp_resclnt_scripting_field_t fld;
+
+ MRP_LUA_ENTER;
+
+ fld = mrp_resclnt_scripting_field_check(L, 2, &fldnam);
+ lua_pop(L, 1);
+
+ rc = resclnt_check(L, 1);
+
+ if (!rc)
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+
+ case RESOURCE_SET_CREATE:
+ mrp_funcbridge_push(L, resource_set_create);
+ break;
+
+ case RESOURCE_SET_DESTROY:
+ mrp_funcbridge_push(L, resource_set_destroy);
+ break;
+
+ case RESOURCE_SET_ACQUIRE:
+ mrp_funcbridge_push(L, resource_set_acquire);
+ break;
+
+ case RESOURCE_SET_RELEASE:
+ mrp_funcbridge_push(L, resource_set_release);
+ break;
+
+ default:
+ lua_pushstring(L, fldnam);
+ lua_rawget(L, 1);
+ break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int resclnt_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ resclnt_check(L, 1);
+ luaL_error(L, "resource client is read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static void resclnt_destroy(void *data)
+{
+ scripting_resclnt_t *rc = (scripting_resclnt_t *)data;
+
+ MRP_UNUSED(data);
+ MRP_UNUSED(rc);
+
+ MRP_LUA_ENTER;
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+static scripting_resclnt_t *resclnt_check(lua_State *L, int idx)
+{
+
+ return (scripting_resclnt_t*)mrp_lua_check_object(L, RESOURCE_CLIENT_CLASS,
+ idx);
+}
+
+static mrp_resclnt_resource_set_type_t str_to_type(const char *str)
+{
+ if (str) {
+ if (!strcmp(str, "screen"))
+ return MRP_RESCLIENT_RESOURCE_SET_SCREEN;
+ else if (!strcmp(str, "audio"))
+ return MRP_RESCLIENT_RESOURCE_SET_AUDIO;
+ else if (!strcmp(str, "input"))
+ return MRP_RESCLIENT_RESOURCE_SET_INPUT;
+ }
+
+ return MRP_RESCLIENT_RESOURCE_SET_UNKNOWN; /* == 0 */
+}
+
+static bool resource_set_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_resclnt_t *resclnt;
+ mrp_resclnt_resource_set_type_t type;
+ const char *zone;
+ const char *appid;
+ int32_t objid;
+
+ 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, "osssd")) {
+ mrp_log_error("bad signature: expected 'osssd' got '%s'", signature);
+ return false;
+ }
+
+ if (!(resclnt = mrp_resclnt_scripting_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'resource_client' class object");
+ return false;
+ }
+
+ if (!(type = str_to_type(args[1].string))) {
+ mrp_log_error("argument 2 is not a valid resource type string");
+ return false;
+ }
+
+ zone = args[2].string;
+ appid = args[3].string;
+ objid = args[4].integer;
+
+ mrp_resclnt_add_resource_set(resclnt, type, zone, appid, NULL + objid);
+
+ return true;
+}
+
+
+static bool resource_set_destroy_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+ mrp_resclnt_t *resclnt;
+ mrp_resclnt_resource_set_type_t type;
+ int32_t objid;
+
+ 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, "osd")) {
+ mrp_log_error("bad signature: expected 'osd' got '%s'", signature);
+ return false;
+ }
+
+ if (!(resclnt = mrp_resclnt_scripting_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'resource_client' class object");
+ return false;
+ }
+
+ if (!(type = str_to_type(args[1].string))) {
+ mrp_log_error("argument 2 is not a valid resource type string");
+ return false;
+ }
+
+ objid = args[2].integer;
+
+ mrp_resclnt_remove_resource_set(resclnt, type, NULL + objid);
+
+ return true;
+}
+
+
+static bool resource_set_acquire_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+ mrp_resclnt_t *resclnt;
+ mrp_resclnt_resource_set_type_t type;
+ int32_t objid;
+
+ 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, "osd")) {
+ mrp_log_error("bad signature: expected 'osd' got '%s'", signature);
+ return false;
+ }
+
+ if (!(resclnt = mrp_resclnt_scripting_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'resource_client' class object");
+ return false;
+ }
+
+ if (!(type = str_to_type(args[1].string))) {
+ mrp_log_error("argument 2 is not a valid resource type string");
+ return false;
+ }
+
+ objid = args[2].integer;
+
+ mrp_resclnt_acquire_resource_set(resclnt, type, NULL + objid);
+
+ return true;
+}
+
+
+static bool resource_set_release_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+ mrp_resclnt_t *resclnt;
+ mrp_resclnt_resource_set_type_t type;
+ int32_t objid;
+
+ 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, "osd")) {
+ mrp_log_error("bad signature: expected 'osd' got '%s'", signature);
+ return false;
+ }
+
+ if (!(resclnt = mrp_resclnt_scripting_unwrap(args[0].pointer))) {
+ mrp_log_error("argument 1 is not a 'resource_client' class object");
+ return false;
+ }
+
+ if (!(type = str_to_type(args[1].string))) {
+ mrp_log_error("argument 2 is not a valid resource type string");
+ return false;
+ }
+
+ objid = args[2].integer;
+
+ mrp_resclnt_release_resource_set(resclnt, type, NULL + objid);
+
+ return true;
+}
+
+
+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(resource_set_create , "osssd", NULL),
+ FUNCBRIDGE(resource_set_destroy , "osd" , NULL),
+ FUNCBRIDGE(resource_set_acquire , "osd" , NULL),
+ FUNCBRIDGE(resource_set_release , "osd" , 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
+}
+
+
+mrp_resclnt_scripting_field_t
+mrp_resclnt_scripting_field_check(lua_State *L,int idx,const char **ret_fldnam)
+{
+ const char *fldnam;
+ size_t fldnamlen;
+ mrp_resclnt_scripting_field_t fldtyp;
+
+ if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
+ fldtyp = 0;
+ else
+ fldtyp = mrp_resclnt_scripting_field_name_to_type(fldnam, fldnamlen);
+
+ if (ret_fldnam)
+ *ret_fldnam = fldnam;
+
+ return fldtyp;
+}
+
+mrp_resclnt_scripting_field_t
+mrp_resclnt_scripting_field_name_to_type(const char *name, ssize_t len)
+{
+ if (len < 0)
+ len = strlen(name);
+
+ switch (len) {
+
+ case 19:
+ if (!strcmp(name, "resource_set_create"))
+ return RESOURCE_SET_CREATE;
+ break;
+
+ case 20:
+ switch (name[13]) {
+ case 'a':
+ if (!strcmp(name, "resource_set_acquire"))
+ return RESOURCE_SET_ACQUIRE;
+ break;
+ case 'd':
+ if (!strcmp(name, "resource_set_destroy"))
+ return RESOURCE_SET_DESTROY;
+ break;
+ case 'r':
+ if (!strcmp(name, "resource_set_release"))
+ return RESOURCE_SET_RELEASE;
+ 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_SYSTEM_CONTROLLER_RESOURCE_CLIENT_SCRIPTING_H__
+#define __MURPHY_SYSTEM_CONTROLLER_RESOURCE_CLIENT_SCRIPTING_H__
+
+#include <lua.h>
+
+#include "resource-client/resource-client.h"
+
+void mrp_resclnt_scripting_init(lua_State *L);
+
+mrp_resclnt_t *mrp_resclnt_scripting_check(lua_State *L, int idx);
+mrp_resclnt_t *mrp_resclnt_scripting_unwrap(void *void_rm);
+
+
+/* internal for scripting-xxx.c */
+mrp_resclnt_scripting_field_t
+mrp_resclnt_scripting_field_check(lua_State *, int, const char **);
+
+mrp_resclnt_scripting_field_t
+mrp_resclnt_scripting_field_name_to_type(const char *, ssize_t);
+
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_RESOURCE_CLIENT_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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include "notifier.h"
+
+static void event_destroy(mrp_resmgr_event_t *);
+
+static const char *type_str(mrp_resmgr_event_type_t);
+static const char *eventid_str(mrp_resmgr_eventid_t);
+
+
+mrp_resmgr_notifier_t *mrp_resmgr_notifier_create(mrp_resmgr_t *resmgr)
+{
+ mrp_resmgr_notifier_t *notifier;
+ mrp_resmgr_notifier_zone_t *nz;
+ int i;
+
+ MRP_ASSERT(resmgr, "invalid argument");
+
+ if ((notifier = mrp_allocz(sizeof(mrp_resmgr_notifier_t)))) {
+ notifier->resmgr = resmgr;
+
+ for (i = 0; i < MRP_ZONE_MAX; i++) {
+ nz = notifier->zones + i;
+ mrp_list_init(&nz->events);
+ }
+ }
+
+ return notifier;
+}
+
+void mrp_resmgr_notifier_destroy(mrp_resmgr_notifier_t *notifier)
+{
+ mrp_list_hook_t *events, *entry, *n;
+ mrp_resmgr_notifier_zone_t *nz;
+ mrp_resmgr_event_t *ev;
+ int i;
+
+ if (notifier) {
+
+ for (i = 0; i < MRP_ZONE_MAX; i++) {
+ nz = notifier->zones + i;
+ events = &nz->events;
+
+ mrp_list_foreach(events, entry, n) {
+ ev = mrp_list_entry(entry, mrp_resmgr_event_t, link);
+ event_destroy(ev);
+ }
+ }
+
+ mrp_free((void *)notifier);
+ }
+}
+
+void mrp_resmgr_notifier_register_event_callback(mrp_resmgr_t *resmgr,
+ mrp_resmgr_notifier_event_callback_t callback)
+{
+ mrp_resmgr_notifier_t *notifier;
+
+ MRP_ASSERT(resmgr && resmgr->notifier, "invalid argument");
+
+ notifier = resmgr->notifier;
+ notifier->callback = callback;
+}
+
+void mrp_resmgr_notifier_queue_screen_event(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_eventid_t eventid,
+ const char *appid,
+ int32_t surfaceid,
+ int32_t layerid,
+ const char *area)
+{
+ mrp_resmgr_notifier_t *notifier;
+ mrp_resmgr_notifier_zone_t *nz;
+ mrp_resmgr_event_t *ev;
+
+ MRP_ASSERT(resmgr && resmgr->notifier && zoneid < MRP_ZONE_MAX && appid,
+ "invalid argument");
+
+ notifier = resmgr->notifier;
+ nz = notifier->zones + zoneid;
+
+ if ((ev = mrp_allocz(sizeof(mrp_resmgr_event_t)))) {
+
+ ev->type = MRP_RESMGR_EVENT_SCREEN;
+ ev->eventid = eventid;
+ ev->appid = mrp_strdup(appid);
+ ev->surfaceid = surfaceid;
+ ev->layerid = layerid;
+ ev->area = mrp_strdup(area ? area : "<unknown>");
+
+ mrp_list_append(&nz->events, &ev->link);
+
+ mrp_debug("queued screen event in zone %u (eventid=%s appid='%s' "
+ "surfaceid=%d layerid=%d, area='%s'",
+ zoneid, eventid_str(ev->eventid), ev->appid,
+ ev->surfaceid, ev->layerid, ev->area);
+
+ nz->nevent.screen++;
+ }
+}
+
+void mrp_notifier_remove_last_event(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_event_type_t type)
+{
+ mrp_resmgr_notifier_t *notifier;
+ mrp_resmgr_notifier_zone_t *nz;
+ mrp_list_hook_t *events, *entry, *n;
+ mrp_resmgr_event_t *ev;
+ size_t *nevent_ptr;
+ int it;
+
+ MRP_ASSERT(resmgr && resmgr->notifier && zoneid < MRP_ZONE_MAX,
+ "invalid argument");
+
+ notifier = resmgr->notifier;
+ nz = notifier->zones + zoneid;
+
+ switch (type) {
+
+ case MRP_RESMGR_EVENT_SCREEN: nevent_ptr = &nz->nevent.screen; break;
+ case MRP_RESMGR_EVENT_AUDIO: nevent_ptr = &nz->nevent.audio; break;
+ case MRP_RESMGR_EVENT_INPUT: nevent_ptr = &nz->nevent.input; break;
+
+ default:
+ mrp_log_error("system-controller: failed to remove last resource "
+ "manager event: invalid event type %d", type);
+ return;
+ }
+
+ it = 0;
+ events = &nz->events;
+
+ mrp_list_foreach(events, entry, n) {
+ ev = mrp_list_entry(entry, mrp_resmgr_event_t, link);
+
+ if (++it > MRP_RESMGR_EVENT_MAX)
+ break;
+
+ if (type == ev->type) {
+ mrp_debug("removing %s event in zone %u (eventid=%s "
+ "appid='%s' surfaceid=%d layerid=%d, area='%s'",
+ type_str(ev->type), zoneid, eventid_str(ev->eventid),
+ ev->appid, ev->surfaceid, ev->layerid, ev->area);
+
+ event_destroy(ev);
+
+ (*nevent_ptr)--;
+
+ return;
+ }
+ }
+
+ mrp_log_error("system-controller: failed to remove last %s event: "
+ "non-existent event", type_str(type));
+}
+
+void mrp_resmgr_notifier_flush_events(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_event_type_t type)
+{
+ mrp_resmgr_notifier_t *notifier;
+ mrp_resmgr_notifier_zone_t *nz;
+ mrp_list_hook_t *events, *entry, *n;
+ mrp_resmgr_event_t *ev;
+ size_t nevent, *nevent_ptr;
+
+ MRP_ASSERT(resmgr && resmgr->notifier && zoneid < MRP_ZONE_MAX,
+ "invalid argument");
+
+ notifier = resmgr->notifier;
+ nz = notifier->zones + zoneid;
+
+ switch (type) {
+
+ case MRP_RESMGR_EVENT_ALL:
+ nevent = nz->nevent.screen + nz->nevent.audio + nz->nevent.input;
+ nevent_ptr = NULL;
+ break;
+
+ case MRP_RESMGR_EVENT_SCREEN:
+ nevent = nz->nevent.screen;
+ nevent_ptr = &nz->nevent.screen;
+ break;
+
+ case MRP_RESMGR_EVENT_AUDIO:
+ nevent = nz->nevent.audio;
+ nevent_ptr = &nz->nevent.audio;
+ break;
+
+ case MRP_RESMGR_EVENT_INPUT:
+ nevent = nz->nevent.input;
+ nevent_ptr = &nz->nevent.input;
+ break;
+
+ default:
+ mrp_log_error("system-controller: failed to flush resource manager "
+ "events: invalid event type %d", type);
+ return;
+ }
+
+ if (!nevent) {
+ mrp_debug("%s event queue in zone %u is empty: nothing to flush",
+ type_str(type), zoneid);
+ return;
+ }
+
+ mrp_debug("%s %d events in zone %u",
+ notifier->callback ? "forwarding" : "throwing away",
+ nevent, zoneid);
+
+ events = &nz->events;
+
+ mrp_list_foreach(events, entry, n) {
+ ev = mrp_list_entry(entry, mrp_resmgr_event_t, link);
+
+ if (type == MRP_RESMGR_EVENT_ALL || type == ev->type) {
+ if (notifier->callback)
+ notifier->callback(resmgr, ev);
+
+ event_destroy(ev);
+
+ if (nevent_ptr)
+ (*nevent_ptr)--;
+ }
+ }
+
+ if (!nevent_ptr) {
+ MRP_ASSERT(mrp_list_empty(&nz->events),
+ "confused with data structures");
+ memset(&nz->nevent, 0, sizeof(nz->nevent));
+ }
+}
+
+static void event_destroy(mrp_resmgr_event_t *ev)
+{
+ if (ev) {
+ mrp_list_delete(&ev->link);
+
+ mrp_free((void *)ev->appid);
+
+ switch (ev->type) {
+
+ case MRP_RESMGR_EVENT_SCREEN:
+ mrp_free((void *)ev->area);
+ break;
+
+ case MRP_RESMGR_EVENT_AUDIO:
+ break;
+
+ case MRP_RESMGR_EVENT_INPUT:
+ break;
+
+ default:
+ mrp_log_error("system-controller: confused with data structures: "
+ "invalid resource manager event type %d", ev->type);
+ break;
+ }
+
+ mrp_free(ev);
+ }
+}
+
+
+static const char *type_str(mrp_resmgr_event_type_t type)
+{
+ switch (type) {
+ case MRP_RESMGR_EVENT_ALL: return "all";
+ case MRP_RESMGR_EVENT_SCREEN: return "screen";
+ case MRP_RESMGR_EVENT_AUDIO: return "audio";
+ case MRP_RESMGR_EVENT_INPUT: return "input";
+ default: return "<unknown>";
+ }
+}
+
+static const char *eventid_str(mrp_resmgr_eventid_t eventid)
+{
+ switch (eventid) {
+ case MRP_RESMGR_EVENTID_GRANT: return "grant";
+ case MRP_RESMGR_EVENTID_REVOKE: return "revoke";
+ default: return "<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_SYSTEM_CONTROLLER_NOTIFICATION_H__
+#define __MURPHY_SYSTEM_CONTROLLER_NOTIFICATION_H__
+
+#include <sys/types.h>
+
+#include <murphy/resource/data-types.h>
+
+#include "resource-manager.h"
+
+enum mrp_resmgr_event_type_e {
+ MRP_RESMGR_EVENT_UNKNOWN = 0,
+ MRP_RESMGR_EVENT_ALL = 0,
+ MRP_RESMGR_EVENT_SCREEN,
+ MRP_RESMGR_EVENT_AUDIO,
+ MRP_RESMGR_EVENT_INPUT,
+
+ MRP_RESMGR_EVENT_MAX
+};
+
+enum mrp_resmgr_eventid_e {
+ MRP_RESMGR_EVENTID_UNKNOWN = 0,
+ MRP_RESMGR_EVENTID_GRANT,
+ MRP_RESMGR_EVENTID_REVOKE,
+};
+
+struct mrp_resmgr_notifier_zone_s {
+ mrp_list_hook_t events;
+ struct {
+ size_t screen;
+ size_t audio;
+ size_t input;
+ } nevent;
+};
+
+struct mrp_resmgr_notifier_s {
+ mrp_resmgr_t *resmgr;
+ mrp_resmgr_notifier_zone_t zones[MRP_ZONE_MAX];
+ mrp_resmgr_notifier_event_callback_t callback;
+};
+
+struct mrp_resmgr_event_s {
+ mrp_list_hook_t link;
+ mrp_resmgr_event_type_t type;
+ mrp_resmgr_eventid_t eventid;
+ char *appid;
+
+ /* screen specific fields */
+ struct {
+ int32_t surfaceid;
+ int32_t layerid;
+ char *area;
+ };
+};
+
+
+
+mrp_resmgr_notifier_t *mrp_resmgr_notifier_create(mrp_resmgr_t *resmgr);
+void mrp_resmgr_notifier_destroy(mrp_resmgr_notifier_t *notif);
+
+void mrp_resmgr_notifier_register_event_callback(mrp_resmgr_t *resmgr,
+ mrp_resmgr_notifier_event_callback_t callback);
+
+void mrp_resmgr_notifier_queue_screen_event(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_eventid_t eventid,
+ const char *appid,
+ int32_t surfaceid,
+ int32_t layerid,
+ const char *area);
+
+void mrp_notifier_remove_last_event(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_event_type_t type);
+
+#define mrp_notifier_remove_last_screen_event(_resmgr, _zoneid) \
+ mrp_notifier_remove_last_event(_resmgr, _zoneid, MRP_RESMGR_EVENT_SCREEN)
+
+#define mrp_notifier_remove_last_audio_event(_resmgr, _zoneid) \
+ mrp_notifier_remove_last_event(_resmgr, _zoneid, MRP_RESMGR_EVENT_AUDIO)
+
+#define mrp_notifier_remove_last_input_event(_resmgr, _zoneid) \
+ mrp_notifier_remove_last_event(_resmgr, _zoneid, MRP_RESMGR_EVENT_INPUT)
+
+void mrp_resmgr_notifier_flush_events(mrp_resmgr_t *resmgr,
+ uint32_t zoneid,
+ mrp_resmgr_event_type_t evtype);
+
+#define mrp_resmgr_notifier_flush_screen_events(_resmgr, _zoneid) \
+ mrp_resmgr_notifier_flush_events(_resmgr, _zoneid, MRP_RESMGR_EVENT_SCREEN)
+
+#define mrp_resmgr_notifier_flush_audio_events(_resmgr, _zoneid) \
+ mrp_resmgr_notifier_flush_events(_resmgr, _zoneid, MRP_RESMGR_EVENT_AUDIO)
+
+#define mrp_resmgr_notifier_flush_input_events(_resmgr, _zoneid) \
+ mrp_resmgr_notifier_flush_events(_resmgr, _zoneid, MRP_RESMGR_EVENT_INPUT)
+
+#define mrp_resmgr_notifier_flush_all_events(_resmgr) \
+ mrp_resmgr_notifier_flush_events(_resmgr, MRP_RESMGR_EVENT_ALL)
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_NOTIFICATION_H__ */
#include <murphy/resource/protocol.h>
#include "resource-manager.h"
+#include "screen.h"
+#include "notifier.h"
static int hash_compare(const void *, const void *);
static uint32_t hash_function(const void *);
cfg.nbucket = MRP_RESMGR_RESOURCE_BUCKETS;
resmgr->resources = mrp_htbl_create(&cfg);
+ resmgr->screen = mrp_resmgr_screen_create(resmgr);
+ resmgr->notifier = mrp_resmgr_notifier_create(resmgr);
return resmgr;
}
#include "data-types.h"
+#define MRP_RESMGR_RESOURCE_MAX 256
+#define MRP_RESMGR_ACTIVE_SCREEN_MAX 128
+
+#define MRP_RESMGR_RESOURCE_BUCKETS (MRP_RESMGR_RESOURCE_MAX / 4)
+
typedef enum mrp_sysctl_scripting_field_e mrp_resmgr_scripting_field_t;
+typedef enum mrp_resmgr_event_type_e mrp_resmgr_event_type_t;
+typedef enum mrp_resmgr_eventid_e mrp_resmgr_eventid_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;
+typedef struct mrp_resmgr_class_s mrp_resmgr_class_t;
+typedef struct mrp_resmgr_window_s mrp_resmgr_window_t;
+typedef struct mrp_resmgr_screen_area_s mrp_resmgr_screen_area_t;
+typedef struct mrp_resmgr_notifier_s mrp_resmgr_notifier_t;
+typedef struct mrp_resmgr_notifier_zone_s mrp_resmgr_notifier_zone_t;
+typedef struct mrp_resmgr_event_s mrp_resmgr_event_t;
-#define MRP_RESMGR_RESOURCE_MAX 256
-#define MRP_RESMGR_RESOURCE_BUCKETS (MRP_RESMGR_RESOURCE_MAX / 4)
+typedef void (*mrp_resmgr_notifier_event_callback_t)(mrp_resmgr_t *,
+ mrp_resmgr_event_t *);
struct mrp_resmgr_s {
mrp_htbl_t *resources;
mrp_resmgr_audio_t *audio;
mrp_resmgr_input_t *input;
+ mrp_resmgr_notifier_t *notifier;
+
void *scripting_data;
};
--- /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 <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <murphy/common.h>
+
+#include <murphy-db/mqi.h>
+
+#include <murphy/resource/config-api.h>
+#include <murphy/resource/manager-api.h>
+#include <murphy/resource/client-api.h>
+
+#include "screen.h"
+#include "notifier.h"
+#include "wayland/area.h"
+#include "wayland/output.h"
+#include "application/application.h"
+
+
+#ifdef BIT
+#undef BIT
+#endif
+#ifdef MASK
+#undef MASK
+#endif
+#ifdef MAX
+#undef MAX
+#endif
+
+#define BIT(i) ((uint32_t)1 << (i))
+#define MASK(w) (((uint32_t)1 << (w)) - 1)
+#define MAX(w) (((uint32_t)1 << (w)))
+
+#define PRIORITY_BITS 8
+#define CLASSPRI_BITS 8
+#define ZORDER_BITS 16
+
+#define PRIORITY_POSITION 0
+#define CLASSPRI_POSITION (PRIORITY_POSITION + PRIORITY_BITS)
+#define ZORDER_POSITION (CLASSPRI_POSITION + CLASSPRI_BITS)
+
+#define PRIORITY_MASK MASK(PRIORITY_BITS)
+#define CLASSPRI_MASK MASK(CLASSPRI_BITS)
+#define ZORDER_MASK MASK(ZORDER_BITS)
+
+#define PRIORITY_MAX MAX(PRIORITY_BITS)
+#define CLASSPRI_MAX MAX(CLASSPRI_BITS)
+#define ZORDER_MAX MAX(ZORDER_BITS)
+
+
+#define ATTRIBUTE(n,t,v) {n, MRP_RESOURCE_RW, mqi_##t, {.t=v}}
+#define ATTR_END {NULL, 0, 0, {.string=NULL}}
+
+typedef struct screen_resource_s screen_resource_t;
+
+
+struct screen_resource_s {
+ mrp_list_hook_t link;
+ mrp_resmgr_screen_t *screen;
+ mrp_resource_t *res;
+ uint32_t zoneid;
+ size_t areaid;
+ uint32_t key;
+ bool acquire;
+ bool grant;
+ uint32_t grantid;
+};
+
+static int hash_compare(const void *, const void *);
+static uint32_t hash_function(const void *);
+
+static void overlap_add(mrp_resmgr_screen_area_t *, size_t);
+static void overlap_remove(mrp_resmgr_screen_area_t *, size_t);
+
+static const char *get_appid_for_resource(mrp_resource_t *);
+static int32_t get_surfaceid_for_resource(mrp_resource_t *);
+static int32_t get_layerid_for_resource(mrp_resource_t *);
+static const char *get_areaname_for_resource(mrp_resource_t *);
+static mrp_application_t *get_application_for_resource(mrp_resource_t *);
+static int32_t get_area_for_resource(mrp_resource_t *);
+static uint32_t get_priority_for_resource(mrp_resource_t *);
+static uint32_t get_class_priority_for_resource(mrp_resource_t *,
+ mrp_application_class_t *);
+static int32_t get_zone_id(const char *);
+
+
+static screen_resource_t *screen_resource_create(mrp_resmgr_screen_t *,
+ mrp_zone_t *,mrp_resource_t *,
+ mrp_application_class_t *);
+static void screen_resource_destroy(mrp_resmgr_screen_t *, mrp_zone_t *,
+ mrp_resource_t *);
+static screen_resource_t *screen_resource_lookup(mrp_resmgr_screen_t *,
+ mrp_resource_t *);
+static bool screen_resource_is_on_top(mrp_resmgr_screen_t *,
+ screen_resource_t *);
+static void screen_resource_raise_to_top(mrp_resmgr_screen_t *,
+ screen_resource_t *);
+static void screen_resource_lower_to_bottom(mrp_resmgr_screen_t *,
+ screen_resource_t *);
+
+
+static uint32_t zorder_new_top_value(mrp_resmgr_screen_area_t *);
+
+static void screen_grant_resources(mrp_resmgr_screen_t *, mrp_zone_t *);
+static void screen_queue_events(mrp_resmgr_screen_t *, mrp_zone_t *);
+
+static void area_insert_resource(mrp_resmgr_screen_area_t*,screen_resource_t*);
+static uint32_t resource_key(mrp_resource_t *, mrp_application_class_t *);
+
+static void screen_notify(mrp_resource_event_t, mrp_zone_t *,
+ mrp_application_class_t *, mrp_resource_t *, void *);
+static void screen_init(mrp_zone_t *, void *);
+static bool screen_allocate(mrp_zone_t *, mrp_resource_t *, void *);
+static void screen_free(mrp_zone_t *, mrp_resource_t *, void *);
+static bool screen_advice(mrp_zone_t *, mrp_resource_t *, void *);
+static void screen_commit(mrp_zone_t *, void *);
+
+#define PRIORITY_ATTRIDX 0
+#define CLASSPRI_ATTRIDX 1
+#define AREA_ATTRIDX 2
+#define APPID_ATTRIDX 3
+#define SURFACE_ATTRIDX 4
+
+static mrp_attr_def_t screen_attrs[] = {
+ ATTRIBUTE("priority" , integer, 0 ),
+ ATTRIBUTE("classpri" , integer, -1 ),
+ ATTRIBUTE("area" , string , "<undefined>"),
+ ATTRIBUTE("appid" , string , "<undefined>"),
+ ATTRIBUTE("surface" , integer, 0 ),
+ ATTR_END
+};
+
+static mrp_resource_mgr_ftbl_t screen_ftbl = {
+ screen_notify,
+ screen_init,
+ screen_allocate,
+ screen_free,
+ screen_advice,
+ screen_commit
+};
+
+mrp_resmgr_screen_t *mrp_resmgr_screen_create(mrp_resmgr_t *resmgr)
+{
+ mrp_resmgr_screen_t *screen;
+ mrp_htbl_config_t cfg;
+ uint32_t resid;
+ size_t i;
+
+ if ((screen = mrp_allocz(sizeof(mrp_resmgr_screen_t)))) {
+ resid = mrp_resource_definition_create(MRP_SYSCTL_SCREEN_RESOURCE,
+ true,screen_attrs,
+ &screen_ftbl,screen);
+ mrp_lua_resclass_create_from_c(resid);
+
+ cfg.nentry = MRP_RESMGR_RESOURCE_MAX;
+ cfg.comp = hash_compare;
+ cfg.hash = hash_function;
+ cfg.free = NULL;
+ cfg.nbucket = MRP_RESMGR_RESOURCE_BUCKETS;
+
+ screen->resmgr = resmgr;
+ screen->resid = resid;
+ screen->resources = mrp_htbl_create(&cfg);
+
+ for (i = 0; i < MRP_ZONE_MAX; i++)
+ mrp_list_init(screen->zones + i);
+ }
+
+ return screen;
+}
+
+
+void mrp_resmgr_screen_destroy(mrp_resmgr_screen_t *screen)
+{
+ if (screen) {
+ mrp_htbl_destroy(screen->resources, false);
+ mrp_free(screen);
+ }
+}
+
+int mrp_resmgr_screen_print(mrp_resmgr_screen_t *screen,
+ uint32_t zoneid,
+ char *buf, int len)
+{
+#define PRINT(...) \
+ do { \
+ p += snprintf(p, e-p, __VA_ARGS__); \
+ if (p >= e) \
+ return p - buf; \
+ } while (0)
+
+ char *p, *e;
+ uint32_t grantid;
+ mrp_resmgr_screen_area_t *area;
+ mrp_list_hook_t *areas, *aentry, *an;
+ mrp_list_hook_t *resources, *rentry, *rn;
+ screen_resource_t *sr;
+ mrp_attr_t a;
+ size_t i;
+
+ MRP_ASSERT(screen && buf && len > 0, "invalid argument");
+
+ e = (p = buf) + len;
+ *p = 0;
+
+ if (zoneid < MRP_ZONE_MAX) {
+ areas = screen->zones + zoneid;
+ grantid = screen->grantids[zoneid];
+ }
+ else {
+ areas = NULL;
+ grantid = 0;
+ }
+
+ PRINT(" Resource 'screen' - grantid:%u\n", grantid);
+
+ if (!areas || mrp_list_empty(areas))
+ PRINT(" No resources\n");
+ else {
+ mrp_list_foreach_back(areas, aentry, an) {
+ area = mrp_list_entry(aentry, mrp_resmgr_screen_area_t, link);
+ resources = &area->resources;
+
+ PRINT(" Area '%s':\n", area->name);
+
+ mrp_list_foreach_back(resources, rentry, rn) {
+ sr = mrp_list_entry(rentry, screen_resource_t, link);
+
+ PRINT(" 0x%08x %s %u",
+ sr->key, sr->acquire ? "acquire":"release", sr->grantid);
+
+ for (i = 0; i < MRP_ARRAY_SIZE(screen_attrs) - 1; i++) {
+ if ((mrp_resource_read_attribute(sr->res, i, &a))) {
+ PRINT(" %s:", a.name);
+
+ switch (a.type) {
+ case mqi_string: PRINT("'%s'",a.value.string); break;
+ case mqi_integer: PRINT("%d",a.value.integer); break;
+ case mqi_unsignd: PRINT("%u",a.value.unsignd); break;
+ case mqi_floating: PRINT("%lf",a.value.floating);break;
+ default: PRINT("<unsupported type>"); break;
+ }
+ }
+ }
+
+ PRINT("\n");
+ } /* mrp_list_foreach_back - resources */
+ } /* mrp_list_foreach_back - areas */
+ }
+
+ return p - buf;
+}
+
+
+void mrp_resmgr_screen_area_create(mrp_resmgr_screen_t *screen,
+ mrp_wayland_area_t *wlarea,
+ const char *zonename)
+{
+ mrp_resmgr_screen_area_t *rmarea, *a;
+ int32_t zoneid;
+ size_t areaid;
+ const char *name;
+ int32_t outputid;
+ size_t i;
+ int32_t x, x0, x1, y, y0, y1;
+
+ MRP_ASSERT(screen && wlarea && wlarea->output && zonename,
+ "invalid argument");
+
+ if (wlarea->areaid < 0 || wlarea->areaid >= MRP_WAYLAND_AREA_MAX) {
+ mrp_log_error("system-controller: refuse to create screen area '%s': "
+ "id %d is out of range (0 - %d)",
+ wlarea->name, wlarea->areaid, MRP_WAYLAND_AREA_MAX - 1);
+ return;
+ }
+
+ areaid = wlarea->areaid;
+ name = wlarea->name ? wlarea->name : "<unknown>";
+ outputid = wlarea->output->outputid;
+
+ if ((zoneid = get_zone_id(zonename))) {
+ mrp_log_error("system-controller: can't create resource manager area "
+ "%d: can't find zone '%s' for it", areaid, zonename);
+ return;
+ }
+
+ if (areaid >= screen->narea) {
+ screen->areas = mrp_reallocz(screen->areas, screen->narea, areaid + 1);
+
+ MRP_ASSERT(screen->areas, "can't allocate memory for screen areas");
+
+ screen->narea = areaid + 1;
+ }
+
+ if (screen->areas[areaid]) {
+ mrp_log_error("system-controller: attempt to redefine "
+ "resource manager area %d", areaid);
+ return;
+ }
+
+ screen->areas[areaid] = rmarea = mrp_allocz(sizeof(*rmarea));
+
+ mrp_list_append(screen->zones + zoneid, &rmarea->link);
+ rmarea->name = mrp_strdup(name);
+ rmarea->outputid = outputid;
+ rmarea->x = wlarea->x;
+ rmarea->y = wlarea->y;
+ rmarea->width = wlarea->width;
+ rmarea->height = wlarea->height;
+ mrp_list_init(&rmarea->resources);
+
+ x1 = (x0 = rmarea->x) + rmarea->width;
+ y1 = (y0 = rmarea->y) + rmarea->height;
+
+ for (i = 0; i < screen->narea; i++) {
+ if ((a = screen->areas[i]) && i != areaid) {
+ if (( a->outputid == outputid ) &&
+ (((x = a->x ) >= x0 && x < x1) ||
+ ((x += a->width ) >= x0 && x < x1) ||
+ ((y = a->y ) >= y0 && y < y1) ||
+ ((y += a->height) >= y0 && y < y1) ) )
+ {
+ overlap_add(a, areaid);
+ overlap_add(rmarea, i);
+ }
+ }
+ }
+
+ mrp_log_info("system-controller: resource manager registered screen area "
+ "%d - '%s'", areaid, name);
+}
+
+void mrp_screen_area_destroy(mrp_resmgr_screen_t *screen, int32_t areaid)
+{
+ mrp_resmgr_screen_area_t *area;
+ size_t i;
+
+ MRP_ASSERT(screen && areaid >= 0 && areaid < MRP_WAYLAND_AREA_MAX,
+ "invalid argument");
+
+ if (areaid >= (int32_t)screen->narea || !(area = screen->areas[areaid])) {
+ mrp_log_error("system-controller: attempt to destroy non-existent "
+ "resource manager area %d", areaid);
+ }
+ else {
+ screen->areas[areaid] = NULL;
+
+ for (i = 0; i < area->noverlap; i++)
+ overlap_remove(screen->areas[area->overlaps[i]], areaid);
+
+ mrp_free((void *)area->name);
+ mrp_free((void *)area->overlaps);
+ mrp_free(area);
+ }
+}
+
+void mrp_screen_resource_raise(mrp_resmgr_screen_t *screen,
+ const char *appid,
+ int32_t surfaceid)
+{
+ mrp_resmgr_screen_area_t *area;
+ mrp_list_hook_t *resources, *entry, *n;
+ screen_resource_t *sr;
+ mrp_resource_t *res;
+ const char *id;
+ size_t i, cnt;
+ size_t zmax, zmin;
+ bool zones[MRP_ZONE_MAX];
+
+ MRP_ASSERT(screen && screen->resources && appid, "invalid argument");
+
+ if (surfaceid == 0) {
+ cnt = 0;
+ zmax = 0;
+ zmin = MRP_ZONE_MAX-1;
+
+ for (i = cnt = 0; i < screen->narea; i++) {
+ area = screen->areas[i];
+ resources = &area->resources;
+
+ mrp_list_foreach(resources, entry, n) {
+ sr = mrp_list_entry(entry, screen_resource_t, link);
+ res = sr->res;
+
+ if ((id = get_appid_for_resource(res)) && !strcmp(id, appid)) {
+ mrp_debug("raise surface %d to top", surfaceid);
+
+ if (!screen_resource_is_on_top(screen, sr)) {
+ screen_resource_raise_to_top(screen, sr);
+
+ cnt++;
+ zones[sr->zoneid] = true;
+ if (zmax < sr->zoneid) zmax = sr->zoneid;
+ if (zmin > sr->zoneid) zmin = sr->zoneid;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!cnt)
+ mrp_debug("nothing to be raised");
+ else {
+ for (i = zmin; i <= zmax; i++) {
+ if (zones[i])
+ mrp_resource_owner_recalc(i);
+ }
+ }
+ }
+ else {
+ if ((sr = mrp_htbl_lookup(screen->resources, NULL + surfaceid))) {
+ res = sr->res;
+
+ if (!(id = get_appid_for_resource(res)) || strcmp(id, appid)) {
+ mrp_log_error("system-controller: can't raise window %u: "
+ "appid mismatch ('%s' vs. '%s')",
+ surfaceid, id, appid);
+ }
+ else {
+ if (screen_resource_is_on_top(screen, sr)) {
+ mrp_debug("nothing to be raised: surface %d "
+ "is already on top", surfaceid);
+ }
+ else {
+ mrp_debug("raise surface %d to top", surfaceid);
+ screen_resource_raise_to_top(screen, sr);
+ mrp_resource_owner_recalc(sr->zoneid);
+ }
+ }
+ }
+ }
+}
+
+void mrp_screen_resource_lower(mrp_resmgr_screen_t *screen,
+ const char *appid,
+ int32_t surfaceid)
+{
+ mrp_resmgr_screen_area_t *area;
+ mrp_list_hook_t *resources, *entry, *n;
+ screen_resource_t *sr;
+ mrp_resource_t *res;
+ const char *id;
+ size_t i, cnt;
+ size_t zmax, zmin;
+ bool zones[MRP_ZONE_MAX];
+
+ MRP_ASSERT(screen && screen->resources && appid, "invalid argument");
+
+ if (surfaceid == 0) {
+ cnt = 0;
+ zmax = 0;
+ zmin = MRP_ZONE_MAX-1;
+
+ for (i = cnt = 0; i < screen->narea; i++) {
+ area = screen->areas[i];
+ resources = &area->resources;
+
+ mrp_list_foreach_back(resources, entry, n) {
+ sr = mrp_list_entry(entry, screen_resource_t, link);
+ res = sr->res;
+
+ if ((id = get_appid_for_resource(res)) && !strcmp(id, appid)) {
+ mrp_debug("lower surface %d to bottom", surfaceid);
+
+ screen_resource_lower_to_bottom(screen, sr);
+
+ cnt++;
+ zones[sr->zoneid] = true;
+ if (zmax < sr->zoneid) zmax = sr->zoneid;
+ if (zmin > sr->zoneid) zmin = sr->zoneid;
+ }
+ }
+ }
+
+ if (!cnt)
+ mrp_debug("nothing to be lowered");
+ else {
+ for (i = zmin; i <= zmax; i++) {
+ if (zones[i])
+ mrp_resource_owner_recalc(i);
+ }
+ }
+ }
+ else {
+ if ((sr = mrp_htbl_lookup(screen->resources, NULL + surfaceid))) {
+ res = sr->res;
+
+ if (!(id = get_appid_for_resource(res)) || strcmp(id, appid)) {
+ mrp_log_error("system-controller: can't lower window %u: "
+ "appid mismatch ('%s' vs. '%s')",
+ surfaceid, id, appid);
+ }
+ else {
+ mrp_debug("lower surface %d to bottom", surfaceid);
+ screen_resource_lower_to_bottom(screen, sr);
+ mrp_resource_owner_recalc(sr->zoneid);
+ }
+ }
+ }
+}
+
+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)(key - (const void *)0);
+}
+
+static void overlap_add(mrp_resmgr_screen_area_t *area, size_t overlapid)
+{
+ size_t i;
+
+ for (i = 0; i < area->noverlap; i++) {
+ if (area->overlaps[i] == overlapid)
+ return;
+ }
+
+ area->overlaps = mrp_realloc(area->overlaps, sizeof(size_t *) * (i + 1));
+
+ MRP_ASSERT(area->overlaps, "can't allocate memory for overalapping "
+ "resource manager areas");
+
+ area->overlaps[i] = overlapid;
+ area->noverlap++;
+}
+
+static void overlap_remove(mrp_resmgr_screen_area_t *area, size_t overlapid)
+{
+ size_t i;
+
+ for (i = 0; i < area->noverlap; i++) {
+ if (area->overlaps[i] == overlapid) {
+ for (i++; i < area->noverlap; i++)
+ area->overlaps[i-1] = area->overlaps[i];
+ area->noverlap--;
+ return;
+ }
+ }
+
+ mrp_log_error("system-controller: attempt to remove unregistered "
+ "overlapping area");
+}
+
+static const char *get_appid_for_resource(mrp_resource_t *res)
+{
+ mrp_attr_t attr;
+ const char *appid;
+
+ if (!mrp_resource_read_attribute(res, APPID_ATTRIDX, &attr) ||
+ attr.type != mqi_string || !(appid = attr.value.string) )
+ appid = NULL;
+
+ return appid;
+}
+
+static int32_t get_surfaceid_for_resource(mrp_resource_t *res)
+{
+ mrp_attr_t attr;
+
+ if (mrp_resource_read_attribute(res, SURFACE_ATTRIDX, &attr)) {
+ if (attr.type == mqi_integer)
+ return attr.value.integer;
+ }
+
+ return 0;
+}
+
+static int32_t get_layerid_for_resource(mrp_resource_t *res)
+{
+ MRP_UNUSED(res);
+
+ return -1;
+}
+
+static const char *get_areaname_for_resource(mrp_resource_t *res)
+{
+ mrp_attr_t attr;
+
+ if (mrp_resource_read_attribute(res, AREA_ATTRIDX, &attr)) {
+ if (attr.type == mqi_string)
+ return attr.value.string;
+ }
+
+ return NULL;
+}
+
+static mrp_application_t *get_application_for_resource(mrp_resource_t *res)
+{
+ const char *appid = get_appid_for_resource(res);
+ mrp_application_t *app = NULL;
+
+ if (!appid || !(app = mrp_application_find(appid)))
+ app = mrp_application_find(MRP_SYSCTL_APPID_DEFAULT);
+
+ return app;
+}
+
+static int32_t get_area_for_resource(mrp_resource_t *res)
+{
+ mrp_wayland_t *wl;
+ mrp_wayland_area_t *a;
+ const char *areaname;
+ void *it;
+
+ if ((areaname = get_areaname_for_resource(res))) {
+ mrp_wayland_foreach(wl, it) {
+ if ((a = mrp_wayland_area_find(wl, areaname)))
+ return a->areaid;
+ }
+ }
+
+ return -1;
+}
+
+
+static uint32_t get_priority_for_resource(mrp_resource_t *res)
+{
+ mrp_attr_t attr;
+ uint32_t priority = 0;
+
+ if (mrp_resource_read_attribute(res, PRIORITY_ATTRIDX, &attr)) {
+ if (attr.type == mqi_integer && attr.value.integer >= 0)
+ priority = attr.value.integer;
+ }
+
+ return priority;
+}
+
+static uint32_t get_class_priority_for_resource(mrp_resource_t *res,
+ mrp_application_class_t *ac)
+{
+ mrp_attr_t attr;
+ uint32_t priority;
+
+ priority = mrp_application_class_get_priority(ac);
+
+ if (mrp_resource_read_attribute(res, CLASSPRI_ATTRIDX, &attr)) {
+ if (attr.type == mqi_integer && attr.value.integer >= 0)
+ priority = attr.value.integer;
+ }
+
+ return priority;
+}
+
+static int32_t get_zone_id(const char *name)
+{
+ const char *zones[MRP_ZONE_MAX + 1];
+ const char *zone;
+ int32_t id;
+
+ if (mrp_zone_get_all_names(MRP_ZONE_MAX + 1, zones)) {
+ for (id = 0; (zone = zones[id]); id++) {
+ if (!strcmp(name, zone))
+ return id;
+ }
+ }
+
+ return -1;
+}
+
+
+
+static screen_resource_t *screen_resource_create(mrp_resmgr_screen_t *screen,
+ mrp_zone_t *zone,
+ mrp_resource_t *res,
+ mrp_application_class_t *ac)
+{
+ mrp_resmgr_t *resmgr;
+ mrp_application_t *app;
+ mrp_resmgr_screen_area_t *area;
+ int32_t areaid;
+ int32_t surfaceid;
+ screen_resource_t *sr;
+ void *hk;
+
+ MRP_ASSERT(screen && screen->resources && zone && res && ac,
+ "invalid argument");
+ MRP_ASSERT(screen->resmgr, "confused with data structures");
+
+ resmgr = screen->resmgr;
+ sr = NULL;
+
+ if (!(app = get_application_for_resource(res))) {
+ mrp_log_error("system-controller: failed to create screen resource: "
+ "can't find app");
+ return NULL;
+ }
+
+ if ((areaid = get_area_for_resource(res)) < 0 ||
+ (size_t)areaid >= screen->narea ||
+ !(area = screen->areas[areaid]) )
+ {
+ mrp_log_error("system-controller: failed to create screen resource: "
+ "can't find area");
+ return NULL;
+ }
+
+ if (!(surfaceid = get_surfaceid_for_resource(res))) {
+ mrp_log_error("system-controller: failed to create screen resource: "
+ "invalid surface attribute");
+ return NULL;
+ }
+
+ if (!(sr = mrp_allocz(sizeof(*sr)))) {
+ mrp_log_error("system-controller: failed to create screen resource: "
+ "can't allocate memory");
+ return NULL;
+ }
+
+ mrp_list_init(&sr->link);
+ sr->screen = screen;
+ sr->res = res;
+ sr->zoneid = mrp_zone_get_id(zone);
+ sr->areaid = areaid;
+ sr->key = resource_key(res, ac);
+
+ area_insert_resource(area, sr);
+
+ mrp_debug("inserting resource to hash table: key=%p value=%p", res, sr);
+ mrp_resmgr_insert_resource(resmgr, zone, res, sr);
+
+ hk = NULL + surfaceid;
+ mrp_debug("inserting surface to hash table: key=%p value=%p", hk, sr);
+ mrp_htbl_insert(screen->resources, hk, sr);
+
+ return sr;
+}
+
+
+static void screen_resource_destroy(mrp_resmgr_screen_t *screen,
+ mrp_zone_t *zone,
+ mrp_resource_t *res)
+{
+ screen_resource_t *sr;
+ int32_t surfaceid;
+
+ MRP_ASSERT(res && screen && screen->resources, "invalid argument");
+ MRP_ASSERT(screen->resmgr, "confused with data structures");
+
+ if ((sr = mrp_resmgr_remove_resource(screen->resmgr, zone, res))) {
+
+ if ((surfaceid = get_surfaceid_for_resource(res)))
+ mrp_htbl_remove(screen->resources, NULL + surfaceid, false);
+
+ mrp_list_delete(&sr->link);
+ mrp_free(sr);
+ }
+}
+
+
+static screen_resource_t *screen_resource_lookup(mrp_resmgr_screen_t *screen,
+ mrp_resource_t *res)
+{
+ screen_resource_t *sr;
+
+ MRP_ASSERT(res && screen, "invalid argument");
+ MRP_ASSERT(screen->resmgr, "confused with data structures");
+
+ sr = mrp_resmgr_lookup_resource(screen->resmgr, res);
+
+ return sr;
+}
+
+static bool screen_resource_is_on_top(mrp_resmgr_screen_t *screen,
+ screen_resource_t *sr)
+{
+ mrp_resmgr_screen_area_t *area;
+ bool on_top;
+
+ if (sr->areaid >= screen->narea || !(area = screen->areas[sr->areaid]))
+ on_top = false;
+ else
+ on_top = (area->resources.prev == &sr->link);
+
+ return on_top;
+}
+
+static void screen_resource_raise_to_top(mrp_resmgr_screen_t *screen,
+ screen_resource_t *sr)
+{
+ mrp_resmgr_screen_area_t *area;
+
+ if (sr->areaid >= screen->narea || !(area = screen->areas[sr->areaid])) {
+ mrp_log_error("system-controller: failed to raise screen resource: "
+ "can't find area for screen");
+ }
+ else {
+ sr->key &= ~(ZORDER_MASK << ZORDER_POSITION);
+ sr->key |= zorder_new_top_value(area);
+
+ area_insert_resource(area, sr);
+ }
+
+ sr->acquire = true;
+}
+
+
+static void screen_resource_lower_to_bottom(mrp_resmgr_screen_t *screen,
+ screen_resource_t *sr)
+{
+ mrp_resmgr_screen_area_t *area;
+
+ if (sr->areaid >= screen->narea || !(area = screen->areas[sr->areaid])) {
+ mrp_log_error("system-controller: failed to lower screen resource: "
+ "can't find area for screen");
+ }
+ else {
+ sr->key &= ~(ZORDER_MASK << ZORDER_POSITION);
+
+ area_insert_resource(area, sr);
+ }
+
+ sr->acquire = false;
+}
+
+
+static uint32_t zorder_new_top_value(mrp_resmgr_screen_area_t *area)
+{
+ mrp_list_hook_t *resources, *entry, *n;
+ screen_resource_t *sr;
+ uint32_t new_top, min, max, z;
+
+ if ((new_top = ++(area->zorder)) >= ZORDER_MAX) {
+ /*
+ * we get here in the unlikely event of z-order value overflow
+ * what we try to do here is to find out the range of the z values
+ * and subtract from all the minimum value, ie. move the whole range
+ * to start from zero.
+ */
+ resources = &area->resources;
+
+ if (mrp_list_empty(resources))
+ new_top = area->zorder = 1;
+ else {
+ min = ZORDER_MAX;
+ max = 0;
+
+ mrp_list_foreach(resources, entry, n) {
+ sr = mrp_list_entry(entry, screen_resource_t, link);
+ z = ((sr->key >> ZORDER_POSITION) & ZORDER_MASK);
+
+ if (z < min) min = z;
+ if (z > max) max = z;
+ }
+
+ /* assert if the range moving would not help */
+ MRP_ASSERT(min < ZORDER_MAX-1, "Z-order overflow");
+
+ mrp_list_foreach(resources, entry, n) {
+ sr = mrp_list_entry(entry, screen_resource_t, link);
+ z = ((sr->key >> ZORDER_POSITION) & ZORDER_MASK) - min;
+
+ sr->key &= ~(ZORDER_MASK << ZORDER_POSITION);
+ sr->key |= (z << ZORDER_POSITION);
+ }
+
+ new_top = area->zorder = (max - min) + 1;
+ }
+ }
+
+ return (new_top << ZORDER_POSITION);
+}
+
+
+static void screen_grant_resources(mrp_resmgr_screen_t *screen,
+ mrp_zone_t *zone)
+{
+ uint32_t zoneid;
+ uint32_t grantid;
+ mrp_list_hook_t *areas, *aentry, *an;
+ mrp_list_hook_t *resources, *rentry , *rn;
+ mrp_resmgr_screen_area_t *area;
+ screen_resource_t *sr;
+
+ zoneid = mrp_zone_get_id(zone);
+ areas = screen->zones + zoneid;
+ grantid = ++(screen->grantids[zoneid]);
+
+ mrp_list_foreach(areas, aentry, an) {
+ area = mrp_list_entry(aentry, mrp_resmgr_screen_area_t, link);
+ resources = &area->resources;
+
+ mrp_list_foreach_back(resources, rentry, rn) {
+ sr = mrp_list_entry(rentry, screen_resource_t, link);
+
+ if (sr->acquire) {
+ sr->grantid = grantid;
+ break;
+ }
+ }
+ }
+}
+
+static void screen_queue_events(mrp_resmgr_screen_t *screen, mrp_zone_t *zone)
+{
+ uint32_t zoneid;
+ uint32_t grantid;
+ mrp_list_hook_t *areas, *aentry, *an;
+ mrp_list_hook_t *resources, *rentry, *rn;
+ mrp_resmgr_screen_area_t *area;
+ screen_resource_t *sr;
+ bool grant;
+ mrp_resmgr_eventid_t eventid;
+ const char *appid, *areaname;
+ int32_t surfaceid, layerid;
+
+ zoneid = mrp_zone_get_id(zone);
+ areas = screen->zones + zoneid;
+ grantid = screen->grantids[zoneid];
+
+ mrp_list_foreach(areas, aentry, an) {
+ area = mrp_list_entry(aentry, mrp_resmgr_screen_area_t, link);
+ resources = &area->resources;
+
+
+ mrp_list_foreach_back(resources, rentry, rn) {
+ sr = mrp_list_entry(rentry, screen_resource_t, link);
+ grant = (grantid == sr->grantid);
+
+ if ((grant && !sr->grant) || (!grant && sr->grant)) {
+
+ eventid = grant ? MRP_RESMGR_EVENTID_GRANT :
+ MRP_RESMGR_EVENTID_REVOKE;
+ appid = get_appid_for_resource(sr->res);
+ surfaceid = get_surfaceid_for_resource(sr->res);
+ layerid = get_layerid_for_resource(sr->res);
+ areaname = get_areaname_for_resource(sr->res);
+
+ mrp_resmgr_notifier_queue_screen_event(screen->resmgr,
+ zoneid, eventid,
+ appid, surfaceid,
+ layerid, areaname);
+ }
+
+ sr->grant = grant;
+ }
+ }
+}
+
+
+static void area_insert_resource(mrp_resmgr_screen_area_t *area,
+ screen_resource_t *resource)
+{
+ mrp_list_hook_t *resources, *insert_after, *n;
+ screen_resource_t *sr;
+ uint32_t key;
+
+ mrp_list_delete(&resource->link);
+
+ resources = &area->resources;
+ key = resource->key;
+ insert_after = resources; /* keep the compiler happy: foreach below
+ will do it anyways */
+
+ mrp_list_foreach_back(resources, insert_after, n) {
+ sr = mrp_list_entry(insert_after, screen_resource_t, link);
+ if (key >= sr->key)
+ break;
+ }
+
+ mrp_list_insert_after(insert_after, &resource->link);
+}
+
+static uint32_t resource_key(mrp_resource_t *res, mrp_application_class_t *ac)
+{
+ uint32_t priority;
+ uint32_t classpri;
+ uint32_t key = 0;
+
+ if (res && ac) {
+ priority = get_priority_for_resource(res);
+ classpri = get_class_priority_for_resource(res, ac);
+ key = ((priority & PRIORITY_MASK) << PRIORITY_POSITION) |
+ ((classpri & CLASSPRI_MASK) << CLASSPRI_POSITION) ;
+ }
+
+ return key;
+}
+
+static void screen_notify(mrp_resource_event_t event,
+ mrp_zone_t *zone,
+ mrp_application_class_t *ac,
+ mrp_resource_t *res,
+ void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ const char *zonename = mrp_zone_get_name(zone);
+ screen_resource_t *sr;
+
+ MRP_ASSERT(zone && ac && res && screen, "invalid argument");
+
+ switch (event) {
+
+ case MRP_RESOURCE_EVENT_CREATED:
+ mrp_debug("screen resource in zone '%s' created", zonename);
+ screen_resource_create(screen, zone, res, ac);
+ break;
+
+ case MRP_RESOURCE_EVENT_DESTROYED:
+ mrp_debug("screen resource in zone '%s' destroyed", zonename);
+ screen_resource_destroy(screen, zone, res);
+ break;
+
+ case MRP_RESOURCE_EVENT_ACQUIRE:
+ mrp_debug("screen resource in zone '%s' is acquiring", zonename);
+ if (!(sr = screen_resource_lookup(screen, res)))
+ goto no_screen_resource;
+ else
+ screen_resource_raise_to_top(screen, sr);
+ break;
+
+ case MRP_RESOURCE_EVENT_RELEASE:
+ mrp_debug("screen resource in zone '%s' is released", zonename);
+ if (!(sr = screen_resource_lookup(screen, res)))
+ goto no_screen_resource;
+ else
+ screen_resource_lower_to_bottom(screen, sr);
+ break;
+
+ no_screen_resource:
+ mrp_debug("resource lookup in hash table failed: key=%p", res);
+ mrp_log_error("system-controller: can't find screen resource "
+ "in zone '%s'", zonename);
+ break;
+
+ default:
+ mrp_log_error("system-controller: invalid event %d at screen "
+ "notification (zone '%s')", event, zonename);
+ break;
+ }
+}
+
+static void screen_init(mrp_zone_t *zone, void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ const char *zonename = mrp_zone_get_name(zone);
+
+ MRP_ASSERT(screen, "invalid argument");
+
+ mrp_debug("screen init in zone '%s'", zonename);
+
+ screen_grant_resources(screen, zone);
+}
+
+static bool screen_allocate(mrp_zone_t *zone,
+ mrp_resource_t *res,
+ void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ uint32_t zoneid;
+ screen_resource_t *sr;
+ uint32_t grantid;
+
+ MRP_ASSERT(zone && res && screen && screen->resmgr, "invalid argument");
+
+ zoneid = mrp_zone_get_id(zone);
+ grantid = screen->grantids[zoneid];
+
+ if ((sr = screen_resource_lookup(screen, res)))
+ return (sr->grantid == grantid);
+
+ mrp_log_error("system-controller: attempt to allocate untracked resource");
+
+ return FALSE;
+}
+
+static void screen_free(mrp_zone_t *zone, mrp_resource_t *res, void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ const char *zonename = mrp_zone_get_name(zone);
+ screen_resource_t *sr;
+
+ MRP_ASSERT(screen && res, "invalid argument");
+
+ mrp_debug("screen free in zone '%s'", zonename);
+
+ if ((sr = screen_resource_lookup(screen, res)))
+ sr->grantid = 0;
+}
+
+static bool screen_advice(mrp_zone_t *zone,mrp_resource_t *res,void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ const char *zonename = mrp_zone_get_name(zone);
+
+ MRP_UNUSED(res);
+
+ MRP_ASSERT(screen, "invalid argument");
+
+ mrp_debug("screen advice in zone '%s'", zonename);
+
+ return TRUE;
+}
+
+static void screen_commit(mrp_zone_t *zone, void *userdata)
+{
+ mrp_resmgr_screen_t *screen = (mrp_resmgr_screen_t *)userdata;
+ const char *zonename;
+ uint32_t zoneid;
+
+ MRP_ASSERT(zone && screen && screen->resmgr, "invalid argument");
+
+ zonename = mrp_zone_get_name(zone);
+ zoneid = mrp_zone_get_id(zone);
+
+ mrp_debug("screen commit in zone '%s'", zonename);
+
+ screen_queue_events(screen, zone);
+ mrp_resmgr_notifier_flush_screen_events(screen->resmgr, zoneid);
+}
--- /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_SCREEN_H__
+#define __MURPHY_SYSTEM_CONTROLLER_SCREEN_H__
+
+#include <sys/types.h>
+
+#include <murphy/common/hashtbl.h>
+
+#include "resource-manager.h"
+#include "wayland/wayland.h"
+
+struct mrp_resmgr_screen_area_s {
+ mrp_list_hook_t link; /* to maintain the list of areas in a zone */
+ const char *name;
+ int32_t outputid;
+ int32_t x, y;
+ int32_t width, height;
+ mrp_list_hook_t resources;
+ size_t noverlap;
+ size_t *overlaps;
+ int32_t zorder;
+};
+
+struct mrp_resmgr_screen_s {
+ mrp_resmgr_t *resmgr;
+ uint32_t resid;
+ mrp_htbl_t *resources; /* to access resources by surfaceid */
+ mrp_list_hook_t zones[MRP_ZONE_MAX]; /* list of areas in the zones */
+ uint32_t grantids[MRP_ZONE_MAX];
+ size_t narea;
+ mrp_resmgr_screen_area_t **areas; /* areas to access by index */
+};
+
+
+mrp_resmgr_screen_t *mrp_resmgr_screen_create(mrp_resmgr_t *resmgr);
+void mrp_resmgr_screen_destroy(mrp_resmgr_screen_t *screen);
+
+int mrp_resmgr_screen_print(mrp_resmgr_screen_t *screen, uint32_t areaid,
+ char *buf, int len);
+
+void mrp_resmgr_screen_area_create(mrp_resmgr_screen_t *screen,
+ mrp_wayland_area_t *wlarea,
+ const char *zonename);
+void mrp_screen_area_destroy(mrp_resmgr_screen_t *screen,
+ int32_t areaid);
+
+void mrp_screen_resource_raise(mrp_resmgr_screen_t *screen,
+ const char *appid,
+ int32_t surfaceid);
+void mrp_screen_resource_lower(mrp_resmgr_screen_t *screen,
+ const char *appid,
+ int32_t surfaceid);
+
+
+#endif /* __MURPHY_SYSTEM_CONTROLLER_SCREEN_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 "notifier.h"
+
+#define SCREEN_EVENT_CLASS MRP_LUA_CLASS_SIMPLE(screen_event)
+
+typedef struct scripting_screen_event_s scripting_screen_event_t;
+
+struct scripting_screen_event_s {
+ const char *eventid;
+ const char *appid;
+ int32_t surfaceid;
+ int32_t layerid;
+ const char *area;
+};
+
+static int screen_event_create_from_lua(lua_State *);
+static int screen_event_getfield(lua_State *);
+static int screen_event_setfield(lua_State *);
+static int screen_event_stringify(lua_State *);
+static void screen_event_destroy_from_lua(void *);
+
+static scripting_screen_event_t *screen_event_check(lua_State *, int);
+
+MRP_LUA_CLASS_DEF_SIMPLE (
+ screen_event, /* class name */
+ scripting_screen_event_t, /* userdata type */
+ screen_event_destroy_from_lua, /* userdata destructor */
+ MRP_LUA_METHOD_LIST ( /* methods */
+ MRP_LUA_METHOD_CONSTRUCTOR (screen_event_create_from_lua)
+ ),
+ MRP_LUA_METHOD_LIST ( /* overrides */
+ MRP_LUA_OVERRIDE_CALL (screen_event_create_from_lua)
+ MRP_LUA_OVERRIDE_GETFIELD (screen_event_getfield)
+ MRP_LUA_OVERRIDE_SETFIELD (screen_event_setfield)
+ MRP_LUA_OVERRIDE_STRINGIFY (screen_event_stringify)
+ )
+);
+
+void mrp_resmgr_scripting_notifier_init(lua_State *L)
+{
+ mrp_lua_create_object_class(L, SCREEN_EVENT_CLASS);
+}
+
+
+void *mrp_resmgr_scripting_screen_event_create_from_c(lua_State *L,
+ mrp_resmgr_event_t *event)
+{
+ scripting_screen_event_t *sev;
+ const char *eventid;
+
+ MRP_ASSERT(event, "invald argument");
+
+ if (!L && !(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("system-controller: can't create scripting screen event:"
+ " LUA is not initialized");
+ return NULL;
+ }
+
+ switch (event->eventid) {
+
+ case MRP_RESMGR_EVENTID_GRANT: eventid = "grant"; break;
+ case MRP_RESMGR_EVENTID_REVOKE: eventid = "revoke"; break;
+
+ default:
+ mrp_log_error("system-controller: can't create scripting screen event:"
+ " invalid event ID %d", event->eventid);
+ return NULL;
+ }
+
+ sev = (scripting_screen_event_t *)mrp_lua_create_object(L,
+ SCREEN_EVENT_CLASS,
+ NULL, 0);
+ if (!sev) {
+ mrp_log_error("system-controller: can't create scripting screen event:"
+ " LUA object creation failed");
+ return NULL;
+ }
+
+ sev->eventid = eventid;
+ sev->appid = mrp_strdup(event->appid);
+ sev->surfaceid = event->surfaceid;
+ sev->layerid = event->layerid;
+ sev->area = mrp_strdup(event->area);
+
+ return sev;
+}
+
+
+static int screen_event_create_from_lua(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ luaL_error(L, "screen_event can't be created from LUA");
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int screen_event_getfield(lua_State *L)
+{
+ scripting_screen_event_t *sev;
+ 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);
+
+ if (!(sev = screen_event_check(L, 1)))
+ lua_pushnil(L);
+ else {
+ switch (fld) {
+ case TYPE: lua_pushstring(L, "screen"); break;
+ case EVENT: lua_pushstring(L, sev->eventid); break;
+ case APPID: lua_pushstring(L, sev->appid); break;
+ case SURFACE: lua_pushinteger(L, sev->surfaceid); break;
+ case LAYER: lua_pushinteger(L, sev->layerid); break;
+ case AREA: lua_pushstring(L, sev->area); break;
+ default: lua_pushnil(L); break;
+ }
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static int screen_event_setfield(lua_State *L)
+{
+ MRP_LUA_ENTER;
+
+ screen_event_check(L, 1);
+ luaL_error(L, "screen_event objects are read-only");
+
+ MRP_LUA_LEAVE(0);
+}
+
+static int screen_event_stringify(lua_State *L)
+{
+ scripting_screen_event_t *sev;
+ char *p, *e;
+ char buf[4096];
+
+ MRP_LUA_ENTER;
+
+ if (!(sev = screen_event_check(L, 1)))
+ lua_pushnil(L);
+ else {
+ e = (p = buf) + sizeof(buf);
+ p += snprintf(p, e-p, "screen_event %s\n appid: '%s'\n"
+ " surface: %d\n layer: %d\n area: '%s'",
+ sev->eventid, sev->appid, sev->surfaceid, sev->layerid,
+ sev->area);
+
+ lua_pushlstring(L, buf, p-buf);
+ }
+
+ MRP_LUA_LEAVE(1);
+}
+
+static void screen_event_destroy_from_lua(void *data)
+{
+ scripting_screen_event_t *sev = (scripting_screen_event_t *)data;
+
+ MRP_LUA_ENTER;
+
+ if (sev) {
+ mrp_free((void *)sev->appid);
+ mrp_free((void *)sev->area);
+ mrp_free((void *)sev);
+ }
+
+ MRP_LUA_LEAVE_NOARG;
+}
+
+
+static scripting_screen_event_t *screen_event_check(lua_State *L, int idx)
+{
+ return (scripting_screen_event_t *)mrp_lua_check_object(L,
+ SCREEN_EVENT_CLASS,
+ idx);
+}
#include "scripting-resource-manager.h"
#include "wayland/scripting-wayland.h"
+#include "screen.h"
+#include "notifier.h"
#define RESOURCE_MANAGER_CLASS MRP_LUA_CLASS_SIMPLE(resource_manager)
struct scripting_resmgr_s {
mrp_resmgr_t *resmgr;
+ mrp_funcbridge_t *screen_event_handler;
};
struct funcbridge_def_s {
};
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 void screen_event_handler_callback(mrp_resmgr_t *,mrp_resmgr_event_t *);
+
static bool register_methods(lua_State *);
static mrp_funcbridge_t *area_create;
-
+static mrp_funcbridge_t *window_raise;
void mrp_resmgr_scripting_init(lua_State *L)
{
mrp_lua_create_object_class(L, RESOURCE_MANAGER_CLASS);
register_methods(L);
+
+ mrp_resmgr_scripting_notifier_init(L);
}
const char *fldnam;
scripting_resmgr_t *rm;
int table;
+ mrp_funcbridge_t *screen_event_handler = NULL;
MRP_LUA_ENTER;
MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
switch (mrp_resmgr_scripting_field_name_to_type(fldnam, fldnamlen)) {
+ case SCREEN_EVENT_HANDLER:
+ screen_event_handler = mrp_funcbridge_create_luafunc(L, -1);
+ break;
+
default:
lua_pushvalue(L, -2);
lua_pushvalue(L, -2);
luaL_error(L, "can't create resmgr object");
rm->resmgr = resmgr;
+ rm->screen_event_handler = screen_event_handler;
+ resmgr->scripting_data = rm;
+
+ mrp_resmgr_notifier_register_event_callback(resmgr,
+ screen_event_handler_callback);
lua_settop(L, table);
MRP_LUA_LEAVE(1);
mrp_funcbridge_push(L, area_create);
break;
+ case WINDOW_RAISE:
+ mrp_funcbridge_push(L, window_raise);
+ break;
+
+ case SCREEN_EVENT_HANDLER:
+ mrp_funcbridge_push(L, rm->screen_event_handler);
+ break;
+
default:
lua_pushstring(L, fldnam);
lua_rawget(L, 1);
}
+static void screen_event_handler_callback(mrp_resmgr_t *resmgr,
+ mrp_resmgr_event_t *event)
+{
+ lua_State *L;
+ scripting_resmgr_t *rm;
+ void *sev;
+ mrp_funcbridge_value_t args[4], ret;
+ char t;
+ bool success;
+
+ MRP_ASSERT(resmgr && event, "invalid argument");
+
+ if (!(rm = resmgr->scripting_data)) {
+ mrp_debug("can't deliver resource events to LUA: "
+ "scripting resource manager was not created yet");
+ return;
+ }
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("can't deliver resource events: LUA is not initialesed");
+ return;
+ }
+
+ switch (event->type) {
+
+ case MRP_RESMGR_EVENT_SCREEN:
+ sev = mrp_resmgr_scripting_screen_event_create_from_c(L, event);
+ break;
+
+ case MRP_RESMGR_EVENT_AUDIO:
+ sev = NULL;
+ break;
+
+ case MRP_RESMGR_EVENT_INPUT:
+ sev = NULL;
+ break;
+
+ default:
+ sev = NULL;
+ break;
+ }
+
+ if (!sev) {
+ mrp_debug("can't deliver resource events to LUA: "
+ "failed to create scripting event");
+ return;
+ }
+
+ args[0].pointer = rm;
+ args[1].pointer = sev;
+
+ memset(&ret, 0, sizeof(ret));
+
+ success = mrp_funcbridge_call_from_c(L, rm->screen_event_handler, "oo",
+ args, &t, &ret);
+ if (!success) {
+ mrp_log_error("failed to call resource_manager.screen_event_handler method "
+ "(%s)", ret.string ? ret.string : "NULL");
+ mrp_free((void *)ret.string);
+ }
+}
+
+
static bool area_create_bridge(lua_State *L,
void *data,
const char *signature,
{
mrp_wayland_area_t *area;
mrp_resmgr_t *resmgr;
+ const char *zonename;
MRP_UNUSED(L);
MRP_UNUSED(data);
*ret_type = MRP_FUNCBRIDGE_NO_DATA;
- if (strcmp(signature, "oo")) {
- mrp_log_error("bad signature: expected 'oo' got '%s'",signature);
+ if (strcmp(signature, "oos")) {
+ mrp_log_error("bad signature: expected 'oos' got '%s'",signature);
return false;
}
return false;
}
+ zonename = args[2].string;
+
+ mrp_resmgr_screen_area_create(resmgr->screen, area, zonename);
return true;
}
+static bool window_raise_bridge(lua_State *L,
+ void *data,
+ const char *signature,
+ mrp_funcbridge_value_t *args,
+ char *ret_type,
+ mrp_funcbridge_value_t *ret_val)
+{
+ mrp_resmgr_t *resmgr;
+ const char *appid;
+ int32_t surfaceid;
+ int32_t direction;
+
+ 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, "osdd")) {
+ mrp_log_error("bad signature: expected 'osdd' 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 (!(appid = args[1].string)) {
+ mrp_log_error("argument 2 is an invalid appid string");
+ return false;
+ }
+
+ if ((surfaceid = args[2].integer) < 0) {
+ mrp_log_error("argument 3 is an invalid surfaceid");
+ return false;
+ }
+
+ direction = args[3].integer;
+
+ if (direction > 0)
+ mrp_screen_resource_raise(resmgr->screen, appid, surfaceid);
+ else if (direction < 0)
+ mrp_screen_resource_lower(resmgr->screen, appid, surfaceid);
+
+ return true;
+}
+
+
+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 , "oos" , NULL),
+ FUNCBRIDGE(window_raise , "osdd", 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
+}
+
mrp_resmgr_scripting_field_t
mrp_resmgr_scripting_field_check(lua_State *L,int idx,const char **ret_fldnam)
switch (len) {
case 4:
- if (!strcmp(name, "name"))
- return NAME;
+ switch (name[0]) {
+ case 'a':
+ if (!strcmp(name, "appid"))
+ return APPID;
+ if (!strcmp(name, "area"))
+ return AREA;
+ break;
+ case 'n':
+ if (!strcmp(name, "name"))
+ return NAME;
+ break;
+ default:
+ break;
+ }
break;
case 5:
if (!strcmp(name, "AUDIO"))
return AUDIO;
break;
+ case 'e':
+ if (!strcmp(name, "event"))
+ return EVENT;
+ break;
case 'i':
if (!strcmp(name, "input"))
return INPUT;
break;
+ case 'l':
+ if (!strcmp(name, "layer"))
+ return LAYER;
+ break;
+ case 't':
+ if (!strcmp(name, "type"))
+ return TYPE;
+ break;
default:
break;
}
break;
case 7:
- if (!strcmp(name, "classes"))
- return CLASSES;
+ switch (name[0]) {
+ case 'c':
+ if (!strcmp(name, "classes"))
+ return CLASSES;
+ break;
+ case 's':
+ if (!strcmp(name, "surface"))
+ return SURFACE;
+ break;
+ default:
+ break;
+ }
break;
case 9:
return AREA_CREATE;
break;
- default:
+ case 12:
+ if (!strcmp(name, "window_raise"))
+ return WINDOW_RAISE;
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;
+ case 20:
+ if (!strcmp(name, "screen_event_handler"))
+ return SCREEN_EVENT_HANDLER;
+ break;
- 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;
- }
+ default:
+ break;
}
- return success;
-
-#undef FUNCBRIDGE_END
-#undef FUNCBRIDGE
+ return 0;
}
mrp_resmgr_t *mrp_resmgr_scripting_check(lua_State *L, int idx);
mrp_resmgr_t *mrp_resmgr_scripting_unwrap(void *void_rm);
+/* scripting-notifier.c */
+void mrp_resmgr_scripting_notifier_init(lua_State *L);
+void *mrp_resmgr_scripting_screen_event_create_from_c(lua_State *L,
+ mrp_resmgr_event_t *event);
+
+/* internal for scripting-xxx.c */
mrp_resmgr_scripting_field_t
mrp_resmgr_scripting_field_check(lua_State *, int, const char **);
mrp_wayland_animation_type_t,
mrp_wayland_animation_t *);
static void set_window_area(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *,
mrp_wayland_animation_t *);
static void set_window_geometry(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *,
mrp_wayland_animation_t *);
static void set_window_alignment(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *);
static void set_window_visible(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *,
mrp_wayland_animation_t *);
static void set_window_active(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *);
static void set_window_mapped(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *,
uint32_t);
static void set_window_layer(mrp_wayland_window_t *,
+ mrp_wayland_layer_update_mask_t,
mrp_wayland_window_update_t *);
static void window_request(mrp_wayland_window_t *,
mrp_wayland_window_update_t *,
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);
+ u.surfaceid, u.name, u.pid, u.appid, layertype);
mrp_wayland_window_create(wl, &u);
}
"confused with data structures");
if (!winname) {
- mrp_log_error("Missing window name in %s()", __FUNCTION__);
+ mrp_log_error("system-controller: Missing window name in %s()",
+ __FUNCTION__);
return;
}
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_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");
u.mask = MRP_WAYLAND_WINDOW_NODEID_MASK |
MRP_WAYLAND_WINDOW_LAYERTYPE_MASK ;
u.nodeid = node;
- u.layertype = layertype;
+ u.layertype = get_layer_type(layertype);
if (hint == ICO_WINDOW_MGR_HINT_CHANGE) {
if (x <= MAX_COORDINATE) {
}
if (!(u.layer = mrp_wayland_layer_find(wl, layer)))
- mrp_log_error("can't find layer %u", layer);
+ mrp_log_error("system-controller: can't find layer %u", layer);
else
u.mask |= MRP_WAYLAND_WINDOW_LAYER_MASK;
mrp_debug("surfaceid=%u active=%d", surfaceid, active);
+ if (!active) {
+ mrp_debug("ignoring active=0 events");
+ return;
+ }
+
if (!(win = find_window(wm, surfaceid, "state update")))
return;
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;
+ if ((active & ICO_WINDOW_MGR_ACTIVE_POINTER))
+ u.active |= MRP_WAYLAND_WINDOW_ACTIVE_POINTER;
+ if ((active & ICO_WINDOW_MGR_ACTIVE_KEYBOARD))
+ u.active |= MRP_WAYLAND_WINDOW_ACTIVE_KEYBOARD;
+ if ((active & ICO_WINDOW_MGR_ACTIVE_SELECTED))
+ u.active |= MRP_WAYLAND_WINDOW_ACTIVE_SELECTED;
+ if ((win->active & u.active) == u.active) {
+ mrp_debug("window %u already active: nothing to do", surfaceid);
+ return;
+ }
+
mrp_wayland_window_update(win, MRP_WAYLAND_WINDOW_ACTIVE, &u);
}
u.visible = visible;
if (!(layer = mrp_wayland_layer_find(wl, layerid))) {
- mrp_log_error("can't find layer %u", layerid);
+ mrp_log_error("system-controller: can't find layer %u", layerid);
return;
}
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);
+ mrp_log_error("system-controller: window %d not found. No %s",
+ surfaceid, operation);
}
return win;
}
static void set_window_area(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u,
mrp_wayland_animation_t *anims)
{
u->width = area->width;
u->height = area->height;
- set_window_geometry(win, u, anims);
+ set_window_geometry(win, passthrough, u, anims);
+ set_window_alignment(win, passthrough, u);
}
static void set_window_geometry(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u,
mrp_wayland_animation_t *anims)
{
node != win->nodeid;
need_positioning = false;
- if (!(mask & MRP_WAYLAND_WINDOW_X_MASK) || (u->x == win->x)) {
+ if (!(mask & MRP_WAYLAND_WINDOW_X_MASK) ||
+ ((u->x == win->x) && !(passthrough & MRP_WAYLAND_WINDOW_X_MASK)))
+ {
if (!first_time)
x = ICO_WINDOW_MGR_V_NOCHANGE;
else {
x = u->x;
need_positioning = true;
}
- if (!(mask & MRP_WAYLAND_WINDOW_Y_MASK) || (u->y == win->y)) {
+ if (!(mask & MRP_WAYLAND_WINDOW_Y_MASK) ||
+ ((u->y == win->y) && !(passthrough & MRP_WAYLAND_WINDOW_Y_MASK)))
+ {
if (!first_time)
y = ICO_WINDOW_MGR_V_NOCHANGE;
else {
}
need_resizing = false;
- if (!(mask & MRP_WAYLAND_WINDOW_WIDTH_MASK) || (u->width == win->width)) {
+ if (!(mask & MRP_WAYLAND_WINDOW_WIDTH_MASK) ||
+ ((u->width == win->width) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_WIDTH_MASK)))
+ {
if (!first_time)
width = ICO_WINDOW_MGR_V_NOCHANGE;
else {
width = win->width;
- need_positioning = true;
+ need_resizing = true;
}
}
else {
width = u->width;
need_resizing = true;
}
- if (!(mask&MRP_WAYLAND_WINDOW_HEIGHT_MASK) || (u->height == win->height)) {
+ if (!(mask & MRP_WAYLAND_WINDOW_HEIGHT_MASK) ||
+ ((u->height == win->height) &&
+ !(passthrough && MRP_WAYLAND_WINDOW_HEIGHT_MASK)))
+ {
if (!first_time)
height = ICO_WINDOW_MGR_V_NOCHANGE;
else {
height = win->height;
- need_positioning = true;
+ need_resizing = true;
}
}
else {
}
static void set_window_alignment(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u)
{
struct ico_window_mgr *ico_window_mgr;
mrp_wayland_area_t *area;
uint32_t attrs;
+ MRP_UNUSED(passthrough);
+
ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
if (!(area = u->area)) {
- mrp_log_error("attempt to set NULL area");
+ mrp_log_error("system-controller: attempt to set NULL area");
return;
}
}
static void set_window_visible(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u,
mrp_wayland_animation_t *anims)
{
need_visibility_change = false;
if (!(mask & MRP_WAYLAND_WINDOW_VISIBLE_MASK) ||
- (u->visible && win->visible) || (!u->visible && !win->visible))
+ (((u->visible && win->visible) || (!u->visible && !win->visible)) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_VISIBLE_MASK)))
{
visible = ICO_WINDOW_MGR_V_NOCHANGE;
anim_type = 0;
need_raising = false;
if (!(mask & MRP_WAYLAND_WINDOW_RAISE_MASK) ||
- (u->raise && win->raise) || (!u->raise && !win->raise))
+ (((u->raise && win->raise) || (!u->raise && !win->raise)) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_RAISE_MASK)))
{
raise = ICO_WINDOW_MGR_V_NOCHANGE;
}
}
static void set_window_active(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
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)
+ if ((u->active == win->active) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_ACTIVE_MASK))
+ {
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;
+ return;
+ }
+
+ active = 0;
- mrp_debug("calling ico_window_mgr_set_active"
- "(surfaceid=%d, active=0x%x)",
- win->surfaceid, active);
+ 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;
- ico_window_mgr_set_active(ico_window_mgr, win->surfaceid, active);
- }
+ 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_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u,
uint32_t framerate)
{
ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
- if ((u->mapped && win->mapped) || (!u->mapped && !win->mapped))
+ if (((u->mapped && win->mapped) || (!u->mapped && !win->mapped)) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_MAPPED_MASK))
+ {
mrp_debug("nothing to do");
+ }
else {
if (u->mapped) {
mrp_debug("calling ico_window_mgr_map_surface"
}
static void set_window_layer(mrp_wayland_window_t *win,
+ mrp_wayland_layer_update_mask_t passthrough,
mrp_wayland_window_update_t *u)
{
struct ico_window_mgr *ico_window_mgr;
ico_window_mgr = (struct ico_window_mgr *)win->wm->proxy;
- if (win->layer && (u->layer == win->layer)) {
+ if (win->layer && (u->layer == win->layer) &&
+ !(passthrough & MRP_WAYLAND_WINDOW_LAYER_MASK))
+ {
mrp_debug("nothing to do");
}
else {
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_manager_t *wm;
+ mrp_wayland_layer_update_mask_t passthrough;
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;
+ wm = win->wm;
+ wl = wm->interface->wl;
+ passthrough = wm->passthrough.request;
mask = u->mask;
mrp_wayland_window_request_print(u, wbuf, sizeof(wbuf));
while (mask) {
if ((mask & layer_mask)) {
- set_window_layer(win, u);
+ set_window_layer(win, passthrough, u);
mask &= ~layer_mask;
}
else if ((mask & mapped_mask)) {
- set_window_mapped(win, u, framerate);
+ set_window_mapped(win, passthrough, u, framerate);
mask &= ~mapped_mask;
}
else if ((mask & area_mask)) {
- set_window_area(win, u, anims);
+ set_window_area(win, passthrough, u, anims);
mask &= ~(area_mask | geometry_mask);
}
else if ((mask & geometry_mask)) {
- set_window_geometry(win, u, anims);
+ set_window_geometry(win, passthrough, 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);
+ set_window_visible(win, passthrough, u, anims);
mask &= ~visible_mask;
}
else if ((mask & active_mask)) {
- set_window_active(win, u);
+ set_window_active(win, passthrough, u);
mask &= ~active_mask;
}
else {
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;
enum mrp_wayland_layer_operation_e {
MRP_WAYLAND_LAYER_OPERATION_NONE = 0,
- MRP_WAYLAND_LAYER_CREATE,
- MRP_WAYLAND_LAYER_DESTROY,
- MRP_WAYLAND_LAYER_VISIBLE
+ MRP_WAYLAND_LAYER_CREATE, /* 1 */
+ MRP_WAYLAND_LAYER_DESTROY, /* 2 */
+ MRP_WAYLAND_LAYER_VISIBLE /* 3 */
};
struct mrp_wayland_layer_s {
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);
return mask;
}
-
-
mrp_wayland_scripting_field_t
mrp_wayland_scripting_field_check(lua_State *L,int idx,const char **ret_fldnam)
{
case 14:
switch (name[0]) {
+ case 'm':
+ if (!strcmp(name, "manager_update"))
+ return MANAGER_UPDATE;
+ break;
case 'o':
if (!strcmp(name, "output_request"))
return OUTPUT_REQUEST;
}
break;
+ case 15:
+ if (!strcmp(name, "manager_request"))
+ return MANAGER_REQUEST;
+ break;
+
+ case 18:
+ if (!strcmp(name, "passthrough_update"))
+ return PASSTHROUGH_UPDATE;
+ break;
+
+ case 19:
+ if (!strcmp(name, "passthrough_request"))
+ return PASSTHROUGH_REQUEST;
+ break;
+
default:
break;
}
#include "layer.h"
#include "output.h"
#include "area.h"
+#include "window-manager.h"
#include "ico-window-manager.h"
#define WINDOW_MANAGER_CLASS MRP_LUA_CLASS_SIMPLE(window_manager)
mrp_wayland_t *wl;
const char *name;
const char *display;
+ mrp_funcbridge_t *manager_update;
mrp_funcbridge_t *output_update;
mrp_funcbridge_t *layer_update;
mrp_funcbridge_t *window_update;
static void layer_def_free(layer_def_t *);
+static bool manager_request_bridge(lua_State *, void *,
+ const char *, mrp_funcbridge_value_t *,
+ char *, mrp_funcbridge_value_t *);
+static void manager_update_callback(mrp_wayland_t *,
+ mrp_wayland_window_manager_operation_t,
+ mrp_wayland_window_manager_t *);
+
static bool window_request_bridge(lua_State *, void *,
const char *, mrp_funcbridge_value_t *,
char *, mrp_funcbridge_value_t *);
)
);
+static mrp_funcbridge_t *manager_request;
static mrp_funcbridge_t *output_request;
static mrp_funcbridge_t *area_create;
static mrp_funcbridge_t *layer_request;
char *name;
const char *display = NULL;
layer_def_t *layers = NULL;
+ mrp_funcbridge_t *manager_update = NULL;
mrp_funcbridge_t *output_update = NULL;
mrp_funcbridge_t *layer_update = NULL;
mrp_funcbridge_t *window_update = NULL;
layers = layer_def_check(L, -1);
break;
+ case MANAGER_UPDATE:
+ manager_update = mrp_funcbridge_create_luafunc(L, -1);
+ break;
+
case OUTPUT_UPDATE:
output_update = mrp_funcbridge_create_luafunc(L, -1);
break;
case WINDOW_UPDATE:
window_update = mrp_funcbridge_create_luafunc(L, -1);
- break;
+ break;
default:
lua_pushvalue(L, -2);
winmgr->wl = wl;
winmgr->name = mrp_strdup(name);
winmgr->display = mrp_strdup(display);
+ winmgr->manager_update = manager_update;
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_window_manager_update_callback(wl,
+ manager_update_callback);
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);
static int window_manager_getfield(lua_State *L)
{
scripting_winmgr_t *wmgr;
+ mrp_wayland_t *wl;
const char *fldnam;
mrp_wayland_scripting_field_t fld;
+ uint32_t mask;
MRP_LUA_ENTER;
wmgr = window_manager_check(L, 1);
- if (!wmgr)
+ if (!wmgr || !(wl = wmgr->wl))
lua_pushnil(L);
else {
switch (fld) {
lua_pushstring(L, wmgr->display);
break;
+ case MANAGER_REQUEST:
+ mrp_funcbridge_push(L, manager_request);
+ break;
+
+ case MANAGER_UPDATE:
+ mrp_funcbridge_push(L, wmgr->manager_update);
+ break;
+
case OUTPUT_REQUEST:
mrp_funcbridge_push(L, output_request);
break;
mrp_funcbridge_push(L, wmgr->window_update);
break;
+ case PASSTHROUGH_REQUEST:
+ mask = (wl->wm ? wl->wm->passthrough.request : 0);
+ goto push_mask;
+
+ case PASSTHROUGH_UPDATE:
+ mask = (wl->wm ? wl->wm->passthrough.update : 0);
+ goto push_mask;
+
+ push_mask:
+ if (!mrp_wayland_scripting_window_mask_create_from_c(L, mask))
+ lua_pushnil(L);
+ break;
+
default:
lua_pushstring(L, fldnam);
lua_rawget(L, 1);
}
}
+static bool manager_request_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_t *wl;
+ mrp_wayland_window_manager_t *wm;
+ mrp_json_t *json;
+ const char *key;
+ mrp_json_t *val;
+ mrp_json_iter_t it;
+ int32_t mask;
+
+ 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("system-controller: bad signature: "
+ "expected 'oo' got '%s'", signature);
+ return false;
+ }
+
+ if (!(wl = mrp_wayland_scripting_window_manager_unwrap(args[0].pointer))) {
+ mrp_log_error("system-controller: argument 1 is not a "
+ "'window_manager' class object");
+ return false;
+ }
+
+ if (!(wm = wl->wm)) {
+ mrp_log_error("system-controller: 'window_manager' is not initilized");
+ return false;
+ }
+
+ if (!(json = mrp_json_lua_unwrap(args[1].pointer))) {
+ mrp_log_error("system-controller: argument 2 is not a "
+ "'JSON' class object");
+ return false;
+ }
+
+ mrp_json_foreach_member(json, key,val, it) {
+ switch (mrp_wayland_scripting_field_name_to_type(key, -1)) {
+
+ case PASSTHROUGH_REQUEST:
+ if (!mrp_wayland_json_integer_copy(wl, &mask, val, 1))
+ mrp_debug("'%s' field has invalid value", key);
+ else {
+ mrp_debug("set passthrough.request to 0x%x", mask);
+ wm->passthrough.request = mask;
+ }
+ break;
+
+ case PASSTHROUGH_UPDATE:
+ if (!mrp_wayland_json_integer_copy(wl, &mask, val, 1))
+ mrp_debug("'%s' field has invalid value", key);
+ else {
+ mrp_debug("set passthrough.update to 0x%x", mask);
+ wm->passthrough.update = mask;
+ }
+ break;
+
+ default:
+ mrp_debug("ignoring JSON field '%s'", key);
+ break;
+ }
+ }
+
+ return true;
+}
+
+static void manager_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_manager_operation_t oper,
+ mrp_wayland_window_manager_t *wm)
+{
+ lua_State *L;
+ scripting_winmgr_t *winmgr;
+ mrp_funcbridge_value_t args[4], ret;
+ char t;
+ bool success;
+
+ MRP_ASSERT(wl && wm, "invalid argument");
+
+ if (!(L = mrp_lua_get_lua_state())) {
+ mrp_log_error("sysem-controller: can't update manager: "
+ "LUA is not initialesed");
+ return;
+ }
+
+ if (!(winmgr = (scripting_winmgr_t *)wl->scripting_data)) {
+ mrp_log_error("system-controller: window manager "
+ "scripting is not initialized");
+ return;
+ }
+
+ MRP_ASSERT(wl == winmgr->wl, "confused with data structures");
+
+ args[0].pointer = winmgr;
+ args[1].integer = oper;
+
+ memset(&ret, 0, sizeof(ret));
+
+ success = mrp_funcbridge_call_from_c(L, winmgr->manager_update, "od",
+ args, &t, &ret);
+ if (!success) {
+ mrp_log_error("failed to call window_manager.%s.manager_update method "
+ "(%s)", winmgr->name, ret.string ? ret.string : "NULL");
+ mrp_free((void *)ret.string);
+ }
+}
+
static bool window_request_bridge(lua_State *L,
void *data,
const char *signature,
*ret_type = MRP_FUNCBRIDGE_NO_DATA;
if (strcmp(signature, "oood")) {
- mrp_log_error("bad signature: expected 'oood' got '%s'",signature);
+ mrp_log_error("system-controller: 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");
+ mrp_log_error("system-controller: 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");
+ mrp_log_error("system-controller: 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");
+ mrp_log_error("system-controller: 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);
+ mrp_log_error("system-controller: argument 3 is not valid framerate "
+ "(out of range 0-%d)", MRP_WAYLAND_FRAMERATE_MAX);
return false;
}
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);
+ mrp_log_error("system-controller: 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");
+ mrp_log_error("system-controller: 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);
+ mrp_log_error("system-controller: no scripting data for "
+ "window %d", win->surfaceid);
return;
}
memset(&u, 0, sizeof(u));
u.mask = copy_json_fields(wl, json, fields, &u);
+ mrp_wayland_layer_request(wl, &u);
+
return true;
}
mrp_json_iter_t it;
request_def_t *f;
uint32_t m, mask;
+ bool found;
mask = 0;
mrp_json_foreach_member(json, key,val, it) {
- for (f = fields; f->name; f++) {
+ for (f = fields, found = false; f->name; f++) {
if (!strcmp(key, f->name)) {
+ found = true;
if ((m = f->copy(wl, copy + f->offset, val, f->mask)))
mask |= m;
else
break;
}
}
+ if (!found)
+ mrp_debug("ignoring JSON field '%s'", key);
}
return mask;
#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(manager_request, "oo" , NULL),
+ FUNCBRIDGE(output_request , "oo" , NULL),
+ FUNCBRIDGE(area_create , "oo" , NULL),
+ FUNCBRIDGE(layer_request , "oo" , NULL),
+ FUNCBRIDGE(window_request , "oood", NULL),
FUNCBRIDGE_END
};
static int window_mask_getfield(lua_State *);
static int window_mask_setfield(lua_State *);
static int window_mask_stringify(lua_State *);
+static int window_mask_tointeger(lua_State *);
static void window_mask_destroy(void *);
static scripting_window_mask_t *window_mask_check(lua_State *, int);
window_mask_destroy, /* userdata destructor */
MRP_LUA_METHOD_LIST ( /* methods */
MRP_LUA_METHOD_CONSTRUCTOR (window_mask_create_from_lua)
+ MRP_LUA_METHOD(tointeger, window_mask_tointeger)
),
MRP_LUA_METHOD_LIST ( /* overrides */
MRP_LUA_OVERRIDE_CALL (window_mask_create_from_lua)
if (fld == MASK)
mask = lua_tointeger(L, -1);
else if ((m = get_window_mask(fld)))
- mask |= m;
+ mask |= lua_toboolean(L, -1) ? m : 0;
else
luaL_error(L, "bad field '%s'", fldnam);
}
MRP_LUA_LEAVE(1);
}
+static int window_mask_tointeger(lua_State *L)
+{
+ scripting_window_mask_t *um;
+
+ MRP_LUA_ENTER;
+
+ um = window_mask_check(L, 1);
+ lua_pushinteger(L, um->mask);
+
+ MRP_LUA_LEAVE(1);
+}
+
static void window_mask_destroy(void *data)
{
scripting_window_mask_t *um = (scripting_window_mask_t *)data;
#include "wayland.h"
#include "output.h"
#include "layer.h"
+#include "window-manager.h"
static uint32_t oid_hash(const void *);
wl->wm = wm;
mrp_htbl_foreach(wl->layers, update_layers, wm);
+
+ if (wl->window_manager_update_callback) {
+ wl->window_manager_update_callback(wl,
+ MRP_WAYLAND_WINDOW_MANAGER_CREATE,
+ wm);
+ }
}
return true;
}
+void mrp_wayland_register_window_manager_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_manager_update_callback_t callback)
+{
+ MRP_ASSERT(wl, "invalid aruments");
+
+ mrp_debug("registering window_manager_update_callback");
+
+ wl->window_manager_update_callback = callback;
+}
+
void mrp_wayland_register_output_update_callback(mrp_wayland_t *wl,
mrp_wayland_output_update_callback_t callback)
{
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 enum mrp_wayland_window_manager_operation_e
+ mrp_wayland_window_manager_operation_t;
typedef struct mrp_wayland_s mrp_wayland_t;
typedef struct mrp_wayland_factory_s mrp_wayland_factory_t;
mrp_wayland_object_t *);
typedef void (*mrp_wayland_destructor_t)(mrp_wayland_object_t *);
+typedef void (*mrp_wayland_window_manager_update_callback_t)(mrp_wayland_t *,
+ mrp_wayland_window_manager_operation_t,
+ mrp_wayland_window_manager_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 *);
+ 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 *);
+ 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 *);
+ 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 *);
+ 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 *);
+ mrp_application_operation_t,
+ mrp_application_update_mask_t,
+ mrp_application_t *);
struct mrp_wayland_s {
mrp_wayland_window_manager_t *wm;
mrp_wayland_input_manager_t *im;
+ mrp_wayland_window_manager_update_callback_t window_manager_update_callback;
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_window_manager_t *wm);
bool mrp_wayland_register_interface(mrp_wayland_t *wl,
mrp_wayland_factory_t *factory);
+
+void mrp_wayland_register_window_manager_update_callback(mrp_wayland_t *wl,
+ mrp_wayland_window_manager_update_callback_t callback);
void mrp_wayland_register_output_update_callback(mrp_wayland_t *wl,
- mrp_wayland_output_update_callback_t callback);
+ 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);
+ 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);
+ 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);
+ 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);
#include <sys/types.h>
-#include "wayland/wayland.h"
+#include "wayland/window.h"
+
+enum mrp_wayland_window_manager_operation_e {
+ MRP_WAYLAND_WINDOW_MANAGER_OPERATION_NONE = 0,
+ MRP_WAYLAND_WINDOW_MANAGER_CREATE, /* 1 */
+ MRP_WAYLAND_WINDOW_MANAGER_DESTROY, /* 2 */
+};
#define MRP_WAYLAND_WINDOW_MANAGER_COMMON \
MRP_WAYLAND_OBJECT_COMMON; \
void (*window_request)(mrp_wayland_window_t *, \
mrp_wayland_window_update_t *, \
mrp_wayland_animation_t *, \
- uint32_t)
+ uint32_t); \
+ struct { \
+ mrp_wayland_window_update_mask_t request; \
+ mrp_wayland_window_update_mask_t update; \
+ } passthrough
+
struct mrp_wayland_window_manager_s {
MRP_WAYLAND_WINDOW_MANAGER_COMMON;
typedef struct {
mrp_wayland_window_t *win;
+ mrp_wayland_window_operation_t oper;
int32_t state;
-} update_active_t;
+ bool raise;
+} update_others_t;
static mrp_wayland_window_update_mask_t update(mrp_wayland_window_t *,
mrp_wayland_window_update_t *);
}
-#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_window_t *win;
mrp_wayland_window_manager_t *wm;
+ char buf[4096];
MRP_ASSERT(wl && u, "invalid arguments");
MRP_ASSERT(win->wm, "confused with data structures");
+ mrp_wayland_window_request_print(u, buf,sizeof(buf));
+ mrp_debug("window %d%s", u->surfaceid, buf);
+
wm = win->wm;
wm->window_request(win, u, anims, framerate);
}
-static int update_active(void *key, void *object, void *ud)
+static int update_others(void *key, void *object, void *ud)
{
mrp_wayland_window_t *win = (mrp_wayland_window_t *)object;
- update_active_t *active = (update_active_t *)ud;
+ update_others_t *uo = (update_others_t *)ud;
MRP_UNUSED(key);
- if (win != active->win) {
- if (active->state == 0)
- win->active = 0;
- else
- win->active &= ~active->state;
+ if (win != uo->win) {
+ switch (uo->oper) {
+
+ case MRP_WAYLAND_WINDOW_ACTIVE:
+ if (uo->state == 0)
+ win->active = 0;
+ else
+ win->active &= ~uo->state;
+
+ mrp_debug("setting window %d 'active' to 0x%x",
+ win->surfaceid, win->active);
+ break;
+
+ case MRP_WAYLAND_WINDOW_VISIBLE:
+ if (uo->raise)
+ win->raise = false;
- mrp_debug("setting window %d 'active' to 0x%x",
- win->surfaceid, win->active);
+ mrp_debug("setting window %d 'raise' to %s",
+ win->surfaceid, win->raise ? "true" : "false");
+ break;
+
+ default:
+ break;
+ }
}
return MRP_HTBL_ITER_MORE;
int32_t surfaceid;
mrp_wayland_window_update_mask_t mask;
char buf[2048];
- update_active_t active;
+ update_others_t uo;
MRP_ASSERT(win && win->wm && win->wm->interface &&
win->wm->interface->wl && u, "invalid argument");
mask = update(win, u);
- if (!mask)
+ 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);
- }
+ return;
+ }
+
+ 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);
+
+ memset(&uo, 0, sizeof(uo));
+ uo.win = win;
+ uo.oper = oper;
+
+ switch (oper) {
+
+ case MRP_WAYLAND_WINDOW_ACTIVE:
+ uo.state = win->active;
+ goto update_loop;
+
+ case MRP_WAYLAND_WINDOW_VISIBLE:
+ if ((mask & MRP_WAYLAND_WINDOW_RAISE_MASK) && win->raise) {
+ uo.raise = true;
+ goto update_loop;
+ }
+ break;
+
+
+ default:
+ break;
+
+ update_loop:
+ mrp_htbl_foreach(wl->windows, update_others, &uo);
+ break;
}
}
mrp_wayland_window_update_t *u)
{
mrp_wayland_window_update_mask_t mask = 0;
+ mrp_wayland_window_update_mask_t passthrough = win->wm->passthrough.update;
if ((u->mask & MRP_WAYLAND_WINDOW_NAME_MASK)) {
- if (!win->name || strcmp(u->name, win->name)) {
+ if (!win->name || strcmp(u->name, win->name) ||
+ (passthrough & MRP_WAYLAND_WINDOW_NAME_MASK))
+ {
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)) {
+ if (!win->appid || strcmp(u->appid, win->appid) ||
+ (passthrough & MRP_WAYLAND_WINDOW_APPID_MASK)) {
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) {
+ if (u->pid != win->pid ||
+ (passthrough & MRP_WAYLAND_WINDOW_PID_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_PID_MASK;
win->pid = u->pid;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_NODEID_MASK)) {
- if (u->nodeid != win->nodeid) {
+ if (u->nodeid != win->nodeid ||
+ (passthrough & MRP_WAYLAND_WINDOW_NODEID_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_NODEID_MASK;
win->nodeid = u->nodeid;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_LAYER_MASK)) {
- if (u->layer != win->layer) {
+ if (u->layer != win->layer ||
+ (passthrough & MRP_WAYLAND_WINDOW_LAYER_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_LAYER_MASK;
win->layer = u->layer;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_X_MASK)) {
- if (u->x != win->x) {
+ if (u->x != win->x ||
+ (passthrough & MRP_WAYLAND_WINDOW_X_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
win->x = u->x;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_Y_MASK)) {
- if (u->y != win->y) {
+ if (u->y != win->y ||
+ (passthrough & MRP_WAYLAND_WINDOW_Y_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_POSITION_MASK;
win->y = u->y;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_WIDTH_MASK)) {
- if (u->width != win->width) {
+ if (u->width != win->width ||
+ (passthrough & MRP_WAYLAND_WINDOW_WIDTH_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_SIZE_MASK;
win->width = u->width;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_HEIGHT_MASK)) {
- if (u->height != win->height) {
+ if (u->height != win->height ||
+ (passthrough & MRP_WAYLAND_WINDOW_HEIGHT_MASK))
+ {
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)) {
+ if ((u->visible && !win->visible) || (!u->visible && win->visible) ||
+ (passthrough & MRP_WAYLAND_WINDOW_VISIBLE_MASK))
+ {
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)) {
+ if ((u->raise && !win->raise) || (!u->raise && win->raise) ||
+ (passthrough & MRP_WAYLAND_WINDOW_RAISE_MASK))
+ {
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)) {
+ if ((u->mapped && !win->mapped) || (!u->mapped && win->mapped) ||
+ (passthrough & MRP_WAYLAND_WINDOW_MAPPED_MASK))
+ {
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)) {
+ if (u->active != win->active ||
+ (passthrough & MRP_WAYLAND_WINDOW_ACTIVE_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_ACTIVE_MASK;
win->active = u->active;
}
}
if ((u->mask & MRP_WAYLAND_WINDOW_LAYERTYPE_MASK)) {
- if ((u->layertype != win->layertype)) {
+ if (u->layertype != win->layertype ||
+ (passthrough & MRP_WAYLAND_WINDOW_LAYERTYPE_MASK))
+ {
mask |= MRP_WAYLAND_WINDOW_LAYERTYPE_MASK;
win->layertype = u->layertype;
}
mrp_debug("found area '%s'", u2.area->name);
+#if 0
+ if (u->layertype == MRP_WAYLAND_LAYER_TYPE_UNKNOWN ||
+ u->layertype == MRP_WAYLAND_LAYER_INPUT ||
+ u->layertype == MRP_WAYLAND_LAYER_TOUCH ||
+ u->layertype == MRP_WAYLAND_LAYER_CURSOR )
+ {
+ win->area = u2.area;
+ win->x = u2.area->x;
+ win->y = u2.area->y;
+ win->width = u2.area->width;
+ win->height = u2.area->height;
+ return mask;
+ }
+#endif
+
u2.mask |= MRP_WAYLAND_WINDOW_AREA_MASK;
if (!(mask & MRP_WAYLAND_WINDOW_POSITION_MASK)) {
return mask;
}
-
+
static char *active_str(mrp_wayland_active_t active, char *buf, size_t len)
{
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,