system-controller: add support for window specific areas
authorJanos Kovacs <jankovac503@gmail.com>
Wed, 5 Mar 2014 02:04:08 +0000 (04:04 +0200)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 8 Jan 2015 16:37:14 +0000 (18:37 +0200)
Change-Id: Ibbf6cdfe34159c35320b46b5a2e87ef0696206cd

packaging.in/murphy.lua
src/plugins/system-controller/application/application.c
src/plugins/system-controller/application/application.h
src/plugins/system-controller/application/scripting-application.c
src/plugins/system-controller/data-types.h
src/plugins/system-controller/wayland/area.c
src/plugins/system-controller/wayland/window.c

index 689f938..8500e02 100644 (file)
@@ -1017,6 +1017,13 @@ wmgr = window_manager {
                               width  = function(w,h) return w/2-181 end,
                               height = function(w,h) return h-64-128 end
                            },
+                           Control = {
+                              id     = 11,
+                              pos_x  = 0,
+                              pos_y  = function(w,h) return h-128 end,
+                              width  = function(w,h) return w end,
+                              height = 128
+                           },
                         }
               }
   },
@@ -1330,6 +1337,7 @@ application {
 application {
     appid           = "org.tizen.ico.homescreen",
     area            = "Center.Full",
+    windows         = { {'ico_hs_controlbarwindow', 'Center.Control'} },
     privileges      = { screen = "system", audio = "system" },
     resource_class  = "player",
     screen_priority = 20
@@ -1422,43 +1430,14 @@ if sc then
         if not connected then
             print('Setting homescreen='..msg.appid)
             homescreen = msg.appid
+            if command and command == 1 then
+                send_driving_mode_to_home_screen()
+                send_night_mode_to_home_screen()
+            end
             print('Trying to connect to wayland...')
             connected = wmgr:connect()
         end
         if connected and command then
-            if command == 1 then -- send_appid
-                local driving_mode = mdb.select.select_driving_mode.single_value
-                local night_mode = mdb.select.select_night_mode.single_value
-
-                if not driving_mode then driving_mode = 0 end
-                if not night_mode then night_mode = 0 end
-
-                local reply = m:JSON({ command = 0x60001,
-                                       arg     = m:JSON({ stateid = 1,
-                                                          state   = driving_mode})
-                                     })
-                 if verbose > 0 then
-                     print("### <== sending " ..
-                           command_name(command) .. " message")
-                     if verbose > 1 then
-                         print(reply)
-                     end
-                 end
-                 sc:send_message(homescreen, reply)
-
-                 reply = m:JSON({ command = 0x60001,
-                                  arg     = m:JSON({ stateid = 2,
-                                                     state   = night_mode})
-                                })
-                 if verbose > 0 then
-                     print("### <== sending " ..
-                           command_name(command) .. " message")
-                     if verbose > 1 then
-                         print(reply)
-                     end
-                 end
-                 sc:send_message(homescreen, reply)
-            end
         end
     end
 
@@ -1964,5 +1943,47 @@ if sc then
     end
 end
 
+function send_driving_mode_to_home_screen()
+    local driving_mode = mdb.select.select_driving_mode.single_value
+
+    if not driving_mode then driving_mode = 0 end
+
+    local reply = m:JSON({ command = 0x60001,
+                           arg     = m:JSON({ stateid = 1,
+                                              state   = driving_mode
+                                     })
+                  })
+
+    if verbose > 0 then
+        print("### <== sending " .. command_name(reply.command) .. " message")
+        if verbose > 1 then
+            print(reply)
+        end
+    end
+
+    sc:send_message(homescreen, reply)
+end
+
+function send_night_mode_to_home_screen()
+    local night_mode = mdb.select.select_night_mode.single_value
+
+    if not night_mode then night_mode = 0 end
+
+    local reply = m:JSON({ command = 0x60001,
+                           arg     = m:JSON({ stateid = 2,
+                                              state   = night_mode
+                                     })
+                  })
+
+    if verbose > 0 then
+        print("### <== sending " .. command_name(reply.command) .. " message")
+        if verbose > 1 then
+            print(reply)
+        end
+     end
+
+     sc:send_message(homescreen, reply)
+end
+
 -- we should have 'audio_playback' defined by now
 m:try_load_plugin('telephony')
index ac570d9..c18304f 100644 (file)
@@ -41,6 +41,7 @@
 
 static void init_applications(void);
 static mrp_wayland_area_t *area_find(const char *);
+static mrp_application_window_t *windows_dup(mrp_application_window_def_t *);
 
 mrp_htbl_t *applications;
 
@@ -112,6 +113,8 @@ mrp_application_t *mrp_application_create(mrp_application_update_t *u,
         app->requisites.screen = u->requisites.screen;
     IF_PRESENT(u, AUDIO_REQUISITES)
         app->requisites.audio = u->requisites.audio;
+    IF_PRESENT(u, WINDOWS)
+        app->windows = windows_dup(u->windows);
 
     if (!scripting_data)
         scripting_data = mrp_application_scripting_app_create_from_c(app);
@@ -138,6 +141,7 @@ mrp_application_t *mrp_application_create(mrp_application_update_t *u,
 void mrp_application_destroy(mrp_application_t *app)
 {
     mrp_wayland_t *wl;
+    mrp_application_window_t *w;
     void *it;
 
     if (app && app->appid) {
@@ -160,6 +164,14 @@ void mrp_application_destroy(mrp_application_t *app)
 
         mrp_free(app->appid);
 
+        if (app->windows) {
+            for (w = app->windows;  w->window_name;   w++) {
+                mrp_free((void *)w->window_name);
+                mrp_free((void *)w->area_name);
+            }
+            mrp_free((void *)app->windows);
+        }
+
         free(app);
     }
 }
@@ -173,6 +185,23 @@ mrp_application_t *mrp_application_find(const char *appid)
     return (mrp_application_t *)mrp_htbl_lookup(applications, (void *)appid);
 }
 
+mrp_wayland_area_t *mrp_application_area_find(mrp_application_t *app,
+                                              const char *window_name)
+{
+    mrp_application_window_t *w;
+
+    if (app) {
+        if (window_name && app->windows) {
+            for (w = app->windows;   w->window_name;   w++) {
+                if (!strcmp(window_name, w->window_name))
+                    return w->area;
+            }
+        }
+        return app->area;
+    }
+
+    return NULL;
+}
 
 size_t mrp_application_print(mrp_application_t *app,
                              mrp_application_update_mask_t mask,
@@ -185,6 +214,7 @@ size_t mrp_application_print(mrp_application_t *app,
     char *p, *e;
     char sbuf[1024];
     char abuf[1024];
+    char wbuf[4096];
 
     e = (p = buf) + len;
 
@@ -217,6 +247,10 @@ size_t mrp_application_print(mrp_application_t *app,
                                         abuf,sizeof(abuf));
         PRINT("requisites: screen=%s, audio=%s", sbuf, abuf);
     }
+    if ((mask & MRP_APPLICATION_WINDOWS_MASK)) {
+        mrp_application_windows_print(app->windows, wbuf,sizeof(wbuf));
+        PRINT("windows: %s", wbuf);
+    }
 
     return p - buf;
 
@@ -285,6 +319,38 @@ size_t mrp_application_requisite_print(mrp_application_requisite_t rqs,
 }
 
 
+size_t mrp_application_windows_print(mrp_application_window_t *wins,
+                                     char *buf, size_t len)
+{
+#define PRINT(w)                                                        \
+    do {                                                                \
+        if (p < e && w->window_name && w->area_name) {                  \
+            p += snprintf(p, e-p, "%s%s:%s",                            \
+                          p == buf ? "":", ",                           \
+                          w->window_name,                               \
+                          w->area ? w->area->name : w->area_name);      \
+        }                                                               \
+    } while(0)
+
+    mrp_application_window_t *w;
+    char *p, *e;
+
+    e = (p = buf) + len;
+
+    *p = 0;
+
+    for (w = wins;   w && w->window_name;    w++)
+        PRINT(w);
+
+    if (p == buf)
+        p += snprintf(p, e-p, "none");
+
+    return p - buf;
+
+#undef PRINT
+}
+
+
 static void init_applications(void)
 {
     mrp_htbl_config_t cfg;
@@ -313,3 +379,29 @@ static mrp_wayland_area_t *area_find(const char *fullname)
 
     return NULL;
 }
+
+static
+mrp_application_window_t *windows_dup(mrp_application_window_def_t *defs)
+{
+    mrp_application_window_t *dup = NULL;
+    const char *area_name;
+    int i, n;
+
+    if (defs) {
+
+        for (n = 0;   defs[n].window_name;   n++)
+            ;
+
+        if ((dup = mrp_allocz(sizeof(mrp_application_window_t) * (n + 1)))) {
+            for (i = 0;  i < n;  i++) {
+                if ((area_name = defs[i].area_name)) {
+                    dup[i].window_name = mrp_strdup(defs[i].window_name);
+                    dup[i].area_name = mrp_strdup(area_name);
+                    dup[i].area = area_find(area_name);
+                }
+            }
+        }
+    }
+
+    return dup;
+}
index 127dcb4..cb395e2 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 
 #include "data-types.h"
+#include "wayland/area.h"
 
 #ifndef __MURPHY_WAYLAND_H__
 #error "do not include directly application.h; include wayland/wayland.h"
@@ -50,6 +51,8 @@ typedef struct mrp_application_s              mrp_application_t;
 typedef struct mrp_application_update_s       mrp_application_update_t;
 typedef struct mrp_application_privileges_s   mrp_application_privileges_t;
 typedef struct mrp_application_requisites_s   mrp_application_requisites_t;
+typedef struct mrp_application_window_s       mrp_application_window_t;
+typedef struct mrp_application_window_def_s   mrp_application_window_def_t;
 
 enum mrp_application_operation_e {
     MRP_APPLICATION_OPERATION_NONE = 0,
@@ -88,6 +91,12 @@ struct mrp_application_requisites_s {
     mrp_application_privilege_t audio;
 };
 
+struct mrp_application_window_s {
+    const char *window_name;
+    const char *area_name;
+    mrp_wayland_area_t *area;
+};
+
 struct mrp_application_s {
     char *appid;
     char *area_name;
@@ -97,6 +106,7 @@ struct mrp_application_s {
     const char *resource_class;
     int32_t screen_priority;
     mrp_application_requisites_t requisites;
+    mrp_application_window_t *windows;
 
     void *scripting_data;
 };
@@ -113,8 +123,14 @@ enum mrp_application_update_mask_e {
     MRP_APPLICATION_SCREEN_REQUISITES_MASK = 0x080,
     MRP_APPLICATION_AUDIO_REQUISITES_MASK  = 0x100,
     MRP_APPLICATION_REQUISITES_MASK        = 0x180,
+    MRP_APPLICATION_WINDOWS_MASK    = 0x200,
 
-    MRP_APPLICATION_END_MASK = 0x200
+    MRP_APPLICATION_END_MASK = 0x400
+};
+
+struct mrp_application_window_def_s {
+    const char *window_name;
+    const char *area_name;
 };
 
 struct mrp_application_update_s {
@@ -125,6 +141,7 @@ struct mrp_application_update_s {
     mrp_application_privileges_t privileges;
     int32_t screen_priority;
     mrp_application_requisites_t requisites;
+    mrp_application_window_def_t *windows;
 };
 
 mrp_application_t *mrp_application_create(mrp_application_update_t *u,
@@ -132,6 +149,8 @@ mrp_application_t *mrp_application_create(mrp_application_update_t *u,
 void mrp_application_destroy(mrp_application_t *app);
 
 mrp_application_t *mrp_application_find(const char *appid);
+mrp_wayland_area_t *mrp_application_area_find(mrp_application_t *app,
+                                              const char *window_name);
 
 size_t mrp_application_print(mrp_application_t *app,
                              mrp_application_update_mask_t mask,
@@ -146,4 +165,7 @@ const char *mrp_application_privilege_str(mrp_application_privilege_t priv);
 size_t mrp_application_requisite_print(mrp_application_requisite_t rqs,
                                        char *buf, size_t len);
 
+size_t mrp_application_windows_print(mrp_application_window_t *wins,
+                                     char *buf, size_t len);
+
 #endif /* __MURPHY_APPLICATION_H__ */
index 4eb893a..976c528 100644 (file)
@@ -101,6 +101,9 @@ static int reqs_push(lua_State *, mrp_application_requisites_t *);
 
 static int reqs_entry_check(lua_State *, int);
 
+static mrp_application_window_def_t *windows_check(lua_State *, int);
+static void windows_free(mrp_application_window_def_t *);
+
 
 static field_t field_check(lua_State *, int, const char **);
 static field_t field_name_to_type(const char *, ssize_t);
@@ -241,6 +244,7 @@ static int app_create_from_lua(lua_State *L)
     int32_t spri = 0;
     mrp_application_privileges_t *privs = NULL;
     mrp_application_requisites_t *reqs = NULL;
+    mrp_application_window_def_t *windows = NULL;
     char *id;
     char buf[4096];
 
@@ -252,12 +256,13 @@ static int app_create_from_lua(lua_State *L)
     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;
-        case REQUISITES:      reqs  = reqs_check(L, -1);                 break;
-        case RESOURCE_CLASS:  class = luaL_checkstring(L, -1);           break;
-        case SCREEN_PRIORITY: spri  = luaL_checkinteger(L, -1);          break;
+        case APPID:           appid   = luaL_checkstring(L, -1);         break;
+        case AREA:            arnam   = luaL_checkstring(L, -1);         break;
+        case WINDOWS:         windows = windows_check(L, -1);            break;
+        case PRIVILEGES:      privs   = priv_check(L, -1);               break;
+        case REQUISITES:      reqs    = reqs_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;
         }
     }
@@ -298,6 +303,10 @@ static int app_create_from_lua(lua_State *L)
         reqs_free(reqs);
     }
 
+    if (windows) {
+        u.mask |= MRP_APPLICATION_WINDOWS_MASK;
+        u.windows = windows;
+    }
 
     if ((app = mrp_application_create(&u, a))) {
         a->app = app;
@@ -309,6 +318,8 @@ static int app_create_from_lua(lua_State *L)
         lua_pushnil(L);
     }
 
+    windows_free(windows);
+
     MRP_LUA_LEAVE(1);
 }
 
@@ -916,11 +927,76 @@ static int reqs_entry_check(lua_State *L, int idx)
         case BLINKER_RIGHT: r = MRP_APPLICATION_REQUISITE_BLINKER_RIGHT; break;
         default:            luaL_error(L,"invalid requisite '%s'",name); break;
         }
+
+        if (type == LUA_TTABLE)
+            lua_pop(L, 1);
     }
 
     return r;
 }
 
+static mrp_application_window_def_t *windows_check(lua_State *L, int idx)
+{
+    mrp_application_window_def_t *windows, *w;
+    int i, j, m, n;
+    const char *val;
+
+    idx = mrp_lua_absidx(L, idx);
+
+    luaL_checktype(L, idx, LUA_TTABLE);
+
+    n = lua_objlen(L, idx);
+    windows = mrp_allocz(sizeof(mrp_application_window_def_t) * (n + 1));
+
+    for (i = 0;   i < n;   i++) {
+        w = windows + i;
+
+        lua_pushinteger(L, i+1);
+        lua_gettable(L, idx);
+
+        luaL_checktype(L, -1, LUA_TTABLE);
+
+        if ((m = lua_objlen(L, -1)) != 2)
+            luaL_error(L, "invalid application window specification");
+
+        for (j = 0;  j < m;  j++) {
+            lua_pushinteger(L, j+1);
+            lua_gettable(L, -2);
+
+            if (!lua_isstring(L, -1))
+                luaL_error(L, "window specifcation: string expected");
+
+            val = mrp_strdup(lua_tostring(L, -1));
+
+            switch (j) {
+            case 0:      w->window_name = val;    break;
+            case 1:      w->area_name   = val;    break;
+            default:                              break;
+            }
+
+            lua_pop(L, 1);
+        }
+        
+        lua_pop(L, 1);
+    }
+
+    return windows;
+}
+
+static void windows_free(mrp_application_window_def_t *windows)
+{
+    mrp_application_window_def_t *w;
+
+    if (windows) {
+        for (w = windows;  w->window_name;   w++) {
+            mrp_free((void *)w->window_name);
+            mrp_free((void *)w->area_name);
+        }
+        mrp_free((void *)windows);
+    }
+}
+
+
 static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
 {
     const char *fldnam;
@@ -989,8 +1065,18 @@ static field_t field_name_to_type(const char *name, ssize_t len)
         break;
 
     case 7:
-        if (!strcmp(name, "driving"))
-            return DRIVING;
+        switch(name[0]) {
+        case 'd':
+            if (!strcmp(name, "driving"))
+                return DRIVING;
+            break;
+        case 'w':
+            if (!strcmp(name, "windows"))
+                return WINDOWS;
+            break;
+        default:
+            break;
+        }
         break;
 
     case 8:
index 9116d12..d70ed93 100644 (file)
@@ -50,7 +50,7 @@ enum mrp_sysctl_scripting_field_e {
     /*  6 */ ACTIVE, BOTTOM, HEIGHT, HAPTIC, INPUTS, LAYERS, MAPPED, MIDDLE,
              OUTPUT, PARKED, RESIZE, ROTATE, SCREEN, SWITCH,
     /*  7 */ AUDIOID, CLASSES, DISPLAY, DRIVING, KEYCODE, PIXEL_X, PIXEL_Y,
-             POINTER, SURFACE, VISIBLE,
+             POINTER, SURFACE, VISIBLE, WINDOWS,
     /*  8 */ KEYBOARD, POSITION, REVERSES, SUBPIXEL, VERTICAL,
     /*  9 */ CONNECTED, DEVICE_ID, LAYERTYPE, PERMANENT, REQUISITE, SHAREABLE,
     /* 10 */ ATTRIBUTES, HORIZONTAL, KEEPRATIO, PRIVILEGES, REQUISITES,
index 56838d9..4e78d99 100644 (file)
@@ -289,13 +289,22 @@ static int set_area_for_applications(void *key, void *object, void *ud)
 {
     mrp_application_t *app = (mrp_application_t *)object;
     mrp_wayland_area_t *area = (mrp_wayland_area_t *)ud;
+    mrp_application_window_t *w;
 
     MRP_UNUSED(key);
 
     if (!strcmp(app->area_name, area->fullname)) {
-        mrp_debug("set area '%s' for app '%s'", area->name, app->appid);
+        mrp_debug("set area '%s' for app '%s'", area->fullname, app->appid);
         app->area = area;
     }
 
+    for (w = app->windows;   w && w->area_name;    w++) {
+        if (!strcmp(area->fullname, w->area_name)) {
+            mrp_debug("set area '%s' for window '%s'",
+                      area->fullname, w->window_name);
+            w->area = area;
+        }
+    }
+
     return MRP_HTBL_ITER_MORE;
 }
index 3b78cc7..a496a41 100644 (file)
@@ -611,7 +611,7 @@ static mrp_wayland_window_update_mask_t set_appid(mrp_wayland_window_t *win,
 
     memset(&u2, 0, sizeof(u2));
 
-    if (!(u2.area = win->application->area)) {
+    if (!(u2.area = mrp_application_area_find(win->application, win->name))) {
         mrp_log_error("system-controller: no area for application '%s'",
                       win->application->appid);
         return mask;