packaging: pass-through Lua resource veto.
[profile/ivi/murphy.git] / packaging.in / murphy.lua
1 with_system_controller = true
2 with_amb = false
3 verbose = 0
4
5 m = murphy.get()
6
7 -- try loading the various logging plugins
8 m:try_load_plugin('systemd')
9 m:try_load_plugin('dlog')
10
11 -- load the console plugin
12 m:try_load_plugin('console')
13
14 m:try_load_plugin('console.disabled', 'webconsole', {
15                   address = 'wsck:127.0.0.1:3000/murphy',
16                   httpdir = '/usr/share/murphy/webconsole' });
17
18 -- load the dbus plugin
19 if m:plugin_exists('dbus') then
20     m:load_plugin('dbus')
21 end
22
23 -- load the native resource plugin
24 if m:plugin_exists('resource-native') then
25     m:load_plugin('resource-native')
26     m:info("native resource plugin loaded")
27 else
28     m:info("No native resource plugin found...")
29 end
30
31 -- load the dbus resource plugin
32 m:try_load_plugin('resource-dbus', {
33     dbus_bus = "system",
34     dbus_service = "org.Murphy",
35     dbus_track = true,
36     default_zone = "driver",
37     default_class = "implicit"
38 })
39
40 -- load the domain control plugin
41 if m:plugin_exists('domain-control') then
42     m:load_plugin('domain-control')
43 else
44     m:info("No domain-control plugin found...")
45 end
46
47 -- load the AMB plugin
48 if m:plugin_exists('amb') then
49     m:try_load_plugin('amb')
50
51     if builtin.method.amb_initiate and
52        builtin.method.amb_update
53     then
54         with_amb = true
55     end
56 else
57     m:info("No amb plugin found...")
58 end
59
60 -- load the ASM resource plugin
61 if m:plugin_exists('resource-asm') then
62     m:try_load_plugin('resource-asm', {
63         zone = "driver",
64         share_mmplayer = "player:AVP,mandatory,exclusive,strict",
65         ignored_argv0 = "WebProcess"
66     })
67 else
68     m:info("No audio session manager plugin found...")
69 end
70
71 if m:plugin_exists('ivi-resource-manager') then
72     m:load_plugin('ivi-resource-manager')
73     with_system_controller = false
74 end
75
76 -- define application classes
77 application_class {
78     name     = "interrupt",
79     priority = 99,
80     modal    = true ,
81     share    = false,
82     order    = "fifo"
83 }
84
85 application_class {
86     name     = "emergency",
87     priority = 80,
88     modal    = false,
89     share    = false,
90     order    = "fifo"
91 }
92 application_class {
93     name     = "alert",
94     priority = 51,
95     modal    = false,
96     share    = false,
97     order    = "fifo"
98 }
99
100 application_class {
101     name     = "navigator",
102     priority = 50,
103     modal    = false,
104     share    = true,
105     order    = "fifo"
106 }
107
108 application_class {
109     name     = "phone",
110     priority = 6 ,
111     modal    = false,
112     share    = true ,
113     order    = "lifo"
114 }
115 application_class {
116     name     = "camera",
117     priority = 5,
118     modal    = false,
119     share    = false,
120     order    = "lifo"
121 }
122
123 application_class { name="event"    , priority=4 , modal=false, share=true , order="fifo" }
124 application_class { name="game"     , priority=3 , modal=false, share=false, order="lifo" }
125 --# doesn't need to be created here, ivi-resource-manager creates it if loaded
126 --#application_class { name="basic"    , priority=2 , modal=false, share=false, order="lifo" }
127 application_class { name="player"   , priority=1 , modal=false, share=true , order="lifo" }
128 application_class { name="implicit" , priority=0 , modal=false, share=false, order="lifo" }
129
130 -- define zone attributes
131 zone.attributes {
132     type = {mdb.string, "common", "rw"},
133     location = {mdb.string, "anywhere", "rw"}
134 }
135
136 -- define zones
137 zone {
138      name = "driver",
139      attributes = {
140          type = "common",
141          location = "front-left"
142      }
143 }
144
145 zone {
146      name = "passanger1",
147      attributes = {
148          type = "private",
149          location = "front-right"
150      }
151 }
152
153 zone {
154      name = "passanger2",
155      attributes = {
156          type = "private",
157          location = "back-left"
158      }
159 }
160
161 zone {
162      name = "passanger3",
163      attributes = {
164          type = "private",
165          location = "back-right"
166      }
167 }
168
169 zone {
170      name = "passanger4",
171      attributes = {
172          type = "private",
173          location = "back-left"
174      }
175 }
176
177
178 -- define resource classes
179 if not m:plugin_exists('ivi-resource-manager') then
180    resource.class {
181         name = "audio_playback",
182         shareable = true,
183         attributes = {
184             role = { mdb.string, "music", "rw" },
185             pid = { mdb.string, "<unknown>", "rw" },
186             policy = { mdb.string, "relaxed", "rw" }
187         }
188    }
189 end
190
191 resource.class {
192      name = "audio_recording",
193      shareable = true,
194      attributes = {
195          role   = { mdb.string, "music"    , "rw" },
196          pid    = { mdb.string, "<unknown>", "rw" },
197          policy = { mdb.string, "relaxed"  , "rw" }
198      }
199 }
200
201 resource.class {
202      name = "video_playback",
203      shareable = false,
204 }
205
206 resource.class {
207      name = "video_recording",
208      shareable = false
209 }
210
211 if not m:plugin_exists('ivi-resource-manager') and
212    not with_system_controller
213 then
214     resource.method.veto = {
215         function(zone, rset, grant, owners, req_set)
216             return true
217          end
218     }
219 end
220
221 -- test for creating selections
222 mdb.select {
223            name = "audio_owner",
224            table = "audio_playback_owner",
225            columns = {"application_class"},
226            condition = "zone_name = 'driver'"
227 }
228
229 mdb.select {
230            name = "vehicle_speed",
231            table = "amb_vehicle_speed",
232            columns = {"value"},
233            condition = "key = 'VehicleSpeed'"
234 }
235
236 element.lua {
237    name    = "speed2volume",
238    inputs  = { speed = mdb.select.vehicle_speed, param = 9 },
239    outputs = {  mdb.table { name = "speedvol",
240                             index = {"zone", "device"},
241                             columns = {{"zone", mdb.string, 16},
242                                        {"device", mdb.string, 16},
243                                        {"value", mdb.floating}},
244                             create = true
245                            }
246              },
247    oldvolume = 0.0,
248    update  = function(self)
249                 speed = self.inputs.speed.single_value
250                 if (speed) then
251                     volume = (speed - 144.0) / 7.0
252                 else
253                     volume = 0.0
254                 end
255                 diff = volume - self.oldvolume
256                 if (diff*diff > self.inputs.param) then
257                     print("*** element "..self.name.." update "..volume)
258                     self.oldvolume = volume
259                     mdb.table.speedvol:replace({zone = "driver", device = "speakers", value = volume})
260                 end
261              end
262 }
263
264 -- Night mode processing chain
265
266 mdb.select {
267     name = "exterior_brightness",
268     table = "amb_exterior_brightness",
269     columns = { "value" },
270     condition = "key = 'ExteriorBrightness'"
271 }
272
273 element.lua {
274     name    = "nightmode",
275     inputs  = { brightness = mdb.select.exterior_brightness },
276     oldmode = -1;
277     outputs = {
278         mdb.table {
279             name = "amb_nightmode",
280             index = { "id" },
281             create = true,
282             columns = {
283                 { "id", mdb.unsigned },
284                 { "night_mode", mdb.unsigned }
285             }
286         }
287     },
288     update = function(self)
289         -- This is a trivial function to calculate night mode. Later, we will
290         -- need a better threshold value and hysteresis to prevent oscillation.
291
292         brightness = self.inputs.brightness.single_value
293
294         if not brightness then
295             return
296         end
297
298         print("*** element "..self.name.." update brightness: "..brightness)
299
300         if brightness > 300 then
301             mode = 0
302         else
303             mode = 1
304         end
305
306         print("*** resulting mode: ".. mode)
307
308         if not (mode == self.oldmode) then
309             mdb.table.amb_nightmode:replace({ id = 0, night_mode = mode })
310         end
311
312         self.oldmode = mode
313     end
314 }
315
316 mdb.select {
317     name = "select_night_mode",
318     table = "amb_nightmode",
319     columns = { "night_mode" },
320     condition = "id = 0"
321 }
322
323 if with_amb then
324     sink.lua {
325         name = "night_mode",
326         inputs = { owner = mdb.select.select_night_mode },
327         property = "NightMode",
328         type = "b",
329         initiate = builtin.method.amb_initiate,
330         update = builtin.method.amb_update
331     }
332 end
333
334
335 -- Driving mode processing chain
336
337
338 element.lua {
339     name    = "drivingmode",
340     inputs  = { speed = mdb.select.vehicle_speed },
341     oldmode = -1;
342     outputs = {
343         mdb.table {
344             name = "amb_drivingmode",
345             index = { "id" },
346             create = true,
347             columns = {
348                 { "id", mdb.unsigned },
349                 { "driving_mode", mdb.unsigned }
350             }
351         }
352     },
353     update = function(self)
354
355         speed = self.inputs.speed.single_value
356
357         if not speed then
358             return
359         end
360
361         if speed == 0 then
362             mode = 0
363         else
364             mode = 1
365         end
366
367         if not (mode == self.oldmode) then
368             mdb.table.amb_drivingmode:replace({ id = 0, driving_mode = mode })
369         end
370
371         self.oldmode = mode
372     end
373 }
374
375 mdb.select {
376     name = "select_driving_mode",
377     table = "amb_drivingmode",
378     columns = { "driving_mode" },
379     condition = "id = 0"
380 }
381
382 if with_amb then
383     sink.lua {
384         name = "driving_mode",
385         inputs = { owner = mdb.select.select_driving_mode },
386         property = "DrivingMode",
387         type = "u",
388         initiate = builtin.method.amb_initiate,
389         update = builtin.method.amb_update
390     }
391 end
392
393 -- turn signals (left, right)
394
395 mdb.select {
396     name = "winker",
397     table = "amb_turn_signal",
398     columns = { "value" },
399     condition = "key = 'TurnSignal'"
400 }
401
402 -- regulation (on), use "select_driving_mode"
403
404 -- shift position (parking, reverse, other)
405
406 mdb.select {
407     name = "gear_position",
408     table = "amb_gear_position",
409     columns = { "value" },
410     condition = "key = 'GearPosition'"
411 }
412
413 -- cameras (back, front, left, right)
414
415 element.lua {
416     name    = "camera_state",
417     inputs  = { winker = mdb.select.winker, gear = mdb.select.gear_position },
418     oldmode = -1;
419     outputs = {
420         mdb.table {
421             name = "target_camera_state",
422             index = { "id" },
423             create = true,
424             columns = {
425                 { "id", mdb.unsigned },
426                 { "front_camera", mdb.unsigned },
427                 { "back_camera", mdb.unsigned },
428                 { "right_camera", mdb.unsigned },
429                 { "left_camera", mdb.unsigned }
430             }
431         }
432     },
433     update = function(self)
434
435         front_camera = 0
436         back_camera = 0
437         right_camera = 0
438         left_camera = 0
439
440         if self.inputs.gear == 128 then
441             back_camera = 1
442         elseif self.inputs.winker == 1 then
443             right_camera = 1
444         elseif self.inputs.winker == 2 then
445             left_camera = 1
446         end
447
448         mdb.table.target_camera_state:replace({ id = 0, front_camera = front_camera, back_camera = back_camera, right_camera = right_camera, left_camera = left_camera })
449
450     end
451 }
452
453 -- load the telephony plugin
454 m:try_load_plugin('telephony')
455
456
457 -- system controller test setup
458
459 if not with_system_controller or not m:plugin_exists('system-controller') then
460    return
461 end
462
463 m:load_plugin('system-controller')
464
465 window_manager_operation_names = {
466     [1] = "create",
467     [2] = "destroy"
468 }
469
470 function window_manager_operation_name(oper)
471     local name = window_manager_operation_names[oper]
472     if name then return name end
473     return "<unknown " .. tostring(oper) .. ">"
474 end
475
476 window_operation_names = {
477     [1] = "create",
478     [2] = "destroy",
479     [3] = "name_change",
480     [4] = "visible",
481     [5] = "configure",
482     [6] = "active"
483 }
484
485 function window_operation_name(oper)
486     local name = window_operation_names[oper]
487     if name then return name end
488     return "<unknown " .. tostring(oper) .. ">"
489 end
490
491 layer_operation_names = {
492     [1] = "create",
493     [2] = "destroy",
494     [3] = "visible"
495 }
496
497 function layer_operation_name(oper)
498     local name = layer_operation_names[oper]
499     if name then return name end
500     return "<unknown " .. tostring(oper) .. ">"
501 end
502
503 command_names = {
504     [0x00001] = "send_appid",
505     [0x10001] = "create",
506     [0x10002] = "destroy",
507     [0x10003] = "show",
508     [0x10004] = "hide",
509     [0x10005] = "move",
510     [0x10006] = "change_active",
511     [0x10007] = "change_layer",
512     [0x10008] = "change_attr",
513     [0x10009] = "name",
514     [0x10011] = "map_thumb",
515     [0x10012] = "unmap_thumb",
516     [0x10020] = "show layer",
517     [0x10021] = "hide_layer",
518     [0x10022] = "change_layer_attr",
519     [0x20001] = "add_input",
520     [0x20002] = "del_input",
521     [0x20003] = "send_input",
522     [0x40001] = "acquire_res",
523     [0x40002] = "release_res",
524     [0x40003] = "deprive_res",
525     [0x40004] = "waiting_res",
526     [0x40005] = "revert_res",
527     [0x40011] = "create_res",
528     [0x40012] = "destroy_res",
529     [0x50001] = "set_region",
530     [0x50002] = "unset_region",
531     [0x60001] = "change_state"
532 }
533
534 function command_name(command)
535     local name = command_names[command]
536     if name then return name end
537     return "<unknown " .. tostring(command) .. ">"
538 end
539
540 input_layer = {
541    [3] = true, -- input
542    [4] = true, -- touch
543    [5] = true  -- cursor
544 }
545
546 resmgr = resource_manager {
547   screen_event_handler = function(self, ev)
548                              local event = ev.event
549                              local surface = ev.surface
550
551                              if event == "grant" then
552                                  if verbose > 0 then
553                                     print("*** make visible surface "..surface)
554                                  end
555                                  local a = animation({})
556                                  local r = m:JSON({surface = surface,
557                                                    visible = 1,
558                                                    raise   = 1})
559                                  wmgr:window_request(r,a,0)
560                                  elseif event == "revoke" then
561                                  if verbose > 0 then
562                                     print("*** hide surface "..surface)
563                                  end
564                                  local a = animation({})
565                                  local r = m:JSON({surface = ev.surface,
566                                                    visible = 0})
567                                  wmgr:window_request(r,a,0)
568                              else
569                                  if verbose > 0 then
570                                     print("*** resource event: "..tostring(ev))
571                                  end
572                              end
573                          end
574 }
575
576 resclnt = resource_client {}
577
578 wmgr = window_manager {
579   geometry = function(self, w,h, v)
580                   if type(v) == "function" then
581                       return v(w,h)
582                   end
583                   return v
584              end,
585
586   application = function(self, appid)
587                      if appid then
588                          local app = application_lookup(appid)
589                          if not app then
590                              app = application_lookup("default")
591                          end
592                          return app
593                      end
594                      return { privileges = {screen="none", audio="none"} }
595                 end,
596
597   outputs = { { name  = "Center",
598                 id    = 0,
599                 zone  = "driver",
600                 areas = { Status = {
601                               id     = 0,
602                               pos_x  = 0,
603                               pos_y  = 0,
604                               width  = function(w,h) return w end,
605                               height = 64
606                           },
607                           Full = {
608                               id     = 1,
609                               pos_x  = 0,
610                               pos_y  = 64,
611                               width  = function(w,h) return w end,
612                               height = function(w,h) return h-64-128 end
613                           },
614                           Upper = {
615                               id     = 2,
616                               pos_x  = 0,
617                               pos_y  = 64,
618                               width  = function(w,h) return w end,
619                               height = function(w,h) return (h-64-128)/2 end
620                           },
621                           Lower = {
622                               id     = 3,
623                               pos_x  = 0,
624                               pos_y  = function(w,h) return (h-64-128)/2+64 end,
625                               width  = function(w,h) return w end,
626                               height = function(w,h) return (h-64-128)/2 end
627                           },
628                           UpperLeft = {
629                               id     = 4,
630                               pos_x  = 0,
631                               pos_y  = 64,
632                               width  = function(w,h) return w/2 end,
633                               height = function(w,h) return (h-64-128)/2 end
634                           },
635                           UpperRight = {
636                               id     = 5,
637                               pos_x  = function(w,h) return w/2 end,
638                               pos_y  = 64,
639                               width  = function(w,h) return w/2 end,
640                               height = function(w,h) return (h-64-128)/2 end
641                           },
642                           LowerLeft = {
643                               id     = 6,
644                               pos_x  = 0,
645                               pos_y  = function(w,h) return (h-64-128/2)+64 end,
646                               width  = function(w,h) return w/2 end,
647                               height = function(w,h) return (h-64-128)/2 end
648                           },
649                           LowerRight = {
650                               id     = 7,
651                               pos_x  = function(w,h) return w/2 end,
652                               pos_y  = function(w,h) return (h-64-128/2)+64 end,
653                               width  = function(w,h) return w/2 end,
654                               height = function(w,h) return (h-64-128)/2 end
655                           },
656                           SysApp = {
657                               id     = 8,
658                               pos_x  = 0,
659                               pos_y  = 64,
660                               width  = function(w,h) return w end,
661                               height = function(w,h) return h-64-128 end
662                           },
663                           ["SysApp.Left"] = {
664                               id     = 9,
665                               pos_x  = 0,
666                               pos_y  = 64,
667                               width  = function(w,h) return w/2-181 end,
668                               height = function(w,h) return h-64-128 end
669                           },
670                           ["SysApp.Right"] = {
671                               id     = 10,
672                               pos_x  = function(w,h) return w/2+181 end,
673                               pos_y  = 64,
674                               width  = function(w,h) return w/2-181 end,
675                               height = function(w,h) return h-64-128 end
676                           },
677                         }
678                },
679                { name  = "Mid",
680                  zone  = "driver",
681                  id    = 1
682                }
683
684   },
685   layers = { {      0, "Background"   , 1 },
686              {      1, "Application"  , 2 },
687              {      2, "Softkeyboard" , 4 },
688              {      3, "HomeScreen"   , 2 },
689              {      4, "ControlBar"   , 2 },
690              {      5, "InterruptApp" , 2 },
691              {      6, "OnScreen"     , 2 },
692              {    101, "Input"        , 3 },
693              {    102, "Cursor"       , 5 },
694              {    103, "Startup"      , 6 },
695              { 0x1000, "Background"   , 1 },
696              { 0x2000, "Normal"       , 2 },
697              { 0x3000, "Fullscreen"   , 2 },
698              { 0x4000, "InputPanel"   , 3 },
699              { 0xA000, "Touch"        , 4 },
700              { 0xB000, "Cursor"       , 5 },
701              { 0xC000, "Startup"      , 6 }
702   },
703
704
705   manager_update = function(self, oper)
706                        if verbose > 0 then
707                            print("### <== WINDOW MANAGER UPDATE:" ..
708                                  window_manager_operation_name(oper))
709                        end
710                        if oper == 1 then
711                            local umask = window_mask { raise   = true,
712                                                        visible = true,
713                                                        active  = true }
714                            local rmask = window_mask { active  = true }
715                            local req = m:JSON({
716                                        passthrough_update  = umask:tointeger(),
717                                        passthrough_request = rmask:tointeger()
718                            })
719                            self:manager_request(req)
720                        end
721                    end,
722
723   window_update = function(self, oper, win, mask)
724                       if verbose > 0 then
725                           print("### <== WINDOW UPDATE oper:" ..
726                                 window_operation_name(oper) ..
727                                 " mask: " .. tostring(mask))
728                           if verbose > 1 then
729                               print(win)
730                           end
731                       end
732
733                       local arg = m:JSON({ surface = win.surface,
734                                            winname = win.name,
735                       })
736                       local command = 0
737
738                       if oper == 1 then -- create
739                            local layertype = win.layertype
740                            if layertype and input_layer[layertype] then
741                                if verbose > 0 then
742                                    print("ignoring input panel creation")
743                                end
744                                return
745                            end
746                            command     = 0x10001
747                       elseif oper == 2 then -- destroy
748                            command     = 0x10002
749                       elseif oper == 3 then  -- namechange
750                            command     = 0x10009
751                       elseif oper == 4 or oper == 5 then --visible or configure
752                            command     = 0x10008
753                            arg.zone    = win.area
754                            arg.node    = win.node
755                            arg.layer   = win.layer
756                            arg.pos_x   = win.pos_x
757                            arg.pos_y   = win.pos_y
758                            arg.width   = win.width
759                            arg.height  = win.height
760                            arg.raise   = win.raise
761                            arg.visible = win.visible
762                            arg.active  = win.active
763                       elseif oper == 6 then -- active
764                            command     = 0x10006
765                            arg.active  = win.active
766                       else
767                            if verbose > 0 then
768                                print("### nothing to do")
769                            end
770                            return
771                       end
772
773                       local msg = m:JSON({ command = command,
774                                            appid   = win.appid,
775                                            pid     = win.pid,
776                                            arg     = arg
777                       })
778                       if verbose > 0 then
779                           print("### <== sending " ..
780                                 command_name(msg.command) ..
781                                 " window message to '" .. win.name .. "'")
782                           if verbose > 1 then
783                               print(msg)
784                           end
785                       end
786                       sc:send_message(sysctlid, msg)
787
788                       if oper == 1 then -- create
789                           local i = input_layer[win.layertype]
790                           local p = self:application(win.appid)
791                           local s = p.privileges.screen
792
793                           if s == "system" then
794                               local a = animation({})
795                               local r = m:JSON({surface = win.surface,
796                                                 visible = 1,
797                                                 raise   = 1})
798                               self:window_request(r,a,0)
799                           else
800                               if i then
801                                   if verbose > 0 then
802                                       print("do not make resource for " ..
803                                             "input window")
804                                   end
805                               else
806                                   resclnt:resource_set_create("screen",
807                                                                "driver",
808                                                                win.appid,
809                                                                win.surface)
810                               end
811                           end
812                       elseif oper == 2 then -- destroy
813                           resclnt:resource_set_destroy("screen", win.surface)
814                       elseif oper == 6 then -- active
815                           if win.active then
816                               local i = input_layer[win.layertype]
817                               local p = self:application(win.appid)
818                               local s = p.privileges.screen
819                               local surface = win.surface
820                               if not i and s ~= "system" then
821                                  resclnt:resource_set_acquire("screen",surface)
822                                  resmgr:window_raise(win.appid, surface, 1)
823                               end
824                           end
825                       end
826                   end,
827
828   layer_update = function(self, oper, layer, mask)
829                       if verbose > 0 then
830                           print("### LAYER UPDATE:" .. 
831                                 layer_operation_name(oper) ..
832                                 " mask: " .. tostring(mask))
833                           if verbose > 1 then
834                               print(layer)
835                           end
836                       end
837                       if oper == 3 then -- visible
838                          local command = 0x10022
839                          local msg = m:JSON({
840                                          command = command,
841                                          appid = "",
842                                          arg = m:JSON({layer = layer.id,
843                                                        visible = layer.visible
844                                          })
845                                 })
846                          if verbose > 0 then
847                             print("### <== sending "..command_name(command)..
848                                   " layer message")
849                             if verbose > 1 then
850                                 print(msg)
851                             end
852                          end
853                          sc:send_message(sysctlid, msg)
854                       else
855                            if verbose > 0 then
856                                print("### nothing to do")
857                            end
858                       end
859                  end,
860
861   output_update = function(self, oper, out, mask)
862                       local idx = out.index
863                       if verbose > 0 then
864                           print("### OUTPUT UPDATE:" .. oper ..
865                                 " mask: "..tostring(mask))
866                       end
867                       print(out)
868                       local outdef = self.outputs[idx+1]
869                       if (oper == 1) then -- create
870                           if outdef then
871                               self:output_request(m:JSON({index = idx,
872                                                           id    = outdef.id,
873                                                           name  = outdef.name
874                                                           }))
875                           end
876                       elseif (oper == 5) then -- done
877                           local ads = outdef.areas
878                           local on = outdef.name
879                           if ads then
880                               for name,ad in pairs(ads) do
881                                   local can = wmgr:canonical_name(on.."."..name)
882                                   local a = m:JSON({name   = name,
883                                                     output = out.index})
884                                   for fld,val in pairs(ad) do
885                                       a[fld] = self:geometry(out.width,
886                                                              out.height,
887                                                              val) 
888                                    end
889                                    self:area_create(a)
890                                    resmgr:area_create(area[can], outdef.zone)
891                               end
892                           end
893                       end
894                   end
895 }
896
897
898 sc = m:get_system_controller()
899
900 -- resource sets
901 sets = {}
902
903 connected = false
904 sysctlid = ""
905
906 -- these shoud be before wmgr:connect() is called
907 if verbose > 0 then
908    print("====== creating applications ======")
909 end
910 application {
911     appid          = "default",
912     area           = "Center.Full",
913     privileges     = { screen = "none", audio = "none" },
914     resource_class = "player",
915     screen_priority = 0
916 }
917
918 application {
919     appid           = "weston",
920     area            = "Center.Full",
921     privileges      = { screen = "system", audio = "none" },
922     resource_class  = "implicit",
923     screen_priority = 30
924 }
925
926 application {
927     appid           = "org.tizen.ico.homescreen",
928     area            = "Center.Full",
929     privileges      = { screen = "system", audio = "system" },
930     resource_class  = "player",
931     screen_priority = 20
932 }
933
934 application {
935     appid           = "org.tizen.ico.statusbar",
936     area            = "Center.Status",
937     privileges      = { screen = "system", audio = "none" },
938     resource_class  = "player",
939     screen_priority = 20 
940 }
941
942
943 if sc then
944     sc.client_handler = function (self, cid, msg)
945         local command = msg.command
946         if verbose > 0 then
947             print('### ==> client handler:')
948             if verbose > 1 then
949                 print(msg)
950             end
951         end
952         if not connected then
953             print('Setting sysctlid='..msg.appid)
954             sysctlid = msg.appid
955             print('Trying to connect to wayland...')
956             connected = wmgr:connect()
957         end
958         if connected and command then
959             if command == 1 then -- send_appid
960                 local reply = m:JSON({ command = 0x60001,
961                                        arg     = m:JSON({ stateid = 1,
962                                                           state   = 0})
963                                      })
964                  if verbose > 0 then
965                      print("### <== sending " ..
966                            command_name(command) .. " message")
967                      if verbose > 1 then
968                          print(reply)
969                      end
970                  end
971                  sc:send_message(sysctlid, reply)
972
973                  reply = m:JSON({ command = 0x60001,
974                                   arg     = m:JSON({ stateid = 2,
975                                                      state   = 0})
976                                 })
977                  if verbose > 0 then
978                      print("### <== sending " ..
979                            command_name(command) .. " message")
980                      if verbose > 1 then
981                          print(reply)
982                      end
983                  end
984                  sc:send_message(sysctlid, reply)
985             end
986         end
987     end
988
989     sc.generic_handler = function (self, cid, msg)
990         if verbose > 0 then
991             print('### ==> generic handler:')
992             if verbose > 1 then
993                print(msg)
994             end
995         end
996     end
997
998     sc.window_handler = function (self, cid, msg)
999         if verbose > 0 then
1000             print('### ==> received ' ..
1001                    command_name(msg.command) .. ' message')
1002             if verbose > 1 then
1003                 print(tostring(msg))
1004             end
1005         end
1006
1007         local a = animation({})
1008         local nores = false
1009         if msg.command == 0x10003 then       -- ico SHOW command
1010             local raise_mask = 0x01000000
1011             local lower_mask = 0x02000000
1012             local nores_mask = 0x40000000
1013             local time_mask  = 0x00ffffff
1014             msg.arg.visible = 1
1015             if msg.arg then
1016                 local time = 200
1017                 if  msg.arg.anim_time then
1018                     local t = msg.arg.anim_time
1019                     time = m:AND(t, time_mask)
1020                     nores = m:AND(t, nores_mask)
1021                     if m:AND(t, raise_mask) then
1022                         msg.arg.raise = 1
1023                     elseif m:AND(t, lower_mask) then
1024                         msg.arg.raise = 0
1025                     end
1026                 end
1027                 if msg.arg.anim_name then
1028                     a.show = { msg.arg.anim_name, time }
1029                     print('time: ' .. tostring(a.show[2]))
1030                 end
1031             end
1032             if not nores then
1033                 local p = wmgr:application(msg.appid)
1034                 local s = p.privileges.screen
1035                 if s == "system" then
1036                     nores = true
1037                 end
1038             end
1039             if verbose > 2 then
1040                 print('### ==> SHOW')
1041                 print(tostring(msg.arg))
1042             end
1043             if nores then
1044                 wmgr:window_request(msg.arg, a, 0)
1045             else
1046                 local surface = msg.arg.surface
1047                 resclnt:resource_set_acquire("screen", surface)
1048                 resmgr:window_raise(msg.appid, surface, 1)
1049             end
1050         elseif msg.command == 0x10004 then   -- ico HIDE command
1051             local raise_mask = 0x01000000
1052             local lower_mask = 0x02000000
1053             local nores_mask = 0x40000000
1054             local time_mask  = 0x00ffffff
1055             msg.arg.visible = 0
1056             if msg.arg then
1057                 local time = 200
1058                 if msg.arg.anim_time then
1059                     local t = msg.arg.anim_time
1060                     time = m:AND(t, time_mask)
1061                     nores = m:AND(t, nores_mask)
1062                 end
1063                 if msg.arg.anim_name then
1064                     a.hide = { msg.arg.anim_name, time }
1065                     print('hide animation time: ' .. tostring(a.hide[2]))
1066                 end
1067             end
1068             if not nores then
1069                 local p = wmgr:application(msg.appid)
1070                 local s = p.privileges.screen
1071                 if s == "system" then
1072                     nores = true
1073                 end
1074             end
1075             if verbose > 2 then
1076                 print('### ==> HIDE REQUEST')
1077                 print(tostring(msg.arg))
1078             end
1079             if nores then
1080                 wmgr:window_request(msg.arg, a, 0)
1081             else
1082                 resmgr:window_raise(msg.appid, msg.arg.surface, -1)
1083             end
1084         elseif msg.command == 0x10005 then   -- ico MOVE
1085             if verbose > 2 then
1086                 print('### ==> MOVE REQUEST')
1087                 print(tostring(msg.arg))
1088             end
1089             wmgr:window_request(msg.arg, a, 0)
1090             -- TODO: handle if area changed
1091         elseif msg.command == 0x10006 then   -- ico ACTIVE
1092             if not msg.arg.active then
1093                 msg.arg.active = 3 -- pointer + keyboard
1094             end
1095             if verbose > 2 then
1096                 print('### ==> ACTIVE REQUEST')
1097                 print(tostring(msg.arg))
1098             end
1099             wmgr:window_request(msg.arg, a, 0)
1100         elseif msg.command == 0x10007 then   -- ico CHANGE_LAYER
1101             if verbose > 2 then
1102                 print('### ==> CHANGE_LAYER REQUEST')
1103                 print(tostring(msg.arg))
1104             end
1105             --[[
1106             if msg.arg.layer ~= 4 or msg.arg.layer ~= 5 then
1107                 print("do not change layer for other than cursor or touch")
1108                 return
1109             end
1110             --]]
1111             wmgr:window_request(msg.arg, a, 0)
1112         elseif msg.command == 0x10011 then   -- ico MAP_THUMB
1113             local framerate = msg.arg.framerate
1114             if not framerate or framerate < 0 then
1115                 framerate = 0
1116             end
1117             msg.arg.map = 1
1118             if verbose > 2 then
1119                 print('### ==> MAP_THUMB REQUEST')
1120                 print(msg.arg)
1121                 print('framerate: '..framerate)
1122             end
1123             wmgr:window_request(msg.arg, a, framerate)
1124         elseif msg.command == 0x10012 then   -- ico UNMAP_THUMB
1125             msg.arg.map = 0
1126             if verbose > 2 then
1127                 print('### ==> UNMAP_THUMB REQUEST')
1128                 print(msg.arg)
1129             end
1130             wmgr:window_request(msg.arg, a, 0)
1131         elseif msg.command == 0x10020 then   -- ico SHOW_LAYER command
1132             msg.arg.visible = 1
1133             if verbose > 2 then
1134                 print('### ==> SHOW_LAYER REQUEST')
1135                 print(msg.arg)
1136             end
1137             wmgr:layer_request(msg.arg)
1138         elseif msg.command == 0x10021 then   -- ico HIDE_LAYER command
1139             msg.arg.visible = 0
1140             if verbose > 2 then
1141                 print('### ==> HIDE_LAYER REQUEST')
1142                 print(msg.arg)
1143             end
1144             wmgr:layer_request(msg.arg)
1145         end
1146     end
1147
1148     sc.input_handler = function (self, cid, msg)
1149         if verbose > 0 then
1150             print('### ==> input handler: ' .. command_name(msg.comand))
1151             if verbose > 1 then
1152                 print(msg)
1153             end
1154         end
1155     end
1156
1157     sc.user_handler = function (self, cid, msg)
1158         if verbose > 0 then
1159             print('### ==> user handler: ' .. command_name(msg.command))
1160             if verbose > 1 then
1161                 print(msg)
1162             end
1163         end
1164     end
1165
1166     sc.resource_handler = function (self, cid, msg)
1167         if verbose > 0 then
1168             print('### ==> resource handler: ' .. command_name(msg.command))
1169             if verbose > 1 then
1170                 print(msg)
1171             end
1172         end
1173
1174         createResourceSet = function (ctl, client, msg)
1175             cb = function(rset, data)
1176                 print("> resource callback")
1177
1178                 -- type is either basic (0) or interrupt (1)
1179                 requestType = 0
1180                 if msg.res.type then
1181                     requestType = msg.res.type
1182                 end
1183
1184                 if rset.acquired then
1185                     cmd = 0x00040001 -- acquire
1186                 else
1187                     cmd = 0x00040002 -- release
1188                 end
1189
1190                 reply = m.JSON({
1191                         appid = data.client,
1192                         command = cmd,
1193                         res = {
1194                             type = requestType
1195                         }
1196                     })
1197
1198                 if rset.resources.audio_playback then
1199                     reply.res.sound = {
1200                         zone = "driver",
1201                         name = msg.appid,
1202                         adjust = 0,
1203                         -- id = "0"
1204                     }
1205                 end
1206
1207                 if rset.resources.display then
1208                     reply.res.window = {
1209                         zone = "driver",
1210                         name = msg.appid,
1211                         -- id = "0"
1212                     }
1213                 end
1214
1215                 if rset.resources.input then
1216                     reply.res.input = {
1217                         name = msg.appid,
1218                         event = 0
1219                     }
1220                 end
1221                 print("sending message to client: " .. data.client)
1222
1223                 if sc:send_message(data.client, reply) then
1224                     print('*** reply OK')
1225                 else
1226                     print('*** reply FAILED')
1227                 end
1228             end
1229
1230             rset = m:ResourceSet({
1231                     application_class = "player",
1232                     zone = "driver", -- msg.zone ("full")
1233                     callback = cb
1234                 })
1235
1236             rset.data = {
1237                 cid = cid,
1238                 ctl = ctl
1239             }
1240
1241             if msg.res.sound then
1242                 rset:addResource({
1243                         resource_name = "audio_playback"
1244                     })
1245                 rset.resources.audio_playback.attributes.pid = tostring(msg.pid)
1246                 rset.resources.audio_playback.attributes.appid = msg.appid
1247                 print("sound name: " .. msg.res.sound.name)
1248                 print("sound zone:" .. msg.res.sound.zone)
1249                 print("sound adjust: " .. tostring(msg.res.sound.adjust))
1250                 if msg.res.sound.id then
1251                     print("sound id: " .. msg.res.sound.id)
1252                 end
1253             end
1254
1255             if msg.res.input then
1256                 rset:addResource({
1257                         resource_name = "input"
1258                     })
1259                 rset.resources.input.attributes.pid = tostring(msg.pid)
1260                 rset.resources.input.attributes.appid = msg.appid
1261                 print("input name: " .. msg.res.sound.name)
1262                 print("input event:" .. tostring(msg.res.input.event))
1263             end
1264
1265             if msg.res.window then
1266                 rset:addResource({
1267                         resource_name = "display"
1268                     })
1269                 rset.resources.display.attributes.pid = tostring(msg.pid)
1270                 rset.resources.display.attributes.appid = msg.appid
1271                 print("display name: " .. msg.res.display.name)
1272                 print("display zone:" .. msg.res.display.zone)
1273                 if msg.res.display.id then
1274                     print("display id: " .. msg.res.display.id)
1275                 end
1276             end
1277
1278             return rset
1279         end
1280
1281         -- parse the message
1282
1283         -- fields common to all messages:
1284         --      msg.command
1285         --      msg.appid
1286         --      msg.pid
1287
1288         if msg.command == 0x00040011 then -- MSG_CMD_CREATE_RES
1289             print("command CREATE")
1290
1291             if not sets.cid then
1292                 sets.cid = createResourceSet(self, cid, msg)
1293             end
1294
1295         elseif msg.command == 0x00040012 then -- MSG_CMD_DESTORY_RES
1296             print("command DESTROY")
1297
1298             if sets.cid then
1299                 sets.cid:release()
1300             end
1301
1302             sets.cid = nil -- garbage collecting
1303
1304         elseif msg.command == 0x00040001 then -- MSG_CMD_ACQUIRE_RES
1305             print("command ACQUIRE")
1306
1307             if not sets.cid then
1308                 sets.cid = createResourceSet(self, cid, msg)
1309             end
1310
1311             sets.cid:acquire()
1312
1313         elseif msg.command == 0x00040002 then -- MSG_CMD_RELEASE_RES
1314             print("command RELEASE")
1315
1316             if sets.cid then
1317                 sets.cid:release()
1318             end
1319
1320         elseif msg.command == 0x00040003 then -- MSG_CMD_DEPRIVE_RES
1321             print("command DEPRIVE")
1322
1323         elseif msg.command == 0x00040004 then -- MSG_CMD_WAITING_RES
1324             print("command WAITING")
1325
1326         elseif msg.command == 0x00040005 then -- MSG_CMD_REVERT_RES
1327             print("command REVERT")
1328         end
1329     end
1330
1331     sc.inputdev_handler = function (self, cid, msg)
1332         if verbose > 0 then
1333             print('*** inputdev handler: ' .. command_name(msg.command))
1334             if verbose > 1 then
1335                 print(msg)
1336             end
1337         end
1338     end
1339 end