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