Initialize Tizen 2.3
[framework/system/coord.git] / src / rotation / rotation.c
1 /*
2  * coord
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdbool.h>
20 #include <string.h>
21 #include <E_DBus.h>
22 #include "core/log.h"
23 #include "core/list.h"
24 #include "core/common.h"
25 #include "core/coords.h"
26 #include "core/edbus-handler.h"
27 #include "shared/dbus.h"
28 #include "rotation.h"
29
30 #define CHECK_VALID_OPS(ops, r)         ((ops) ? true : !(r = -ENODEV))
31
32 /* rotation operation variable */
33 static c_list *r_head;
34 static const struct rotation_profile_ops *r_ops;
35
36 void add_rotation(const struct rotation_ops *ops) {
37         C_LIST_APPEND(r_head, (void*)ops);
38 }
39
40 void remove_rotation(const struct rotation_ops *ops) {
41         C_LIST_REMOVE(r_head, (void*)ops);
42 }
43
44 int broadcast_rotation_status(int last_notified_status) {
45         int r, rot;
46         char *arr[1];
47         char str_status[32];
48
49         rot = r_ops->get_rotation_status();
50
51         if (last_notified_status == rot) {
52                 return rot;
53         }
54
55         snprintf(str_status, sizeof(str_status), "%d", rot);
56         arr[0] = str_status;
57         r = broadcast_edbus_signal(COORD_PATH_ROTATION, COORD_INTERFACE_ROTATION, 
58                         COORD_SIGNAL_ROTATION_CHANGED, "i", arr);
59         _D("broadcast rotation signal: %d", rot);
60         if (r < 0) {
61                 _E("Failed: broadcast_edbus_signal()");
62                 return last_notified_status;
63         }
64
65         return rot;
66 }
67
68 static DBusMessage *edbus_get_degree(E_DBus_Object *obj, DBusMessage *message)
69 {
70         DBusMessageIter iter;
71         DBusMessage* reply;
72         int r, rot;
73
74         if (!CHECK_VALID_OPS(r_ops, r))
75                 goto exit;
76
77         rot = r_ops->get_rotation_status();
78         r = rot;
79
80 exit:
81         reply = dbus_message_new_method_return(message);
82         dbus_message_iter_init_append(reply, &iter);
83         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &r);
84         return reply;
85 }
86
87 static const struct edbus_method edbus_methods[] = {
88         { COORD_METHOD_ROTATION_DEGREE, NULL,   NULL,   edbus_get_degree },
89         /* Add methods here */
90 };
91
92 static void rotation_init(void *data)
93 {
94         _D("init rotation");
95
96         struct rotation_ops *ops;
97         c_list *elem;
98         int r;
99
100         /* find valid profile */
101         C_LIST_FOREACH(r_head, elem, ops) {
102                 if (ops->load)
103                         r_ops = ops->load();
104                 break;
105         }
106
107         if (!CHECK_VALID_OPS(r_ops, r)) {
108                 _E("Can't find the valid rotation profile");
109                 return;
110         }
111
112         /* init dbus interface */
113         r = register_edbus_method(COORD_PATH_ROTATION, edbus_methods, ARRAY_SIZE(edbus_methods));
114         if (r < 0) {
115                 _E("fail to init edbus method(%d)", r);
116                 return;
117         }
118 }
119
120 static void rotation_exit(void *data)
121 {
122         _D("exit rotation");
123
124         struct rotation_ops *ops;
125         c_list *elem;
126         int r;
127
128         if (!CHECK_VALID_OPS(r_ops, r))
129                 return;
130
131         /* release profile */
132         C_LIST_FOREACH(r_head, elem, ops) {
133                 if (ops->release)
134                         ops->release();
135                 r_ops = NULL;
136                 break;
137         }
138
139 }
140
141 static const struct coord_ops rotation_coord_ops = {
142         .priority       = COORD_PRIORITY_NORMAL,
143         .name           = "rotation",
144         .init           = rotation_init,
145         .exit           = rotation_exit,
146 };
147
148 COORD_OPS_REGISTER(&rotation_coord_ops)
149