bc2dc4c96e1c3da750af7fe2203823e08f6f1653
[platform/framework/web/wrt-plugins-common.git] / src / modules / tizen / DEPRACATED / Display / Screen.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #include "Screen.h"
17 #include <stdio.h>
18 #include <limits.h>
19 #include <algorithm>
20 #include <commons/Exception.h>
21 #include <API/Display/EventChangeState.h>
22
23 // TODO: attach to platform event informing about changed size!
24
25 namespace {
26 const char* COMMAND_XDPYINFO = "xdpyinfo";
27 const char* PATTERN_COLOR_DEPTH = "depth of root window:\\s+(\\d+)\\s+planes";
28 const char* PATTERN_SIZE = "dimensions:\\s+(\\d+)x(\\d+)";
29 } // anonymous
30
31 namespace WrtPlugins {
32 namespace Platform {
33 namespace Display {
34 unsigned short Screen::getColorDepth() const
35 {
36     unsigned short colorDepth = 0;
37     if (!getXDpyProperty(PATTERN_COLOR_DEPTH, &colorDepth)) {
38         ThrowMsg(Commons::PlatformException, "Could not read color depth.");
39     }
40     return colorDepth;
41 }
42
43 Dimension Screen::getSize() const
44 {
45     unsigned int width = 0, height = 0;
46     if (!getXDpyProperty(PATTERN_SIZE, &width, &height)) {
47         ThrowMsg(Commons::PlatformException, "Could not read size.");
48     }
49     return Dimension(width, height);
50 }
51
52 Dimension Screen::getActualSize() const
53 {
54     unsigned int width = 0, height = 0;
55     if (!getXDpyProperty(PATTERN_SIZE, &width, &height)) {
56         ThrowMsg(Commons::PlatformException, "Could not read size.");
57     }
58     if (getOrientation() == Api::Display::O_LANDSCAPE) {
59         std::swap(width, height);
60     }
61     return Dimension(width, height);
62 }
63
64 Api::Display::Orientation Screen::getOrientation() const
65 {
66     appcore_rm rot = APPCORE_RM_UNKNOWN;
67     if (appcore_get_rotation_state(&rot) != 0) {
68         ThrowMsg(Commons::PlatformException, "Could not get orientation.");
69     }
70     switch (rot) {
71     case APPCORE_RM_LANDSCAPE_NORMAL:
72     case APPCORE_RM_LANDSCAPE_REVERSE:
73         return Api::Display::O_LANDSCAPE;
74     default:
75         return Api::Display::O_PORTRAIT;
76     }
77 }
78
79 Api::Display::State Screen::getState() const
80 {
81     Try {
82         int state = m_powerState.getInt();
83         switch (state) {
84         case VCONFKEY_PM_STATE_NORMAL:
85             return Api::Display::ST_ON;
86         case VCONFKEY_PM_STATE_LCDDIM:
87             return Api::Display::ST_DIM;
88         default:
89             return Api::Display::ST_OFF;
90         }
91     }
92     Catch(Commons::ConversionException) {
93         ReThrowMsg(Commons::PlatformException,
94                    "Could not get device's power state.");
95     }
96 }
97
98 void Screen::addOnChangeOrientation(
99     const Api::Display::EventChangeOrientationEmitterPtr& emitter)
100 {
101     m_onChangeOrientation.attach(emitter);
102     ChangeOrientationEmitters::LockType lock = m_onChangeOrientation.getLock();
103     if (m_onChangeOrientation.size() == 1) {
104         if (appcore_set_rotation_cb(onChangeOrientation, this) != 0) {
105             ThrowMsg(Commons::PlatformException,
106                      "Could not attach to platform event.");
107         }
108     }
109 }
110
111 void Screen::removeOnChangeOrientation(
112     Api::Display::EventChangeOrientationEmitter::IdType id)
113 {
114     m_onChangeOrientation.detach(id);
115     ChangeOrientationEmitters::LockType lock = m_onChangeOrientation.getLock();
116     if (m_onChangeOrientation.size() == 0) {
117         if (appcore_unset_rotation_cb() != 0) {
118             ThrowMsg(Commons::PlatformException,
119                      "Could not detach from platform event.");
120         }
121     }
122 }
123
124 void Screen::addOnChangeState(
125     const Api::Display::EventChangeStateEmitterPtr& emitter)
126 {
127     m_onChangeState.attach(emitter);
128     ChangeStateEmitters::LockType lock = m_onChangeState.getLock();
129     if (m_onChangeState.size() == 1) {
130         m_powerState.attachCallback(onChangeState, this);
131     }
132 }
133
134 void Screen::removeOnChangeState(
135     Api::Display::EventChangeStateEmitter::IdType id)
136 {
137     m_onChangeState.detach(id);
138     ChangeStateEmitters::LockType lock = m_onChangeState.getLock();
139     if (m_onChangeState.size() == 0) {
140         m_powerState.detachCallback();
141     }
142 }
143
144 Screen::Screen(std::size_t index) :
145     m_index(index),
146     m_powerState(VCONFKEY_PM_STATE)
147 {}
148
149 bool Screen::getXDpyProperty(const char* pattern,
150                              const pcrecpp::Arg& arg1,
151                              const pcrecpp::Arg& arg2)
152 {
153     FILE* pipe = popen(COMMAND_XDPYINFO, "r");
154     if (pipe == NULL) {
155         ThrowMsg(Commons::PlatformException,
156                  "Could not initialize pipe to xdpyinfo.");
157     }
158
159     bool matched = false;
160     pcrecpp::RE re(pattern);
161     char line[LINE_MAX] = { 0 };
162     while (fgets(line, LINE_MAX, pipe)) {
163         if (re.PartialMatch(line, arg1, arg2)) {
164             matched = true;
165             break;
166         }
167     }
168     pclose(pipe);
169
170     return matched;
171 }
172
173 void Screen::onChangeState(const VConf::Node* /*node*/,
174                            void* data)
175 {
176     Screen* this_ = static_cast<Screen*>(data);
177     Api::Display::EventChangeStatePtr event(new Api::Display::EventChangeState());
178     Try {
179         event->setState(this_->getState());
180     }
181     Catch(Commons::PlatformException) {
182         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
183     }
184     this_->m_onChangeState.emit(event);
185 }
186
187 int Screen::onChangeOrientation(appcore_rm rot,
188                                 void* data)
189 {
190     Screen* this_ = static_cast<Screen*>(data);
191     Api::Display::EventChangeOrientationPtr event(
192         new Api::Display::EventChangeOrientation());
193     Try {
194         event->setOrientation(this_->getOrientation());
195     }
196     Catch(Commons::PlatformException) {
197         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
198     }
199     this_->m_onChangeOrientation.emit(event);
200     //TODO check returned value
201     return 0;
202 }
203 } // Display
204 } // Platform
205 } // WrtPlugins
206